Commit ee8164a9 authored by ben-chain's avatar ben-chain Committed by GitHub

Merge pull request #2 from ethereum-optimism/dev/port-tests

Ports over most of the tests from Contracts V1
parents c7b37b40 7d72e069
/* External Imports */
import * as fs from 'fs'
import * as path from 'path'
import * as mkdirp from 'mkdirp'
/* Internal Imports */
import { makeStateDump } from '../src'
;(async () => {
const outdir = path.resolve(__dirname, '../build/dumps')
const outfile = path.join(outdir, 'state-dump.latest.json')
mkdirp.sync(outdir)
const dump = await makeStateDump()
fs.writeFileSync(outfile, JSON.stringify(dump))
})()
......@@ -8,7 +8,7 @@ import {
usePlugin('@nomiclabs/buidler-ethers')
usePlugin('@nomiclabs/buidler-waffle')
import '@eth-optimism/smock/src/buidler-plugins/compiler-storage-layout'
import '@eth-optimism/smock/build/src/buidler-plugins/compiler-storage-layout'
const config: BuidlerConfig = {
networks: {
......
......@@ -4,11 +4,11 @@ pragma experimental ABIEncoderV2;
/* Interface Imports */
import { iOVM_ECDSAContractAccount } from "../../iOVM/accounts/iOVM_ECDSAContractAccount.sol";
import { iOVM_ExecutionManager } from "../../iOVM/execution/iOVM_ExecutionManager.sol";
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_ECDSAUtils } from "../../libraries/utils/Lib_ECDSAUtils.sol";
import { Lib_SafeExecutionManagerWrapper } from "../../libraries/wrappers/Lib_SafeExecutionManagerWrapper.sol";
/**
* @title OVM_ECDSAContractAccount
......@@ -43,7 +43,7 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
bytes memory _returndata
)
{
iOVM_ExecutionManager ovmExecutionManager = iOVM_ExecutionManager(msg.sender);
address ovmExecutionManager = msg.sender;
// Address of this contract within the ovm (ovmADDRESS) should be the same as the
// recovered address of the user who signed this message. This is how we manage to shim
......@@ -55,8 +55,8 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
_v,
_r,
_s,
ovmExecutionManager.ovmCHAINID()
) == ovmExecutionManager.ovmADDRESS(),
Lib_SafeExecutionManagerWrapper.safeCHAINID(ovmExecutionManager)
) == Lib_SafeExecutionManagerWrapper.safeADDRESS(ovmExecutionManager),
"Signature provided for EOA transaction execution is invalid."
);
......@@ -64,14 +64,16 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
// Need to make sure that the transaction nonce is right and bump it if so.
require(
decodedTx.nonce == ovmExecutionManager.ovmGETNONCE() + 1,
decodedTx.nonce == Lib_SafeExecutionManagerWrapper.safeGETNONCE(ovmExecutionManager) + 1,
"Transaction nonce does not match the expected nonce."
);
ovmExecutionManager.ovmSETNONCE(decodedTx.nonce);
Lib_SafeExecutionManagerWrapper.safeSETNONCE(ovmExecutionManager, decodedTx.nonce);
// Contract creations are signalled by sending a transaction to the zero address.
if (decodedTx.target == address(0)) {
address created = ovmExecutionManager.ovmCREATE{gas: decodedTx.gasLimit}(
address created = Lib_SafeExecutionManagerWrapper.safeCREATE(
ovmExecutionManager,
decodedTx.gasLimit,
decodedTx.data
);
......@@ -79,7 +81,8 @@ contract OVM_ECDSAContractAccount is iOVM_ECDSAContractAccount {
// initialization. Always return `true` for our success value here.
return (true, abi.encode(created));
} else {
return ovmExecutionManager.ovmCALL(
return Lib_SafeExecutionManagerWrapper.safeCALL(
ovmExecutionManager,
decodedTx.gasLimit,
decodedTx.target,
decodedTx.data
......
......@@ -41,6 +41,32 @@ contract OVM_BaseCrossDomainMessenger is iOVM_BaseCrossDomainMessenger {
targetMessengerAddress = _targetMessengerAddress;
}
/**
* Sends a cross domain message to the target messenger.
* @param _target Target contract address.
* @param _message Message to send to the target.
* @param _gasLimit Gas limit for the provided message.
*/
function sendMessage(
address _target,
bytes memory _message,
uint256 _gasLimit
)
override
public
{
bytes memory xDomainCalldata = _getXDomainCalldata(
_target,
msg.sender,
_message,
messageNonce
);
_sendXDomainMessage(xDomainCalldata, _gasLimit);
messageNonce += 1;
sentMessages[keccak256(xDomainCalldata)] = true;
}
/**********************
* Internal Functions *
......@@ -74,4 +100,19 @@ contract OVM_BaseCrossDomainMessenger is iOVM_BaseCrossDomainMessenger {
_messageNonce
);
}
/**
* Sends a cross domain message.
* @param _message Message to send.
* @param _gasLimit Gas limit for the provided message.
*/
function _sendXDomainMessage(
bytes memory _message,
uint256 _gasLimit
)
virtual
internal
{
revert("Implement me in child contracts!");
}
}
......@@ -3,8 +3,9 @@ pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_EthMerkleTrie } from "../../libraries/trie/Lib_EthMerkleTrie.sol";
import { Lib_SecureMerkleTrie } from "../../libraries/trie/Lib_SecureMerkleTrie.sol";
import { Lib_BytesUtils } from "../../libraries/utils/Lib_BytesUtils.sol";
/* Interface Imports */
......@@ -94,31 +95,6 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
receivedMessages[keccak256(xDomainCalldata)] = true;
}
/**
* Sends a cross domain message to the target messenger.
* @inheritdoc iOVM_L1CrossDomainMessenger
*/
function sendMessage(
address _target,
bytes memory _message,
uint32 _gasLimit
)
override
public
{
bytes memory xDomainCalldata = _getXDomainCalldata(
_target,
msg.sender,
_message,
messageNonce
);
_sendXDomainMessage(xDomainCalldata, _gasLimit);
messageNonce += 1;
sentMessages[keccak256(xDomainCalldata)] = true;
}
/**
* Replays a cross domain message to the target messenger.
* @inheritdoc iOVM_L1CrossDomainMessenger
......@@ -221,11 +197,27 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
)
);
return Lib_EthMerkleTrie.proveAccountStorageSlotValue(
0x4200000000000000000000000000000000000000,
storageKey,
bytes32(uint256(1)),
(
bool exists,
bytes memory encodedMessagePassingAccount
) = Lib_SecureMerkleTrie.get(
abi.encodePacked(0x4200000000000000000000000000000000000000),
_proof.stateTrieWitness,
_proof.stateRoot
);
require(
exists == true,
"Message passing precompile has not been initialized or invalid proof provided."
);
Lib_OVMCodec.EVMAccount memory account = Lib_OVMCodec.decodeEVMAccount(
encodedMessagePassingAccount
);
return Lib_SecureMerkleTrie.verifyInclusionProof(
abi.encodePacked(storageKey),
abi.encodePacked(uint256(1)),
_proof.storageTrieWitness,
_proof.stateRoot
);
......@@ -238,8 +230,9 @@ contract OVM_L1CrossDomainMessenger is iOVM_L1CrossDomainMessenger, OVM_BaseCros
*/
function _sendXDomainMessage(
bytes memory _message,
uint32 _gasLimit
uint256 _gasLimit
)
override
internal
{
ovmL1ToL2TransactionQueue.enqueue(
......
......@@ -88,31 +88,6 @@ contract OVM_L2CrossDomainMessenger is iOVM_L2CrossDomainMessenger, OVM_BaseCros
receivedMessages[keccak256(xDomainCalldata)] = true;
}
/**
* Sends a cross domain message to the target messenger.
* @inheritdoc iOVM_L2CrossDomainMessenger
*/
function sendMessage(
address _target,
bytes memory _message,
uint256 _gasLimit
)
override
public
{
bytes memory xDomainCalldata = _getXDomainCalldata(
_target,
msg.sender,
_message,
messageNonce
);
_sendXDomainMessage(xDomainCalldata, _gasLimit);
messageNonce += 1;
sentMessages[keccak256(xDomainCalldata)] = true;
}
/**********************
* Internal Functions *
......@@ -142,6 +117,7 @@ contract OVM_L2CrossDomainMessenger is iOVM_L2CrossDomainMessenger, OVM_BaseCros
bytes memory _message,
uint256 _gasLimit
)
override
internal
{
ovmL2ToL1MessagePasser.passMessageToL1(_message);
......
......@@ -73,7 +73,10 @@ contract OVM_StateCommitmentChain is iOVM_StateCommitmentChain, OVM_BaseChain, L
elements[i] = abi.encodePacked(_batch[i]);
}
_appendBatch(elements);
_appendBatch(
elements,
abi.encodePacked(block.timestamp)
);
}
/**
......
......@@ -4,6 +4,7 @@ pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol";
/* Interface Imports */
......@@ -20,7 +21,7 @@ import { console } from "@nomiclabs/buidler/console.sol";
/**
* @title OVM_ExecutionManager
*/
contract OVM_ExecutionManager is iOVM_ExecutionManager {
contract OVM_ExecutionManager is iOVM_ExecutionManager, Lib_AddressResolver {
/********************************
* External Contract References *
......@@ -59,12 +60,14 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
***************/
/**
* @param _ovmSafetyChecker Address of the iOVM_SafetyChecker implementation.
* @param _libAddressManager Address of the Address Manager.
*/
constructor(
address _ovmSafetyChecker
) {
ovmSafetyChecker = iOVM_SafetyChecker(_ovmSafetyChecker);
address _libAddressManager
)
Lib_AddressResolver(_libAddressManager)
{
ovmSafetyChecker = iOVM_SafetyChecker(resolve("OVM_SafetyChecker"));
}
......@@ -1516,10 +1519,12 @@ contract OVM_ExecutionManager is iOVM_ExecutionManager {
bool _valid
)
{
// Always have to be below the maximum gas limit.
if (_gasLimit > gasMeterConfig.maxTransactionGasLimit) {
return false;
}
// Always have to be above the minumum gas limit.
if (_gasLimit < gasMeterConfig.minTransactionGasLimit) {
return false;
}
......
......@@ -111,6 +111,20 @@ contract OVM_StateManager is iOVM_StateManager {
accounts[_address] = _account;
}
/**
* Marks an account as empty.
* @param _address Address of the account to mark.
*/
function putEmptyAccount(
address _address
)
override
public
authenticated
{
accounts[_address].codeHash = EMPTY_ACCOUNT_CODE_HASH;
}
/**
* Retrieves an account from the state.
* @param _address Address of the account to retrieve.
......@@ -215,6 +229,24 @@ contract OVM_StateManager is iOVM_StateManager {
return accounts[_address].ethAddress;
}
/**
* Retrieves the storage root of an account.
* @param _address Address of the account to access.
* @return _storageRoot Corresponding storage root.
*/
function getAccountStorageRoot(
address _address
)
override
public
view
returns (
bytes32 _storageRoot
)
{
return accounts[_address].storageRoot;
}
/**
* Initializes a pending account (during CREATE or CREATE2) with the default values.
* @param _address Address of the account to initialize.
......@@ -228,7 +260,7 @@ contract OVM_StateManager is iOVM_StateManager {
{
Lib_OVMCodec.Account storage account = accounts[_address];
account.nonce = 1;
account.codeHash = keccak256(hex'80');
account.codeHash = keccak256(hex'');
account.isFresh = true;
}
......
......@@ -6,7 +6,7 @@ pragma experimental ABIEncoderV2;
import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol";
import { Lib_EthMerkleTrie } from "../../libraries/trie/Lib_EthMerkleTrie.sol";
import { Lib_SecureMerkleTrie } from "../../libraries/trie/Lib_SecureMerkleTrie.sol";
/* Interface Imports */
import { iOVM_StateTransitioner } from "../../iOVM/verification/iOVM_StateTransitioner.sol";
......@@ -14,6 +14,9 @@ import { iOVM_ExecutionManager } from "../../iOVM/execution/iOVM_ExecutionManage
import { iOVM_StateManager } from "../../iOVM/execution/iOVM_StateManager.sol";
import { iOVM_StateManagerFactory } from "../../iOVM/execution/iOVM_StateManagerFactory.sol";
/* Logging Imports */
import { console } from "@nomiclabs/buidler/console.sol";
/**
* @title OVM_StateTransitioner
*/
......@@ -158,70 +161,128 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner, Lib_AddressResolver {
*/
function proveContractState(
address _ovmContractAddress,
Lib_OVMCodec.Account memory _account,
address _ethContractAddress,
Lib_OVMCodec.EVMAccount memory _account,
bytes memory _stateTrieWitness
)
override
public
onlyDuringPhase(TransitionPhase.PRE_EXECUTION)
{
// Exit quickly to avoid unnecessary work.
require(
ovmStateManager.hasAccount(_ovmContractAddress) == false,
"Account state has already been proven"
);
require(
_account.codeHash == Lib_EthUtils.getCodeHash(_account.ethAddress),
_account.codeHash == Lib_EthUtils.getCodeHash(_ethContractAddress),
"Invalid code hash provided."
);
require(
Lib_EthMerkleTrie.proveAccountState(
_ovmContractAddress,
_account,
Lib_SecureMerkleTrie.verifyInclusionProof(
abi.encodePacked(_ovmContractAddress),
Lib_OVMCodec.encodeEVMAccount(_account),
_stateTrieWitness,
preStateRoot
),
"Invalid account state provided."
"Account state is not correct or invalid inclusion proof provided."
);
ovmStateManager.putAccount(
_ovmContractAddress,
_account
Lib_OVMCodec.Account({
nonce: _account.nonce,
balance: _account.balance,
storageRoot: _account.storageRoot,
codeHash: _account.codeHash,
ethAddress: _ethContractAddress,
isFresh: false
})
);
}
/**
* Allows a user to prove that an account does *not* exist in the state.
* @param _ovmContractAddress Address of the contract on the OVM.
* @param _stateTrieWitness Proof of the (empty) account state.
*/
function proveEmptyContractState(
address _ovmContractAddress,
bytes memory _stateTrieWitness
)
override
public
onlyDuringPhase(TransitionPhase.PRE_EXECUTION)
{
// Exit quickly to avoid unnecessary work.
require(
ovmStateManager.hasEmptyAccount(_ovmContractAddress) == false,
"Account state has already been proven."
);
require(
Lib_SecureMerkleTrie.verifyExclusionProof(
abi.encodePacked(_ovmContractAddress),
_stateTrieWitness,
preStateRoot
),
"Account is not empty or invalid inclusion proof provided."
);
ovmStateManager.putEmptyAccount(_ovmContractAddress);
}
/**
* Allows a user to prove the initial state of a contract storage slot.
* @param _ovmContractAddress Address of the contract on the OVM.
* @param _key Claimed account slot key.
* @param _value Claimed account slot value.
* @param _stateTrieWitness Proof of the account state.
* @param _storageTrieWitness Proof of the storage slot.
*/
function proveStorageSlot(
address _ovmContractAddress,
bytes32 _key,
bytes32 _value,
bytes memory _stateTrieWitness,
bytes memory _storageTrieWitness
)
override
public
onlyDuringPhase(TransitionPhase.PRE_EXECUTION)
{
// Exit quickly to avoid unnecessary work.
require(
ovmStateManager.hasContractStorage(_ovmContractAddress, _key) == false,
"Storage slot has already been proven."
);
require(
ovmStateManager.hasAccount(_ovmContractAddress) == true,
"Contract must be verified before proving a storage slot."
);
require(
Lib_EthMerkleTrie.proveAccountStorageSlotValue(
_ovmContractAddress,
_key,
_value,
_stateTrieWitness,
_storageTrieWitness,
preStateRoot
),
"Invalid account state provided."
(
bool exists,
bytes memory value
) = Lib_SecureMerkleTrie.get(
abi.encodePacked(_key),
_storageTrieWitness,
ovmStateManager.getAccountStorageRoot(_ovmContractAddress)
);
if (exists == true) {
require(
keccak256(value) == keccak256(abi.encodePacked(_value)),
"Provided storage slot value is invalid."
);
} else {
require(
_value == bytes32(0),
"Provided storage slot value is invalid."
);
}
ovmStateManager.putContractStorage(
_ovmContractAddress,
_key,
......@@ -249,9 +310,14 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner, Lib_AddressResolver {
"Invalid transaction provided."
);
// TODO: Set state manager for EM here.
// We call `setExecutionManager` right before `run` (and not earlier) just in case the
// OVM_ExecutionManager address was updated between the time when this contract was created
// and when `applyTransaction` was called.
ovmStateManager.setExecutionManager(resolve("OVM_ExecutionManager"));
// `run` always succeeds *unless* the user hasn't provided enough gas to `applyTransaction`
// or an INVALID_STATE_ACCESS flag was triggered. Either way, we won't get beyond this line
// if that's the case.
ovmExecutionManager.run(_transaction, address(ovmStateManager));
phase = TransitionPhase.POST_EXECUTION;
......@@ -270,7 +336,7 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner, Lib_AddressResolver {
*/
function commitContractState(
address _ovmContractAddress,
Lib_OVMCodec.Account memory _account,
Lib_OVMCodec.EVMAccount memory _account,
bytes memory _stateTrieWitness
)
override
......@@ -279,12 +345,12 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner, Lib_AddressResolver {
{
require(
ovmStateManager.commitAccount(_ovmContractAddress) == true,
"Cannot commit an account that has not been changed."
"Account was not changed or has already been committed."
);
postStateRoot = Lib_EthMerkleTrie.updateAccountState(
_ovmContractAddress,
_account,
postStateRoot = Lib_SecureMerkleTrie.update(
abi.encodePacked(_ovmContractAddress),
Lib_OVMCodec.encodeEVMAccount(_account),
_stateTrieWitness,
postStateRoot
);
......@@ -311,15 +377,24 @@ contract OVM_StateTransitioner is iOVM_StateTransitioner, Lib_AddressResolver {
{
require(
ovmStateManager.commitContractStorage(_ovmContractAddress, _key) == true,
"Cannot commit a storage slot that has not been changed."
"Storage slot was not changed or has already been committed."
);
postStateRoot = Lib_EthMerkleTrie.updateAccountStorageSlotValue(
_ovmContractAddress,
_key,
_value,
_stateTrieWitness,
Lib_OVMCodec.EVMAccount memory account = Lib_OVMCodec.toEVMAccount(
ovmStateManager.getAccount(_ovmContractAddress)
);
account.storageRoot = Lib_SecureMerkleTrie.update(
abi.encodePacked(_key),
abi.encodePacked(_value),
_storageTrieWitness,
account.storageRoot
);
postStateRoot = Lib_SecureMerkleTrie.update(
abi.encodePacked(_ovmContractAddress),
Lib_OVMCodec.encodeEVMAccount(account),
_stateTrieWitness,
postStateRoot
);
}
......
......@@ -18,4 +18,16 @@ interface iOVM_BaseCrossDomainMessenger {
function setTargetMessengerAddress(
address _targetMessengerAddress
) external;
/**
* Sends a cross domain message to the target messenger.
* @param _target Target contract address.
* @param _message Message to send to the target.
* @param _gasLimit Gas limit for the provided message.
*/
function sendMessage(
address _target,
bytes memory _message,
uint256 _gasLimit
) external;
}
......@@ -46,18 +46,6 @@ interface iOVM_L1CrossDomainMessenger is iOVM_BaseCrossDomainMessenger {
L2MessageInclusionProof memory _proof
) external;
/**
* Sends a cross domain message to the target messenger.
* @param _target Target contract address.
* @param _message Message to send to the target.
* @param _gasLimit Gas limit for the provided message.
*/
function sendMessage(
address _target,
bytes memory _message,
uint32 _gasLimit
) external;
/**
* Replays a cross domain message to the target messenger.
* @param _target Target contract address.
......
......@@ -27,16 +27,4 @@ interface iOVM_L2CrossDomainMessenger is iOVM_BaseCrossDomainMessenger {
bytes memory _message,
uint256 _messageNonce
) external;
/**
* Sends a cross domain message to the target messenger.
* @param _target Target contract address.
* @param _message Message to send to the target.
* @param _gasLimit Gas limit for the provided message.
*/
function sendMessage(
address _target,
bytes memory _message,
uint256 _gasLimit
) external;
}
......@@ -34,12 +34,14 @@ interface iOVM_StateManager {
************************************/
function putAccount(address _address, Lib_OVMCodec.Account memory _account) external;
function putEmptyAccount(address _address) external;
function getAccount(address _address) external view returns (Lib_OVMCodec.Account memory _account);
function hasAccount(address _address) external view returns (bool _exists);
function hasEmptyAccount(address _address) external view returns (bool _exists);
function setAccountNonce(address _address, uint256 _nonce) external;
function getAccountNonce(address _address) external view returns (uint256 _nonce);
function getAccountEthAddress(address _address) external view returns (address _ethAddress);
function getAccountStorageRoot(address _address) external view returns (bytes32 _storageRoot);
function initPendingAccount(address _address) external;
function commitPendingAccount(address _address, address _ethAddress, bytes32 _codeHash) external;
function testAndSetAccountLoaded(address _address) external returns (bool _wasAccountAlreadyLoaded);
......
......@@ -25,7 +25,13 @@ interface iOVM_StateTransitioner {
function proveContractState(
address _ovmContractAddress,
Lib_OVMCodec.Account calldata _account,
address _ethContractAddress,
Lib_OVMCodec.EVMAccount calldata _account,
bytes calldata _stateTrieWitness
) external;
function proveEmptyContractState(
address _ovmContractAddress,
bytes calldata _stateTrieWitness
) external;
......@@ -33,7 +39,6 @@ interface iOVM_StateTransitioner {
address _ovmContractAddress,
bytes32 _key,
bytes32 _value,
bytes calldata _stateTrieWitness,
bytes calldata _storageTrieWitness
) external;
......@@ -53,7 +58,7 @@ interface iOVM_StateTransitioner {
function commitContractState(
address _ovmContractAddress,
Lib_OVMCodec.Account calldata _account,
Lib_OVMCodec.EVMAccount calldata _account,
bytes calldata _stateTrieWitness
) external;
......
......@@ -4,12 +4,24 @@ pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol";
import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol";
/**
* @title Lib_OVMCodec
*/
library Lib_OVMCodec {
/*************
* Constants *
*************/
bytes constant internal RLP_NULL_BYTES = hex'80';
bytes constant internal NULL_BYTES = bytes('');
bytes32 constant internal NULL_BYTES32 = bytes32('');
bytes32 constant internal KECCAK256_RLP_NULL_BYTES = keccak256(RLP_NULL_BYTES);
bytes32 constant internal KECCAK256_NULL_BYTES = keccak256(NULL_BYTES);
/*********
* Enums *
*********/
......@@ -68,13 +80,6 @@ library Lib_OVMCodec {
bytes data;
}
struct ProofMatrix {
bool checkNonce;
bool checkBalance;
bool checkStorageRoot;
bool checkCodeHash;
}
struct QueueElement {
uint256 timestamp;
bytes32 batchRoot;
......@@ -107,13 +112,13 @@ library Lib_OVMCodec {
EOATransaction memory _decoded
)
{
Lib_RLPReader.RLPItem[] memory decoded = Lib_RLPReader.toList(Lib_RLPReader.toRlpItem(_transaction));
Lib_RLPReader.RLPItem[] memory decoded = Lib_RLPReader.readList(_transaction);
return EOATransaction({
nonce: Lib_RLPReader.toUint(decoded[0]),
gasLimit: Lib_RLPReader.toUint(decoded[2]),
target: Lib_RLPReader.toAddress(decoded[3]),
data: Lib_RLPReader.toBytes(decoded[5])
nonce: Lib_RLPReader.readUint256(decoded[0]),
gasLimit: Lib_RLPReader.readUint256(decoded[2]),
target: Lib_RLPReader.readAddress(decoded[3]),
data: Lib_RLPReader.readBytes(decoded[5])
});
}
......@@ -158,4 +163,77 @@ library Lib_OVMCodec {
{
return keccak256(encodeTransaction(_transaction));
}
/**
* Converts an OVM account to an EVM account.
* @param _in OVM account to convert.
* @return _out Converted EVM account.
*/
function toEVMAccount(
Account memory _in
)
internal
pure
returns (
EVMAccount memory _out
)
{
return EVMAccount({
nonce: _in.nonce,
balance: _in.balance,
storageRoot: _in.storageRoot,
codeHash: _in.codeHash
});
}
/**
* @notice RLP-encodes an account state struct.
* @param _account Account state struct.
* @return _encoded RLP-encoded account state.
*/
function encodeEVMAccount(
EVMAccount memory _account
)
internal
pure
returns (
bytes memory _encoded
)
{
bytes[] memory raw = new bytes[](4);
// Unfortunately we can't create this array outright because
// RLPWriter.encodeList will reject fixed-size arrays. Assigning
// index-by-index circumvents this issue.
raw[0] = Lib_RLPWriter.writeUint(_account.nonce);
raw[1] = Lib_RLPWriter.writeUint(_account.balance);
raw[2] = Lib_RLPWriter.writeBytes(abi.encodePacked(_account.storageRoot));
raw[3] = Lib_RLPWriter.writeBytes(abi.encodePacked(_account.codeHash));
return Lib_RLPWriter.writeList(raw);
}
/**
* @notice Decodes an RLP-encoded account state into a useful struct.
* @param _encoded RLP-encoded account state.
* @return _account Account state struct.
*/
function decodeEVMAccount(
bytes memory _encoded
)
internal
pure
returns (
EVMAccount memory _account
)
{
Lib_RLPReader.RLPItem[] memory accountState = Lib_RLPReader.readList(_encoded);
return EVMAccount({
nonce: Lib_RLPReader.readUint256(accountState[0]),
balance: Lib_RLPReader.readUint256(accountState[1]),
storageRoot: Lib_RLPReader.readBytes32(accountState[2]),
codeHash: Lib_RLPReader.readBytes32(accountState[3])
});
}
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/**
* @title RLPReader
* @author Hamdi Allam hamdi.allam97@gmail.com
* @title Lib_RLPReader
* @dev Adapted from "RLPReader" by Hamdi Allam (hamdi.allam97@gmail.com).
*/
library Lib_RLPReader {
/*
* Data Structures
*/
struct RLPItem {
uint len;
uint memPtr;
}
/*************
* Constants *
*************/
uint256 constant internal MAX_LIST_LENGTH = 32;
/*
* Contract Constants
*/
uint8 constant private STRING_SHORT_START = 0x80;
uint8 constant private STRING_LONG_START = 0xb8;
uint8 constant private LIST_SHORT_START = 0xc0;
uint8 constant private LIST_LONG_START = 0xf8;
uint8 constant private WORD_SIZE = 32;
/*********
* Enums *
*********/
/*
* Public Functions
*/
enum RLPItemType {
DATA_ITEM,
LIST_ITEM
}
/***********
* Structs *
***********/
struct RLPItem {
uint256 length;
uint256 ptr;
}
/**********************
* Internal Functions *
**********************/
/**
* @param item RLP encoded bytes
* Converts bytes to a reference to memory position and length.
* @param _in Input bytes to convert.
* @return Output memory reference.
*/
function toRlpItem(
bytes memory item
function toRLPItem(
bytes memory _in
)
internal
pure
returns (RLPItem memory)
returns (
RLPItem memory
)
{
uint memPtr;
uint256 ptr;
assembly {
memPtr := add(item, 0x20)
ptr := add(_in, 32)
}
return RLPItem(item.length, memPtr);
return RLPItem({
length: _in.length,
ptr: ptr
});
}
/**
* @param item RLP encoded bytes
* Reads an RLP list value into a list of RLP items.
* @param _in RLP list value.
* @return Decoded RLP list items.
*/
function rlpLen(
RLPItem memory item
function readList(
RLPItem memory _in
)
internal
pure
returns (uint)
returns (
RLPItem[] memory
)
{
return item.len;
(
uint256 listOffset,
uint256 listLength,
RLPItemType itemType
) = _decodeLength(_in);
require(
itemType == RLPItemType.LIST_ITEM,
"Invalid RLP list value."
);
// Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by
// writing to the length. Since we can't know the number of RLP items without looping over
// the entire input, we'd have to loop twice to accurately size this array. It's easier to
// simply set a reasonable maximum list length and decrease the size before we finish.
RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH);
uint256 itemCount = 0;
uint256 offset = listOffset;
while (offset < _in.length) {
require(
itemCount < MAX_LIST_LENGTH,
"Provided RLP list exceeds max list length."
);
(
uint256 itemOffset,
uint256 itemLength,
) = _decodeLength(RLPItem({
length: _in.length - offset,
ptr: _in.ptr + offset
}));
out[itemCount] = RLPItem({
length: itemLength + itemOffset,
ptr: _in.ptr + offset
});
itemCount += 1;
offset += itemOffset + itemLength;
}
// Decrease the array size to match the actual item count.
assembly {
mstore(out, itemCount)
}
return out;
}
/**
* @param item RLP encoded bytes
* Reads an RLP list value into a list of RLP items.
* @param _in RLP list value.
* @return Decoded RLP list items.
*/
function payloadLen(
RLPItem memory item
function readList(
bytes memory _in
)
internal
pure
returns (uint)
returns (
RLPItem[] memory
)
{
return item.len - _payloadOffset(item.memPtr);
return readList(
toRLPItem(_in)
);
}
/**
* @param item RLP encoded list in bytes
* Reads an RLP bytes value into bytes.
* @param _in RLP bytes value.
* @return Decoded bytes.
*/
function toList(
RLPItem memory item
function readBytes(
RLPItem memory _in
)
internal
pure
returns (RLPItem[] memory result)
returns (
bytes memory
)
{
require(isList(item));
uint items = numItems(item);
result = new RLPItem[](items);
uint memPtr = item.memPtr + _payloadOffset(item.memPtr);
uint dataLen;
for (uint i = 0; i < items; i++) {
dataLen = _itemLength(memPtr);
result[i] = RLPItem(dataLen, memPtr);
memPtr = memPtr + dataLen;
}
(
uint256 itemOffset,
uint256 itemLength,
RLPItemType itemType
) = _decodeLength(_in);
require(
itemType == RLPItemType.DATA_ITEM,
"Invalid RLP bytes value."
);
return _copy(_in.ptr, itemOffset, itemLength);
}
// @return indicator whether encoded payload is a list. negate this function call for isData.
function isList(
RLPItem memory item
/**
* Reads an RLP bytes value into bytes.
* @param _in RLP bytes value.
* @return Decoded bytes.
*/
function readBytes(
bytes memory _in
)
internal
pure
returns (bool)
returns (
bytes memory
)
{
if (item.len == 0) return false;
uint8 byte0;
uint memPtr = item.memPtr;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < LIST_SHORT_START)
return false;
return true;
return readBytes(
toRLPItem(_in)
);
}
/** RLPItem conversions into data types **/
// @returns raw rlp encoding in bytes
function toRlpBytes(
RLPItem memory item
/**
* Reads an RLP string value into a string.
* @param _in RLP string value.
* @return Decoded string.
*/
function readString(
RLPItem memory _in
)
internal
pure
returns (bytes memory)
returns (
string memory
)
{
bytes memory result = new bytes(item.len);
if (result.length == 0) return result;
uint ptr;
assembly {
ptr := add(0x20, result)
}
return string(readBytes(_in));
}
copy(item.memPtr, ptr, item.len);
return result;
/**
* Reads an RLP string value into a string.
* @param _in RLP string value.
* @return Decoded string.
*/
function readString(
bytes memory _in
)
internal
pure
returns (
string memory
)
{
return readString(
toRLPItem(_in)
);
}
// any non-zero byte is considered true
function toBoolean(
RLPItem memory item
/**
* Reads an RLP bytes32 value into a bytes32.
* @param _in RLP bytes32 value.
* @return Decoded bytes32.
*/
function readBytes32(
RLPItem memory _in
)
internal
pure
returns (bool)
returns (
bytes32
)
{
require(item.len == 1);
uint result;
uint memPtr = item.memPtr;
require(
_in.length <= 33,
"Invalid RLP bytes32 value."
);
(
uint256 itemOffset,
uint256 itemLength,
RLPItemType itemType
) = _decodeLength(_in);
require(
itemType == RLPItemType.DATA_ITEM,
"Invalid RLP bytes32 value."
);
uint256 ptr = _in.ptr + itemOffset;
bytes32 out;
assembly {
result := byte(0, mload(memPtr))
out := mload(ptr)
// Shift the bytes over to match the item size.
if lt(itemLength, 32) {
out := div(out, exp(256, sub(32, itemLength)))
}
}
return result == 0 ? false : true;
return out;
}
function toAddress(
RLPItem memory item
/**
* Reads an RLP bytes32 value into a bytes32.
* @param _in RLP bytes32 value.
* @return Decoded bytes32.
*/
function readBytes32(
bytes memory _in
)
internal
pure
returns (address)
returns (
bytes32
)
{
// 1 byte for the length prefix
require(item.len == 21);
return address(toUint(item));
return readBytes32(
toRLPItem(_in)
);
}
function toUint(
RLPItem memory item
/**
* Reads an RLP uint256 value into a uint256.
* @param _in RLP uint256 value.
* @return Decoded uint256.
*/
function readUint256(
RLPItem memory _in
)
internal
pure
returns (uint)
returns (
uint256
)
{
require(item.len > 0 && item.len <= 33);
uint offset = _payloadOffset(item.memPtr);
uint len = item.len - offset;
uint result;
uint memPtr = item.memPtr + offset;
assembly {
result := mload(memPtr)
// shfit to the correct location if neccesary
if lt(len, 32) {
result := div(result, exp(256, sub(32, len)))
}
}
return uint256(readBytes32(_in));
}
return result;
/**
* Reads an RLP uint256 value into a uint256.
* @param _in RLP uint256 value.
* @return Decoded uint256.
*/
function readUint256(
bytes memory _in
)
internal
pure
returns (
uint256
)
{
return readUint256(
toRLPItem(_in)
);
}
// enforces 32 byte length
function toUintStrict(
RLPItem memory item
/**
* Reads an RLP bool value into a bool.
* @param _in RLP bool value.
* @return Decoded bool.
*/
function readBool(
RLPItem memory _in
)
internal
pure
returns (uint)
returns (
bool
)
{
// one byte prefix
require(item.len == 33);
require(
_in.length == 1,
"Invalid RLP boolean value."
);
uint result;
uint memPtr = item.memPtr + 1;
uint256 ptr = _in.ptr;
uint256 out;
assembly {
result := mload(memPtr)
out := byte(0, mload(ptr))
}
return result;
return out != 0;
}
function toBytes(
RLPItem memory item
/**
* Reads an RLP bool value into a bool.
* @param _in RLP bool value.
* @return Decoded bool.
*/
function readBool(
bytes memory _in
)
internal
pure
returns (bytes memory)
returns (
bool
)
{
require(item.len > 0);
uint offset = _payloadOffset(item.memPtr);
uint len = item.len - offset; // data length
bytes memory result = new bytes(len);
return readBool(
toRLPItem(_in)
);
}
uint destPtr;
assembly {
destPtr := add(0x20, result)
}
/**
* Reads an RLP address value into a address.
* @param _in RLP address value.
* @return Decoded address.
*/
function readAddress(
RLPItem memory _in
)
internal
pure
returns (
address
)
{
require(
_in.length == 21,
"Invalid RLP address value."
);
copy(item.memPtr + offset, destPtr, len);
return result;
return address(readUint256(_in));
}
/*
* Private Functions
/**
* Reads an RLP address value into a address.
* @param _in RLP address value.
* @return Decoded address.
*/
// @return number of payload items inside an encoded list.
function numItems(
RLPItem memory item
function readAddress(
bytes memory _in
)
private
internal
pure
returns (uint)
returns (
address
)
{
if (item.len == 0) return 0;
uint count = 0;
uint currPtr = item.memPtr + _payloadOffset(item.memPtr);
uint endPtr = item.memPtr + item.len;
while (currPtr < endPtr) {
currPtr = currPtr + _itemLength(currPtr); // skip over an item
count++;
}
return readAddress(
toRLPItem(_in)
);
}
return count;
/**
* Reads the raw bytes of an RLP item.
* @param _in RLP item to read.
* @return Raw RLP bytes.
*/
function readRawBytes(
RLPItem memory _in
)
internal
pure
returns (
bytes memory
)
{
return _copy(_in);
}
// @return entire rlp item byte length
function _itemLength(
uint memPtr
/*********************
* Private Functions *
*********************/
/**
* Decodes the length of an RLP item.
* @param _in RLP item to decode.
* @return Offset of the encoded data.
* @return Length of the encoded data.
* @return RLP item type (LIST_ITEM or DATA_ITEM).
*/
function _decodeLength(
RLPItem memory _in
)
private
pure
returns (uint len)
returns (
uint256,
uint256,
RLPItemType
)
{
uint byte0;
require(
_in.length > 0,
"RLP item cannot be null."
);
uint256 ptr = _in.ptr;
uint256 prefix;
assembly {
byte0 := byte(0, mload(memPtr))
prefix := byte(0, mload(ptr))
}
if (byte0 < STRING_SHORT_START)
return 1;
else if (byte0 < STRING_LONG_START)
return byte0 - STRING_SHORT_START + 1;
if (prefix <= 0x7f) {
// Single byte.
return (0, 1, RLPItemType.DATA_ITEM);
} else if (prefix <= 0xb7) {
// Short string.
uint256 strLen = prefix - 0x80;
require(
_in.length > strLen,
"Invalid RLP short string."
);
else if (byte0 < LIST_SHORT_START) {
return (1, strLen, RLPItemType.DATA_ITEM);
} else if (prefix <= 0xbf) {
// Long string.
uint256 lenOfStrLen = prefix - 0xb7;
require(
_in.length > lenOfStrLen,
"Invalid RLP long string length."
);
uint256 strLen;
assembly {
let byteLen := sub(byte0, 0xb7) // number of bytes the actual length is
memPtr := add(memPtr, 1) // skip over the first byte
/* 32 byte word size */
let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len
len := add(dataLen, add(byteLen, 1))
// Pick out the string length.
strLen := div(
mload(add(ptr, 1)),
exp(256, sub(32, lenOfStrLen))
)
}
}
else if (byte0 < LIST_LONG_START) {
return byte0 - LIST_SHORT_START + 1;
}
require(
_in.length > lenOfStrLen + strLen,
"Invalid RLP long string."
);
else {
assembly {
let byteLen := sub(byte0, 0xf7)
memPtr := add(memPtr, 1)
return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM);
} else if (prefix <= 0xf7) {
// Short list.
uint256 listLen = prefix - 0xc0;
let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length
len := add(dataLen, add(byteLen, 1))
require(
_in.length > listLen,
"Invalid RLP short list."
);
return (1, listLen, RLPItemType.LIST_ITEM);
} else {
// Long list.
uint256 lenOfListLen = prefix - 0xf7;
require(
_in.length > lenOfListLen,
"Invalid RLP long list length."
);
uint256 listLen;
assembly {
// Pick out the list length.
listLen := div(
mload(add(ptr, 1)),
exp(256, sub(32, lenOfListLen))
)
}
require(
_in.length > lenOfListLen + listLen,
"Invalid RLP long list."
);
return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM);
}
}
// @return number of bytes until the data
function _payloadOffset(
uint memPtr
/**
* Copies the bytes from a memory location.
* @param _src Pointer to the location to read from.
* @param _offset Offset to start reading from.
* @param _length Number of bytes to read.
* @return Copied bytes.
*/
function _copy(
uint256 _src,
uint256 _offset,
uint256 _length
)
private
pure
returns (uint)
returns (
bytes memory
)
{
uint byte0;
assembly {
byte0 := byte(0, mload(memPtr))
bytes memory out = new bytes(_length);
if (out.length == 0) {
return out;
}
if (byte0 < STRING_SHORT_START)
return 0;
else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START))
return 1;
else if (byte0 < LIST_SHORT_START) // being explicit
return byte0 - (STRING_LONG_START - 1) + 1;
else
return byte0 - (LIST_LONG_START - 1) + 1;
}
/*
* @param src Pointer to source
* @param dest Pointer to destination
* @param len Amount of memory to copy from the source
*/
function copy(
uint src,
uint dest,
uint len
)
private
pure
{
if (len == 0) return;
uint256 src = _src + _offset;
uint256 dest;
assembly {
dest := add(out, 32)
}
// copy as many word sizes as possible
for (; len >= WORD_SIZE; len -= WORD_SIZE) {
// Copy over as many complete words as we can.
for (uint256 i = 0; i < _length / 32; i++) {
assembly {
mstore(dest, mload(src))
}
src += WORD_SIZE;
dest += WORD_SIZE;
src += 32;
dest += 32;
}
// left over bytes. Mask is used to remove unwanted bytes from the word
uint mask = 256 ** (WORD_SIZE - len) - 1;
// Pick out the remaining bytes.
uint256 mask = 256 ** (32 - (_length % 32)) - 1;
assembly {
let srcpart := and(mload(src), not(mask)) // zero out src
let destpart := and(mload(dest), mask) // retrieve the bytes
mstore(dest, or(destpart, srcpart))
mstore(
dest,
or(
and(mload(src), not(mask)),
and(mload(dest), mask)
)
)
}
return out;
}
/**
* Copies an RLP item into bytes.
* @param _in RLP item to copy.
* @return Copied bytes.
*/
function _copy(
RLPItem memory _in
)
private
pure
returns (
bytes memory
)
{
return _copy(_in.ptr, 0, _in.length);
}
}
\ No newline at end of file
}
......@@ -20,7 +20,7 @@ library Lib_RLPWriter {
* @param _in The byte string to encode.
* @return _out The RLP encoded string in bytes.
*/
function encodeBytes(
function writeBytes(
bytes memory _in
)
internal
......@@ -34,7 +34,7 @@ library Lib_RLPWriter {
if (_in.length == 1 && uint8(_in[0]) < 128) {
encoded = _in;
} else {
encoded = Lib_BytesUtils.concat(encodeLength(_in.length, 128), _in);
encoded = Lib_BytesUtils.concat(_writeLength(_in.length, 128), _in);
}
return encoded;
......@@ -45,7 +45,7 @@ library Lib_RLPWriter {
* @param _in The list of RLP encoded byte strings.
* @return _out The RLP encoded list of items in bytes.
*/
function encodeList(
function writeList(
bytes[] memory _in
)
internal
......@@ -54,8 +54,8 @@ library Lib_RLPWriter {
bytes memory _out
)
{
bytes memory list = flatten(_in);
return Lib_BytesUtils.concat(encodeLength(list.length, 192), list);
bytes memory list = _flatten(_in);
return Lib_BytesUtils.concat(_writeLength(list.length, 192), list);
}
/**
......@@ -63,7 +63,7 @@ library Lib_RLPWriter {
* @param _in The string to encode.
* @return _out The RLP encoded string in bytes.
*/
function encodeString(
function writeString(
string memory _in
)
internal
......@@ -72,7 +72,7 @@ library Lib_RLPWriter {
bytes memory _out
)
{
return encodeBytes(bytes(_in));
return writeBytes(bytes(_in));
}
/**
......@@ -80,7 +80,7 @@ library Lib_RLPWriter {
* @param _in The address to encode.
* @return _out The RLP encoded address in bytes.
*/
function encodeAddress(
function writeAddress(
address _in
)
internal
......@@ -97,7 +97,7 @@ library Lib_RLPWriter {
inputBytes := m
}
return encodeBytes(inputBytes);
return writeBytes(inputBytes);
}
/**
......@@ -105,7 +105,7 @@ library Lib_RLPWriter {
* @param _in The uint to encode.
* @return _out The RLP encoded uint in bytes.
*/
function encodeUint(
function writeUint(
uint _in
)
internal
......@@ -114,7 +114,7 @@ library Lib_RLPWriter {
bytes memory _out
)
{
return encodeBytes(toBinary(_in));
return writeBytes(_toBinary(_in));
}
/**
......@@ -122,7 +122,7 @@ library Lib_RLPWriter {
* @param _in The int to encode.
* @return _out The RLP encoded int in bytes.
*/
function encodeInt(
function writeInt(
int _in
)
internal
......@@ -131,7 +131,7 @@ library Lib_RLPWriter {
bytes memory _out
)
{
return encodeUint(uint(_in));
return writeUint(uint(_in));
}
/**
......@@ -139,7 +139,7 @@ library Lib_RLPWriter {
* @param _in The bool to encode.
* @return _out The RLP encoded bool in bytes.
*/
function encodeBool(
function writeBool(
bool _in
)
internal
......@@ -164,7 +164,7 @@ library Lib_RLPWriter {
* @param _offset 128 if item is string, 192 if item is list.
* @return _encoded RLP encoded bytes.
*/
function encodeLength(
function _writeLength(
uint _len,
uint _offset
)
......@@ -203,7 +203,7 @@ library Lib_RLPWriter {
* @param _x The integer to encode.
* @return _binary RLP encoded bytes.
*/
function toBinary(
function _toBinary(
uint _x
)
private
......@@ -239,7 +239,7 @@ library Lib_RLPWriter {
* @param _src Source location.
* @param _len Length of memory to copy.
*/
function memcpy(
function _memcpy(
uint _dest,
uint _src,
uint _len
......@@ -273,7 +273,7 @@ library Lib_RLPWriter {
* @param _list List of byte strings to flatten.
* @return _flattened The flattened byte string.
*/
function flatten(
function _flatten(
bytes[] memory _list
)
private
......@@ -302,7 +302,7 @@ library Lib_RLPWriter {
uint listPtr;
assembly { listPtr := add(item, 0x20)}
memcpy(flattenedPtr, listPtr, item.length);
_memcpy(flattenedPtr, listPtr, item.length);
flattenedPtr += _list[i].length;
}
......
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_SecureMerkleTrie } from "./Lib_SecureMerkleTrie.sol";
import { Lib_OVMCodec } from "../codec/Lib_OVMCodec.sol";
import { Lib_BytesUtils } from "../utils/Lib_BytesUtils.sol";
import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol";
import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol";
/**
* @title Lib_EthMerkleTrie
*/
library Lib_EthMerkleTrie {
/**********************
* Contract Constants *
**********************/
bytes constant private RLP_NULL_BYTES = hex'80';
bytes32 constant private BYTES32_NULL = bytes32('');
uint256 constant private UINT256_NULL = uint256(0);
/*************************************
* Internal Functions: Storage Slots *
*************************************/
/**
* @notice Verifies a proof for the value of an account storage slot.
* @param _address Address of the contract account.
* @param _key Key for the storage slot.
* @param _value Value for the storage slot.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _storageTrieWitness Inclusion proof for the specific storage
* slot associated with the given key.
* @param _stateTrieRoot Known root of the state trie.
* @return `true` if the k/v pair is included, `false` otherwise.
*/
function proveAccountStorageSlotValue(
address _address,
bytes32 _key,
bytes32 _value,
bytes memory _stateTrieWitness,
bytes memory _storageTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bool)
{
// Retrieve the current storage root.
Lib_OVMCodec.EVMAccount memory accountState = getAccountState(
_address,
_stateTrieWitness,
_stateTrieRoot
);
// Verify inclusion of the given k/v pair in the storage trie.
return Lib_SecureMerkleTrie.verifyInclusionProof(
abi.encodePacked(_key),
abi.encodePacked(_value),
_storageTrieWitness,
accountState.storageRoot
);
}
/**
* @notice Updates the value for a given account storage slot.
* @param _address Address of the contract account.
* @param _key Key for the storage slot.
* @param _value New value for the storage slot.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _storageTrieWitness Inclusion proof for the specific storage
* slot associated with the given key.
* @param _stateTrieRoot Known root of the state trie.
* @return Root hash of the updated state trie.
*/
function updateAccountStorageSlotValue(
address _address,
bytes32 _key,
bytes32 _value,
bytes memory _stateTrieWitness,
bytes memory _storageTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bytes32)
{
// Retreive the old storage root.
Lib_OVMCodec.EVMAccount memory accountState = getAccountState(
_address,
_stateTrieWitness,
_stateTrieRoot
);
// Generate a new storage root.
accountState.storageRoot = Lib_SecureMerkleTrie.update(
abi.encodePacked(_key),
abi.encodePacked(_value),
_storageTrieWitness,
accountState.storageRoot
);
// Update the state trie with the new storage root.
return setAccountState(
accountState,
_address,
_stateTrieWitness,
_stateTrieRoot
);
}
/**************************************
* Internal Functions: Account Proofs *
*************************************/
/**
* @notice Verifies a proof of the current state for a given account.
* @param _address Address of the target account.
* @param _accountState Account state object to verify.
* @param _proofMatrix Matrix of fields to verify or ignore.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return `true` if the given account state is valid, `false` otherwise.
*/
function proveAccountState(
address _address,
Lib_OVMCodec.EVMAccount memory _accountState,
Lib_OVMCodec.ProofMatrix memory _proofMatrix,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bool)
{
// Pull the current account state.
Lib_OVMCodec.EVMAccount memory accountState = getAccountState(
_address,
_stateTrieWitness,
_stateTrieRoot
);
// Check each provided component conditionally.
return (
(!_proofMatrix.checkNonce || accountState.nonce == _accountState.nonce) &&
(!_proofMatrix.checkBalance || accountState.balance == _accountState.balance) &&
(!_proofMatrix.checkStorageRoot || accountState.storageRoot == _accountState.storageRoot) &&
(!_proofMatrix.checkCodeHash || accountState.codeHash == _accountState.codeHash)
);
}
/**
* @notice Verifies a proof of the current state for a given account.
* @param _address Address of the target account.
* @param _accountState Account state object to verify.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return `true` if the given account state is valid, `false` otherwise.
*/
function proveAccountState(
address _address,
Lib_OVMCodec.EVMAccount memory _accountState,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bool)
{
return proveAccountState(
_address,
_accountState,
Lib_OVMCodec.ProofMatrix({
checkNonce: true,
checkBalance: true,
checkStorageRoot: true,
checkCodeHash: true
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Verifies a proof of the current state for a given account.
* @param _address Address of the target account.
* @param _accountState Account state object to verify.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return `true` if the given account state is valid, `false` otherwise.
*/
function proveAccountState(
address _address,
Lib_OVMCodec.Account memory _accountState,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bool)
{
return proveAccountState(
_address,
Lib_OVMCodec.EVMAccount({
nonce: _accountState.nonce,
balance: _accountState.balance,
storageRoot: _accountState.storageRoot,
codeHash: _accountState.codeHash
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Verifies a proof of the account nonce.
* @param _address Address of the target account.
* @param _nonce Account transaction nonce.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return `true` if the given nonce is valid, `false` otherwise.
*/
function proveAccountNonce(
address _address,
uint256 _nonce,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bool)
{
return proveAccountState(
_address,
Lib_OVMCodec.EVMAccount({
nonce: _nonce,
balance: UINT256_NULL,
storageRoot: BYTES32_NULL,
codeHash: BYTES32_NULL
}),
Lib_OVMCodec.ProofMatrix({
checkNonce: true,
checkBalance: false,
checkStorageRoot: false,
checkCodeHash: false
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Verifies a proof of the account balance.
* @param _address Address of the target account.
* @param _balance Account balance in wei.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return `true` if the given balance is valid, `false` otherwise.
*/
function proveAccountBalance(
address _address,
uint256 _balance,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bool)
{
return proveAccountState(
_address,
Lib_OVMCodec.EVMAccount({
nonce: UINT256_NULL,
balance: _balance,
storageRoot: BYTES32_NULL,
codeHash: BYTES32_NULL
}),
Lib_OVMCodec.ProofMatrix({
checkNonce: false,
checkBalance: true,
checkStorageRoot: false,
checkCodeHash: false
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Verifies a proof of the account storage root.
* @param _address Address of the target account.
* @param _storageRoot Account storage root, empty if EOA.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return `true` if the given storage root is valid, `false` otherwise.
*/
function proveAccountStorageRoot(
address _address,
bytes32 _storageRoot,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bool)
{
return proveAccountState(
_address,
Lib_OVMCodec.EVMAccount({
nonce: UINT256_NULL,
balance: UINT256_NULL,
storageRoot: _storageRoot,
codeHash: BYTES32_NULL
}),
Lib_OVMCodec.ProofMatrix({
checkNonce: false,
checkBalance: false,
checkStorageRoot: true,
checkCodeHash: false
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Verifies a proof of the account code hash.
* @param _address Address of the target account.
* @param _codeHash Account code hash, empty if EOA.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return `true` if the given code hash is valid, `false` otherwise.
*/
function proveAccountCodeHash(
address _address,
bytes32 _codeHash,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bool)
{
return proveAccountState(
_address,
Lib_OVMCodec.EVMAccount({
nonce: UINT256_NULL,
balance: UINT256_NULL,
storageRoot: BYTES32_NULL,
codeHash: _codeHash
}),
Lib_OVMCodec.ProofMatrix({
checkNonce: false,
checkBalance: false,
checkStorageRoot: false,
checkCodeHash: true
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/***************************************
* Internal Functions: Account Updates *
***************************************/
/**
* @notice Updates the current state for a given account.
* @param _address Address of the target account.
* @param _accountState Account state to insert.
* @param _proofMatrix Matrix of fields to update or ignore.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return Root hash of the updated state trie.
*/
function updateAccountState(
address _address,
Lib_OVMCodec.EVMAccount memory _accountState,
Lib_OVMCodec.ProofMatrix memory _proofMatrix,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bytes32)
{
Lib_OVMCodec.EVMAccount memory newAccountState = _accountState;
// If the user has provided everything, don't bother pulling the
// current account state.
if (
!_proofMatrix.checkNonce ||
!_proofMatrix.checkBalance ||
!_proofMatrix.checkStorageRoot ||
!_proofMatrix.checkCodeHash
) {
// Pull the old account state.
Lib_OVMCodec.EVMAccount memory oldAccountState = getAccountState(
_address,
_stateTrieWitness,
_stateTrieRoot
);
// Conditionally update elements that haven't been provided with
// elements from the old account state.
if (!_proofMatrix.checkNonce) {
newAccountState.nonce = oldAccountState.nonce;
}
if (!_proofMatrix.checkBalance) {
newAccountState.balance = oldAccountState.balance;
}
if (!_proofMatrix.checkStorageRoot) {
newAccountState.storageRoot = oldAccountState.storageRoot;
}
if (!_proofMatrix.checkCodeHash) {
newAccountState.codeHash = oldAccountState.codeHash;
}
}
// Update the account state.
return setAccountState(
newAccountState,
_address,
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Updates the current state for a given account.
* @param _address Address of the target account.
* @param _accountState Account state to insert.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return Root hash of the updated state trie.
*/
function updateAccountState(
address _address,
Lib_OVMCodec.EVMAccount memory _accountState,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bytes32)
{
return updateAccountState(
_address,
_accountState,
Lib_OVMCodec.ProofMatrix({
checkNonce: true,
checkBalance: true,
checkStorageRoot: true,
checkCodeHash: true
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Updates the current state for a given account.
* @param _address Address of the target account.
* @param _accountState Account state to insert.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return Root hash of the updated state trie.
*/
function updateAccountState(
address _address,
Lib_OVMCodec.Account memory _accountState,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bytes32)
{
return updateAccountState(
_address,
Lib_OVMCodec.EVMAccount({
nonce: _accountState.nonce,
balance: _accountState.balance,
storageRoot: _accountState.storageRoot,
codeHash: _accountState.codeHash
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Updates an account nonce.
* @param _address Address of the target account.
* @param _nonce New account transaction nonce.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return Root hash of the updated state trie.
*/
function updateAccountNonce(
address _address,
uint256 _nonce,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bytes32)
{
return updateAccountState(
_address,
Lib_OVMCodec.EVMAccount({
nonce: _nonce,
balance: UINT256_NULL,
storageRoot: BYTES32_NULL,
codeHash: BYTES32_NULL
}),
Lib_OVMCodec.ProofMatrix({
checkNonce: true,
checkBalance: false,
checkStorageRoot: false,
checkCodeHash: false
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Updates an account balance.
* @param _address Address of the target account.
* @param _balance New account balance in wei.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return Root hash of the updated state trie.
*/
function updateAccountBalance(
address _address,
uint256 _balance,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bytes32)
{
return updateAccountState(
_address,
Lib_OVMCodec.EVMAccount({
nonce: UINT256_NULL,
balance: _balance,
storageRoot: BYTES32_NULL,
codeHash: BYTES32_NULL
}),
Lib_OVMCodec.ProofMatrix({
checkNonce: false,
checkBalance: true,
checkStorageRoot: false,
checkCodeHash: false
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Updates an account storage root.
* @param _address Address of the target account.
* @param _storageRoot New account storage root, empty if EOA.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return Root hash of the updated state trie.
*/
function updateAccountStorageRoot(
address _address,
bytes32 _storageRoot,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bytes32)
{
return updateAccountState(
_address,
Lib_OVMCodec.EVMAccount({
nonce: UINT256_NULL,
balance: UINT256_NULL,
storageRoot: _storageRoot,
codeHash: BYTES32_NULL
}),
Lib_OVMCodec.ProofMatrix({
checkNonce: false,
checkBalance: false,
checkStorageRoot: true,
checkCodeHash: false
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/**
* @notice Updates an account code hash.
* @param _address Address of the target account.
* @param _codeHash New account code hash, empty if EOA.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return Root hash of the updated state trie.
*/
function updateAccountCodeHash(
address _address,
bytes32 _codeHash,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
internal
view
returns (bytes32)
{
return updateAccountState(
_address,
Lib_OVMCodec.EVMAccount({
nonce: UINT256_NULL,
balance: UINT256_NULL,
storageRoot: BYTES32_NULL,
codeHash: _codeHash
}),
Lib_OVMCodec.ProofMatrix({
checkNonce: false,
checkBalance: false,
checkStorageRoot: false,
checkCodeHash: true
}),
_stateTrieWitness,
_stateTrieRoot
);
}
/*********************
* Private Functions *
*********************/
/**
* @notice Decodes an RLP-encoded account state into a useful struct.
* @param _encodedAccountState RLP-encoded account state.
* @return Account state struct.
*/
function decodeAccountState(
bytes memory _encodedAccountState
)
private
view
returns (Lib_OVMCodec.EVMAccount memory)
{
Lib_RLPReader.RLPItem[] memory accountState = Lib_RLPReader.toList(Lib_RLPReader.toRlpItem(_encodedAccountState));
return Lib_OVMCodec.EVMAccount({
nonce: Lib_RLPReader.toUint(accountState[0]),
balance: Lib_RLPReader.toUint(accountState[1]),
storageRoot: Lib_BytesUtils.toBytes32(Lib_RLPReader.toBytes(accountState[2])),
codeHash: Lib_BytesUtils.toBytes32(Lib_RLPReader.toBytes(accountState[3]))
});
}
/**
* @notice RLP-encodes an account state struct.
* @param _accountState Account state struct.
* @return RLP-encoded account state.
*/
function encodeAccountState(
Lib_OVMCodec.EVMAccount memory _accountState
)
private
view
returns (bytes memory)
{
bytes[] memory raw = new bytes[](4);
// Unfortunately we can't create this array outright because
// RLPWriter.encodeList will reject fixed-size arrays. Assigning
// index-by-index circumvents this issue.
raw[0] = Lib_RLPWriter.encodeUint(_accountState.nonce);
raw[1] = Lib_RLPWriter.encodeUint(_accountState.balance);
raw[2] = _accountState.storageRoot == 0 ? RLP_NULL_BYTES : Lib_RLPWriter.encodeBytes(abi.encodePacked(_accountState.storageRoot));
raw[3] = _accountState.codeHash == 0 ? RLP_NULL_BYTES : Lib_RLPWriter.encodeBytes(abi.encodePacked(_accountState.codeHash));
return Lib_RLPWriter.encodeList(raw);
}
/**
* @notice Retrieves the current account state and converts into a struct.
* @param _address Account address.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
*/
function getAccountState(
address _address,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
private
view
returns (Lib_OVMCodec.EVMAccount memory)
{
Lib_OVMCodec.EVMAccount memory DEFAULT_ACCOUNT_STATE = Lib_OVMCodec.EVMAccount({
nonce: UINT256_NULL,
balance: UINT256_NULL,
storageRoot: keccak256(hex'80'),
codeHash: keccak256(hex'')
});
(
bool exists,
bytes memory encodedAccountState
) = Lib_SecureMerkleTrie.get(
abi.encodePacked(_address),
_stateTrieWitness,
_stateTrieRoot
);
return exists ? decodeAccountState(encodedAccountState) : DEFAULT_ACCOUNT_STATE;
}
/**
* @notice Updates the current account state for a given address.
* @param _accountState New account state, as a struct.
* @param _address Account address.
* @param _stateTrieWitness Inclusion proof for the account state within
* the state trie.
* @param _stateTrieRoot Known root of the state trie.
* @return Root hash of the updated state trie.
*/
function setAccountState(
Lib_OVMCodec.EVMAccount memory _accountState,
address _address,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
private
view
returns (bytes32)
{
bytes memory encodedAccountState = encodeAccountState(_accountState);
return Lib_SecureMerkleTrie.update(
abi.encodePacked(_address),
encodedAccountState,
_stateTrieWitness,
_stateTrieRoot
);
}
}
\ No newline at end of file
......@@ -6,6 +6,8 @@ import { Lib_BytesUtils } from "../utils/Lib_BytesUtils.sol";
import { Lib_RLPReader } from "../rlp/Lib_RLPReader.sol";
import { Lib_RLPWriter } from "../rlp/Lib_RLPWriter.sol";
import { console } from "@nomiclabs/buidler/console.sol";
/**
* @title Lib_MerkleTrie
*/
......@@ -51,6 +53,7 @@ library Lib_MerkleTrie {
// Just a utility constant. RLP represents `NULL` as 0x80.
bytes1 constant RLP_NULL = bytes1(0x80);
bytes constant RLP_NULL_BYTES = hex'80';
bytes32 constant internal KECCAK256_RLP_NULL_BYTES = keccak256(RLP_NULL_BYTES);
/**********************
......@@ -67,7 +70,7 @@ library Lib_MerkleTrie {
* of a list of RLP-encoded nodes that make a path down to the target node.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @return `true` if the k/v pair exists in the trie, `false` otherwise.
* @return _verified `true` if the k/v pair exists in the trie, `false` otherwise.
*/
function verifyInclusionProof(
bytes memory _key,
......@@ -78,37 +81,45 @@ library Lib_MerkleTrie {
internal
view
returns (
bool
bool _verified
)
{
return _verifyProof(_key, _value, _proof, _root, true);
(
bool exists,
bytes memory value
) = get(_key, _proof, _root);
return (
exists && Lib_BytesUtils.equal(_value, value)
);
}
/**
* @notice Verifies a proof that a given key/value pair is *not* present in
* @notice Verifies a proof that a given key is *not* present in
* the Merkle trie.
* @param _key Key of the node to search for, as a hex string.
* @param _value Value of the node to search for, as a hex string.
* @param _proof Merkle trie inclusion proof for the node *nearest* the
* target node. We effectively need to show that either the key exists and
* its value differs, or the key does not exist at all.
* target node.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @return `true` if the k/v pair is absent in the trie, `false` otherwise.
* @return _verified `true` if the key is absent in the trie, `false` otherwise.
*/
function verifyExclusionProof(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root
)
internal
view
returns (
bool
bool _verified
)
{
return _verifyProof(_key, _value, _proof, _root, false);
(
bool exists,
) = get(_key, _proof, _root);
return exists == false;
}
/**
......@@ -120,7 +131,7 @@ library Lib_MerkleTrie {
* Otherwise, we need to modify the trie to handle the new k/v pair.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @return Root hash of the newly constructed trie.
* @return _updatedRoot Root hash of the newly constructed trie.
*/
function update(
bytes memory _key,
......@@ -131,12 +142,18 @@ library Lib_MerkleTrie {
internal
view
returns (
bytes32
bytes32 _updatedRoot
)
{
// Special case when inserting the very first node.
if (_root == KECCAK256_RLP_NULL_BYTES) {
return keccak256(
_makeLeafNode(_key, _value).encoded
);
}
TrieNode[] memory proof = _parseProof(_proof);
(uint256 pathLength, bytes memory keyRemainder, ) = _walkNodePath(proof, _key, _root);
TrieNode[] memory newPath = _getNewPath(proof, pathLength, keyRemainder, _value);
return _getUpdatedTrieRoot(newPath, _key);
......@@ -147,7 +164,8 @@ library Lib_MerkleTrie {
* @param _key Key to search for, as hex bytes.
* @param _proof Merkle trie inclusion proof for the key.
* @param _root Known root of the Merkle trie.
* @return Whether the node exists, value associated with the key if so.
* @return _exists Whether or not the key exists.
* @return _value Value of the key if it exists.
*/
function get(
bytes memory _key,
......@@ -157,14 +175,20 @@ library Lib_MerkleTrie {
internal
view
returns (
bool,
bytes memory
bool _exists,
bytes memory _value
)
{
TrieNode[] memory proof = _parseProof(_proof);
(uint256 pathLength, bytes memory keyRemainder, ) = _walkNodePath(proof, _key, _root);
(uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = _walkNodePath(proof, _key, _root);
bool exists = keyRemainder.length == 0;
require(
exists || isFinalNode,
"Provided proof is invalid."
);
bytes memory value = exists ? _getNodeValue(proof[pathLength - 1]) : bytes('');
return (
......@@ -177,7 +201,7 @@ library Lib_MerkleTrie {
* Computes the root hash for a trie with a single node.
* @param _key Key for the single node.
* @param _value Value for the single node.
* @return Hash of the trie.
* @return _updatedRoot Hash of the trie.
*/
function getSingleNodeRootHash(
bytes memory _key,
......@@ -186,7 +210,7 @@ library Lib_MerkleTrie {
internal
view
returns (
bytes32
bytes32 _updatedRoot
)
{
return keccak256(_makeLeafNode(
......@@ -200,62 +224,14 @@ library Lib_MerkleTrie {
* Private Functions *
*********************/
/**
* @notice Utility function that handles verification of inclusion or
* exclusion proofs. Since the verification methods are almost identical,
* it's easier to shove this into a single function.
* @param _key Key of the node to search for, as a hex string.
* @param _value Value of the node to search for, as a hex string.
* @param _proof Merkle trie inclusion proof for the node *nearest* the
* target node. If we're proving explicit inclusion, the nearest node
* should be the target node.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @param _inclusion Whether to check for inclusion or exclusion.
* @return `true` if the k/v pair is (in/not in) the trie, `false` otherwise.
*/
function _verifyProof(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root,
bool _inclusion
)
private
view
returns (
bool
)
{
TrieNode[] memory proof = _parseProof(_proof);
(uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = _walkNodePath(proof, _key, _root);
if (_inclusion) {
// Included leaf nodes should have no key remainder, values should match.
return (
keyRemainder.length == 0 &&
Lib_BytesUtils.equal(_getNodeValue(proof[pathLength - 1]), _value)
);
} else {
// If there's no key remainder then a leaf with the given key exists and the value should differ.
// Otherwise, we need to make sure that we've hit a dead end.
return (
(keyRemainder.length == 0 && !Lib_BytesUtils.equal(_getNodeValue(proof[pathLength - 1]), _value)) ||
(keyRemainder.length != 0 && isFinalNode)
);
}
}
/**
* @notice Walks through a proof using a provided key.
* @param _proof Inclusion proof to walk through.
* @param _key Key to use for the walk.
* @param _root Known root of the trie.
* @return (
* Length of the final path;
* Portion of the key remaining after the walk;
* Whether or not we've hit a dead end;
* )
* @return _pathLength Length of the final path
* @return _keyRemainder Portion of the key remaining after the walk.
* @return _isFinalNode Whether or not we've hit a dead end.
*/
function _walkNodePath(
TrieNode[] memory _proof,
......@@ -265,9 +241,9 @@ library Lib_MerkleTrie {
private
view
returns (
uint256,
bytes memory,
bool
uint256 _pathLength,
bytes memory _keyRemainder,
bool _isFinalNode
)
{
uint256 pathLength = 0;
......@@ -355,6 +331,8 @@ library Lib_MerkleTrie {
continue;
}
}
} else {
revert("Received an unparseable node.");
}
}
......@@ -373,7 +351,7 @@ library Lib_MerkleTrie {
* @param _keyRemainder Portion of the initial key that must be inserted
* into the trie.
* @param _value Value to insert at the given key.
* @return A new path with the inserted k/v pair and extra supporting nodes.
* @return _newPath A new path with the inserted k/v pair and extra supporting nodes.
*/
function _getNewPath(
TrieNode[] memory _path,
......@@ -384,7 +362,7 @@ library Lib_MerkleTrie {
private
view
returns (
TrieNode[] memory
TrieNode[] memory _newPath
)
{
bytes memory keyRemainder = _keyRemainder;
......@@ -501,7 +479,7 @@ library Lib_MerkleTrie {
* @notice Computes the trie root from a given path.
* @param _nodes Path to some k/v pair.
* @param _key Key for the k/v pair.
* @return Root hash for the updated trie.
* @return _updatedRoot Root hash for the updated trie.
*/
function _getUpdatedTrieRoot(
TrieNode[] memory _nodes,
......@@ -510,7 +488,7 @@ library Lib_MerkleTrie {
private
view
returns (
bytes32
bytes32 _updatedRoot
)
{
bytes memory key = Lib_BytesUtils.toNibbles(_key);
......@@ -565,7 +543,7 @@ library Lib_MerkleTrie {
/**
* @notice Parses an RLP-encoded proof into something more useful.
* @param _proof RLP-encoded proof to parse.
* @return Proof parsed into easily accessible structs.
* @return _parsed Proof parsed into easily accessible structs.
*/
function _parseProof(
bytes memory _proof
......@@ -573,17 +551,17 @@ library Lib_MerkleTrie {
private
view
returns (
TrieNode[] memory
TrieNode[] memory _parsed
)
{
Lib_RLPReader.RLPItem[] memory nodes = Lib_RLPReader.toList(Lib_RLPReader.toRlpItem(_proof));
Lib_RLPReader.RLPItem[] memory nodes = Lib_RLPReader.readList(_proof);
TrieNode[] memory proof = new TrieNode[](nodes.length);
for (uint256 i = 0; i < nodes.length; i++) {
bytes memory encoded = Lib_RLPReader.toBytes(nodes[i]);
bytes memory encoded = Lib_RLPReader.readBytes(nodes[i]);
proof[i] = TrieNode({
encoded: encoded,
decoded: Lib_RLPReader.toList(Lib_RLPReader.toRlpItem(encoded))
decoded: Lib_RLPReader.readList(encoded)
});
}
......@@ -595,7 +573,7 @@ library Lib_MerkleTrie {
* "hash" within the specification, but nodes < 32 bytes are not actually
* hashed.
* @param _node Node to pull an ID for.
* @return ID for the node, depending on the size of its contents.
* @return _nodeID ID for the node, depending on the size of its contents.
*/
function _getNodeID(
Lib_RLPReader.RLPItem memory _node
......@@ -603,17 +581,17 @@ library Lib_MerkleTrie {
private
view
returns (
bytes32
bytes32 _nodeID
)
{
bytes memory nodeID;
if (_node.len < 32) {
if (_node.length < 32) {
// Nodes smaller than 32 bytes are RLP encoded.
nodeID = Lib_RLPReader.toRlpBytes(_node);
nodeID = Lib_RLPReader.readRawBytes(_node);
} else {
// Nodes 32 bytes or larger are hashed.
nodeID = Lib_RLPReader.toBytes(_node);
nodeID = Lib_RLPReader.readBytes(_node);
}
return Lib_BytesUtils.toBytes32(nodeID);
......@@ -622,7 +600,7 @@ library Lib_MerkleTrie {
/**
* @notice Gets the path for a leaf or extension node.
* @param _node Node to get a path for.
* @return Node path, converted to an array of nibbles.
* @return _path Node path, converted to an array of nibbles.
*/
function _getNodePath(
TrieNode memory _node
......@@ -630,17 +608,17 @@ library Lib_MerkleTrie {
private
view
returns (
bytes memory
bytes memory _path
)
{
return Lib_BytesUtils.toNibbles(Lib_RLPReader.toBytes(_node.decoded[0]));
return Lib_BytesUtils.toNibbles(Lib_RLPReader.readBytes(_node.decoded[0]));
}
/**
* @notice Gets the key for a leaf or extension node. Keys are essentially
* just paths without any prefix.
* @param _node Node to get a key for.
* @return Node key, converted to an array of nibbles.
* @return _key Node key, converted to an array of nibbles.
*/
function _getNodeKey(
TrieNode memory _node
......@@ -648,7 +626,7 @@ library Lib_MerkleTrie {
private
view
returns (
bytes memory
bytes memory _key
)
{
return _removeHexPrefix(_getNodePath(_node));
......@@ -657,7 +635,7 @@ library Lib_MerkleTrie {
/**
* @notice Gets the path for a node.
* @param _node Node to get a value for.
* @return Node value, as hex bytes.
* @return _value Node value, as hex bytes.
*/
function _getNodeValue(
TrieNode memory _node
......@@ -665,17 +643,17 @@ library Lib_MerkleTrie {
private
view
returns (
bytes memory
bytes memory _value
)
{
return Lib_RLPReader.toBytes(_node.decoded[_node.decoded.length - 1]);
return Lib_RLPReader.readBytes(_node.decoded[_node.decoded.length - 1]);
}
/**
* @notice Computes the node hash for an encoded node. Nodes < 32 bytes
* are not hashed, all others are keccak256 hashed.
* @param _encoded Encoded node to hash.
* @return Hash of the encoded node. Simply the input if < 32 bytes.
* @return _hash Hash of the encoded node. Simply the input if < 32 bytes.
*/
function _getNodeHash(
bytes memory _encoded
......@@ -683,7 +661,7 @@ library Lib_MerkleTrie {
private
pure
returns (
bytes memory
bytes memory _hash
)
{
if (_encoded.length < 32) {
......@@ -696,7 +674,7 @@ library Lib_MerkleTrie {
/**
* @notice Determines the type for a given node.
* @param _node Node to determine a type for.
* @return Type of the node; BranchNode/ExtensionNode/LeafNode.
* @return _type Type of the node; BranchNode/ExtensionNode/LeafNode.
*/
function _getNodeType(
TrieNode memory _node
......@@ -704,7 +682,7 @@ library Lib_MerkleTrie {
private
view
returns (
NodeType
NodeType _type
)
{
if (_node.decoded.length == BRANCH_NODE_LENGTH) {
......@@ -728,7 +706,7 @@ library Lib_MerkleTrie {
* nibble arrays.
* @param _a First nibble array.
* @param _b Second nibble array.
* @return Number of shared nibbles.
* @return _shared Number of shared nibbles.
*/
function _getSharedNibbleLength(
bytes memory _a,
......@@ -737,7 +715,7 @@ library Lib_MerkleTrie {
private
view
returns (
uint256
uint256 _shared
)
{
uint256 i = 0;
......@@ -750,7 +728,7 @@ library Lib_MerkleTrie {
/**
* @notice Utility; converts an RLP-encoded node into our nice struct.
* @param _raw RLP-encoded node to convert.
* @return Node as a TrieNode struct.
* @return _node Node as a TrieNode struct.
*/
function _makeNode(
bytes[] memory _raw
......@@ -758,21 +736,21 @@ library Lib_MerkleTrie {
private
view
returns (
TrieNode memory
TrieNode memory _node
)
{
bytes memory encoded = Lib_RLPWriter.encodeList(_raw);
bytes memory encoded = Lib_RLPWriter.writeList(_raw);
return TrieNode({
encoded: encoded,
decoded: Lib_RLPReader.toList(Lib_RLPReader.toRlpItem(encoded))
decoded: Lib_RLPReader.readList(encoded)
});
}
/**
* @notice Utility; converts an RLP-decoded node into our nice struct.
* @param _items RLP-decoded node to convert.
* @return Node as a TrieNode struct.
* @return _node Node as a TrieNode struct.
*/
function _makeNode(
Lib_RLPReader.RLPItem[] memory _items
......@@ -780,12 +758,12 @@ library Lib_MerkleTrie {
private
view
returns (
TrieNode memory
TrieNode memory _node
)
{
bytes[] memory raw = new bytes[](_items.length);
for (uint256 i = 0; i < _items.length; i++) {
raw[i] = Lib_RLPReader.toRlpBytes(_items[i]);
raw[i] = Lib_RLPReader.readRawBytes(_items[i]);
}
return _makeNode(raw);
}
......@@ -794,7 +772,7 @@ library Lib_MerkleTrie {
* @notice Creates a new extension node.
* @param _key Key for the extension node, unprefixed.
* @param _value Value for the extension node.
* @return New extension node with the given k/v pair.
* @return _node New extension node with the given k/v pair.
*/
function _makeExtensionNode(
bytes memory _key,
......@@ -803,13 +781,13 @@ library Lib_MerkleTrie {
private
view
returns (
TrieNode memory
TrieNode memory _node
)
{
bytes[] memory raw = new bytes[](2);
bytes memory key = _addHexPrefix(_key, false);
raw[0] = Lib_RLPWriter.encodeBytes(Lib_BytesUtils.fromNibbles(key));
raw[1] = Lib_RLPWriter.encodeBytes(_value);
raw[0] = Lib_RLPWriter.writeBytes(Lib_BytesUtils.fromNibbles(key));
raw[1] = Lib_RLPWriter.writeBytes(_value);
return _makeNode(raw);
}
......@@ -820,7 +798,7 @@ library Lib_MerkleTrie {
* more gas efficient to keep them separate and duplicate the logic.
* @param _key Key for the leaf node, unprefixed.
* @param _value Value for the leaf node.
* @return New leaf node with the given k/v pair.
* @return _node New leaf node with the given k/v pair.
*/
function _makeLeafNode(
bytes memory _key,
......@@ -829,25 +807,25 @@ library Lib_MerkleTrie {
private
view
returns (
TrieNode memory
TrieNode memory _node
)
{
bytes[] memory raw = new bytes[](2);
bytes memory key = _addHexPrefix(_key, true);
raw[0] = Lib_RLPWriter.encodeBytes(Lib_BytesUtils.fromNibbles(key));
raw[1] = Lib_RLPWriter.encodeBytes(_value);
raw[0] = Lib_RLPWriter.writeBytes(Lib_BytesUtils.fromNibbles(key));
raw[1] = Lib_RLPWriter.writeBytes(_value);
return _makeNode(raw);
}
/**
* @notice Creates an empty branch node.
* @return Empty branch node as a TrieNode stuct.
* @return _node Empty branch node as a TrieNode stuct.
*/
function _makeEmptyBranchNode()
private
view
returns (
TrieNode memory
TrieNode memory _node
)
{
bytes[] memory raw = new bytes[](BRANCH_NODE_LENGTH);
......@@ -861,7 +839,7 @@ library Lib_MerkleTrie {
* @notice Modifies the value slot for a given branch.
* @param _branch Branch node to modify.
* @param _value Value to insert into the branch.
* @return Modified branch node.
* @return _updatedNode Modified branch node.
*/
function _editBranchValue(
TrieNode memory _branch,
......@@ -870,11 +848,11 @@ library Lib_MerkleTrie {
private
view
returns (
TrieNode memory
TrieNode memory _updatedNode
)
{
bytes memory encoded = Lib_RLPWriter.encodeBytes(_value);
_branch.decoded[_branch.decoded.length - 1] = Lib_RLPReader.toRlpItem(encoded);
bytes memory encoded = Lib_RLPWriter.writeBytes(_value);
_branch.decoded[_branch.decoded.length - 1] = Lib_RLPReader.toRLPItem(encoded);
return _makeNode(_branch.decoded);
}
......@@ -883,7 +861,7 @@ library Lib_MerkleTrie {
* @param _branch Branch node to modify.
* @param _index Slot index to modify.
* @param _value Value to insert into the slot.
* @return Modified branch node.
* @return _updatedNode Modified branch node.
*/
function _editBranchIndex(
TrieNode memory _branch,
......@@ -893,11 +871,11 @@ library Lib_MerkleTrie {
private
view
returns (
TrieNode memory
TrieNode memory _updatedNode
)
{
bytes memory encoded = _value.length < 32 ? _value : Lib_RLPWriter.encodeBytes(_value);
_branch.decoded[_index] = Lib_RLPReader.toRlpItem(encoded);
bytes memory encoded = _value.length < 32 ? _value : Lib_RLPWriter.writeBytes(_value);
_branch.decoded[_index] = Lib_RLPReader.toRLPItem(encoded);
return _makeNode(_branch.decoded);
}
......@@ -905,7 +883,7 @@ library Lib_MerkleTrie {
* @notice Utility; adds a prefix to a key.
* @param _key Key to prefix.
* @param _isLeaf Whether or not the key belongs to a leaf.
* @return Prefixed key.
* @return _prefixedKey Prefixed key.
*/
function _addHexPrefix(
bytes memory _key,
......@@ -914,7 +892,7 @@ library Lib_MerkleTrie {
private
view
returns (
bytes memory
bytes memory _prefixedKey
)
{
uint8 prefix = _isLeaf ? uint8(0x02) : uint8(0x00);
......@@ -927,7 +905,7 @@ library Lib_MerkleTrie {
/**
* @notice Utility; removes a prefix from a path.
* @param _path Path to remove the prefix from.
* @return Unprefixed key.
* @return _unprefixedKey Unprefixed key.
*/
function _removeHexPrefix(
bytes memory _path
......@@ -935,7 +913,7 @@ library Lib_MerkleTrie {
private
view
returns (
bytes memory
bytes memory _unprefixedKey
)
{
if (uint8(_path[0]) % 2 == 0) {
......@@ -953,7 +931,7 @@ library Lib_MerkleTrie {
* @param _aLength Length of the first array.
* @param _b Second array to join.
* @param _bLength Length of the second array.
* @return Combined node array.
* @return _joined Combined node array.
*/
function _joinNodeArrays(
TrieNode[] memory _a,
......@@ -964,7 +942,7 @@ library Lib_MerkleTrie {
private
pure
returns (
TrieNode[] memory
TrieNode[] memory _joined
)
{
TrieNode[] memory ret = new TrieNode[](_aLength + _bLength);
......
......@@ -24,7 +24,7 @@ library Lib_SecureMerkleTrie {
* of a list of RLP-encoded nodes that make a path down to the target node.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @return `true` if the k/v pair exists in the trie, `false` otherwise.
* @return _verified `true` if the k/v pair exists in the trie, `false` otherwise.
*/
function verifyInclusionProof(
bytes memory _key,
......@@ -35,7 +35,7 @@ library Lib_SecureMerkleTrie {
internal
view
returns (
bool
bool _verified
)
{
bytes memory key = _getSecureKey(_key);
......@@ -43,31 +43,28 @@ library Lib_SecureMerkleTrie {
}
/**
* @notice Verifies a proof that a given key/value pair is *not* present in
* @notice Verifies a proof that a given key is *not* present in
* the Merkle trie.
* @param _key Key of the node to search for, as a hex string.
* @param _value Value of the node to search for, as a hex string.
* @param _proof Merkle trie inclusion proof for the node *nearest* the
* target node. We effectively need to show that either the key exists and
* its value differs, or the key does not exist at all.
* target node.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @return `true` if the k/v pair is absent in the trie, `false` otherwise.
* @return _verified `true` if the key is not present in the trie, `false` otherwise.
*/
function verifyExclusionProof(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root
)
internal
view
returns (
bool
bool _verified
)
{
bytes memory key = _getSecureKey(_key);
return Lib_MerkleTrie.verifyExclusionProof(key, _value, _proof, _root);
return Lib_MerkleTrie.verifyExclusionProof(key, _proof, _root);
}
/**
......@@ -79,7 +76,7 @@ library Lib_SecureMerkleTrie {
* Otherwise, we need to modify the trie to handle the new k/v pair.
* @param _root Known root of the Merkle trie. Used to verify that the
* included proof is correctly constructed.
* @return Root hash of the newly constructed trie.
* @return _updatedRoot Root hash of the newly constructed trie.
*/
function update(
bytes memory _key,
......@@ -90,7 +87,7 @@ library Lib_SecureMerkleTrie {
internal
view
returns (
bytes32
bytes32 _updatedRoot
)
{
bytes memory key = _getSecureKey(_key);
......@@ -102,7 +99,8 @@ library Lib_SecureMerkleTrie {
* @param _key Key to search for, as hex bytes.
* @param _proof Merkle trie inclusion proof for the key.
* @param _root Known root of the Merkle trie.
* @return Whether the node exists, value associated with the key if so.
* @return _exists Whether or not the key exists.
* @return _value Value of the key if it exists.
*/
function get(
bytes memory _key,
......@@ -112,8 +110,8 @@ library Lib_SecureMerkleTrie {
internal
view
returns (
bool,
bytes memory
bool _exists,
bytes memory _value
)
{
bytes memory key = _getSecureKey(_key);
......@@ -124,7 +122,7 @@ library Lib_SecureMerkleTrie {
* Computes the root hash for a trie with a single node.
* @param _key Key for the single node.
* @param _value Value for the single node.
* @return Hash of the trie.
* @return _updatedRoot Hash of the trie.
*/
function getSingleNodeRootHash(
bytes memory _key,
......@@ -133,7 +131,7 @@ library Lib_SecureMerkleTrie {
internal
view
returns (
bytes32
bytes32 _updatedRoot
)
{
bytes memory key = _getSecureKey(_key);
......@@ -145,13 +143,18 @@ library Lib_SecureMerkleTrie {
* Private Functions *
*********************/
/**
* Computes the secure counterpart to a key.
* @param _key Key to get a secure key from.
* @return _secureKey Secure version of the key.
*/
function _getSecureKey(
bytes memory _key
)
private
pure
returns (
bytes memory
bytes memory _secureKey
)
{
return abi.encodePacked(keccak256(_key));
......
......@@ -35,15 +35,18 @@ library Lib_ECDSAUtils {
)
{
bytes32 messageHash;
uint8 v;
if (_isEthSignedMessage) {
messageHash = getEthSignedMessageHash(_message);
v = _v;
} else {
messageHash = getNativeMessageHash(_message);
v = (_v - uint8(_chainId) * 2) - 8;
}
return ecrecover(
messageHash,
(_v - uint8(_chainId) * 2) - 8,
v,
_r,
_s
);
......
......@@ -151,10 +151,10 @@ library Lib_EthUtils {
)
{
bytes[] memory encoded = new bytes[](2);
encoded[0] = Lib_RLPWriter.encodeAddress(_creator);
encoded[1] = Lib_RLPWriter.encodeUint(_nonce);
encoded[0] = Lib_RLPWriter.writeAddress(_creator);
encoded[1] = Lib_RLPWriter.writeUint(_nonce);
bytes memory encodedList = Lib_RLPWriter.encodeList(encoded);
bytes memory encodedList = Lib_RLPWriter.writeList(encoded);
return getAddressFromHash(keccak256(encodedList));
}
......
......@@ -15,6 +15,11 @@ library Lib_MerkleUtils {
bytes32 _root
)
{
require(
_hashes.length > 0,
"Must provide at least one leaf hash."
);
if (_hashes.length == 1) {
return _hashes[0];
}
......
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
/**
* @title Lib_SafeExecutionManagerWrapper
*/
library Lib_SafeExecutionManagerWrapper {
/**********************
* Internal Functions *
**********************/
/**
* Makes an ovmCALL and performs all the necessary safety checks.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @param _gasLimit Gas limit for the call.
* @param _target Address to call.
* @param _calldata Data to send to the call.
* @return _success Whether or not the call reverted.
* @return _returndata Data returned by the call.
*/
function safeCALL(
address _ovmExecutionManager,
uint256 _gasLimit,
address _target,
bytes memory _calldata
)
internal
returns (
bool _success,
bytes memory _returndata
)
{
bytes memory returndata = _safeExecutionManagerInteraction(
_ovmExecutionManager,
abi.encodeWithSignature(
"ovmCALL(uint256,address,bytes)",
_gasLimit,
_target,
_calldata
)
);
return abi.decode(returndata, (bool, bytes));
}
/**
* Performs an ovmCREATE and the necessary safety checks.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @param _gasLimit Gas limit for the creation.
* @param _bytecode Code for the new contract.
* @return _contract Address of the created contract.
*/
function safeCREATE(
address _ovmExecutionManager,
uint256 _gasLimit,
bytes memory _bytecode
)
internal
returns (
address _contract
)
{
bytes memory returndata = _safeExecutionManagerInteraction(
_ovmExecutionManager,
_gasLimit,
abi.encodeWithSignature(
"ovmCREATE(bytes)",
_bytecode
)
);
return abi.decode(returndata, (address));
}
/**
* Performs a safe ovmCHAINID call.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @return _CHAINID Result of calling ovmCHAINID.
*/
function safeCHAINID(
address _ovmExecutionManager
)
internal
returns (
uint256 _CHAINID
)
{
bytes memory returndata = _safeExecutionManagerInteraction(
_ovmExecutionManager,
abi.encodeWithSignature(
"ovmCHAINID()"
)
);
return abi.decode(returndata, (uint256));
}
/**
* Performs a safe ovmADDRESS call.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @return _ADDRESS Result of calling ovmADDRESS.
*/
function safeADDRESS(
address _ovmExecutionManager
)
internal
returns (
address _ADDRESS
)
{
bytes memory returndata = _safeExecutionManagerInteraction(
_ovmExecutionManager,
abi.encodeWithSignature(
"ovmADDRESS()"
)
);
return abi.decode(returndata, (address));
}
/**
* Performs a safe ovmGETNONCE call.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @return _nonce Result of calling ovmGETNONCE.
*/
function safeGETNONCE(
address _ovmExecutionManager
)
internal
returns (
uint256 _nonce
)
{
bytes memory returndata = _safeExecutionManagerInteraction(
_ovmExecutionManager,
abi.encodeWithSignature(
"ovmGETNONCE()"
)
);
return abi.decode(returndata, (uint256));
}
/**
* Performs a safe ovmSETNONCE call.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @param _nonce New account nonce.
*/
function safeSETNONCE(
address _ovmExecutionManager,
uint256 _nonce
)
internal
{
_safeExecutionManagerInteraction(
_ovmExecutionManager,
abi.encodeWithSignature(
"ovmSETNONCE(uint256)",
_nonce
)
);
}
/*********************
* Private Functions *
*********************/
/**
* Performs an ovm interaction and the necessary safety checks.
* @param _ovmExecutionManager Address of the OVM_ExecutionManager.
* @param _gasLimit Gas limit for the interaction.
* @param _calldata Data to send to the OVM_ExecutionManager (encoded with sighash).
* @return _returndata Data sent back by the OVM_ExecutionManager.
*/
function _safeExecutionManagerInteraction(
address _ovmExecutionManager,
uint256 _gasLimit,
bytes memory _calldata
)
private
returns (
bytes memory _returndata
)
{
(
bool success,
bytes memory returndata
) = _ovmExecutionManager.call{gas: _gasLimit}(_calldata);
if (success == false) {
assembly {
revert(add(returndata, 0x20), mload(returndata))
}
} else if (returndata.length == 1) {
assembly {
return(0, 1)
}
} else {
return returndata;
}
}
function _safeExecutionManagerInteraction(
address _ovmExecutionManager,
bytes memory _calldata
)
private
returns (
bytes memory _returndata
)
{
return _safeExecutionManagerInteraction(
_ovmExecutionManager,
gasleft(),
_calldata
);
}
}
......@@ -2,18 +2,38 @@
pragma solidity ^0.7.0;
contract Helper_SimpleProxy {
address private owner;
address private target;
constructor(
address _target
) {
target = _target;
constructor() {
owner = msg.sender;
}
fallback()
external
{
(bool success, bytes memory returndata) = target.call(msg.data);
makeExternalCall(target, msg.data);
}
function setTarget(
address _target
)
public
{
if (msg.sender == owner) {
target = _target;
} else {
makeExternalCall(target, msg.data);
}
}
function makeExternalCall(
address _target,
bytes memory _calldata
)
private
{
(bool success, bytes memory returndata) = _target.call(_calldata);
if (success) {
assembly {
......
......@@ -8,7 +8,7 @@ import { Lib_OVMCodec } from "../../optimistic-ethereum/libraries/codec/Lib_OVMC
/**
* @title TestLib_OVMCodec
*/
library TestLib_OVMCodec {
contract TestLib_OVMCodec {
function decodeEOATransaction(
bytes memory _transaction
......
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_RLPReader } from "../../optimistic-ethereum/libraries/rlp/Lib_RLPReader.sol";
/**
* @title TestLib_RLPReader
*/
contract TestLib_RLPReader {
function readList(
bytes memory _in
)
public
view
returns (
bytes[] memory
)
{
Lib_RLPReader.RLPItem[] memory decoded = Lib_RLPReader.readList(_in);
bytes[] memory out = new bytes[](decoded.length);
for (uint256 i = 0; i < out.length; i++) {
out[i] = Lib_RLPReader.readRawBytes(decoded[i]);
}
return out;
}
function readString(
bytes memory _in
)
public
view
returns (
string memory
)
{
return Lib_RLPReader.readString(_in);
}
function readBytes(
bytes memory _in
)
public
view
returns (
bytes memory
)
{
return Lib_RLPReader.readBytes(_in);
}
function readBytes32(
bytes memory _in
)
public
view
returns (
bytes32
)
{
return Lib_RLPReader.readBytes32(_in);
}
function readUint256(
bytes memory _in
)
public
view
returns (
uint256
)
{
return Lib_RLPReader.readUint256(_in);
}
function readBool(
bytes memory _in
)
public
view
returns (
bool
)
{
return Lib_RLPReader.readBool(_in);
}
function readAddress(
bytes memory _in
)
public
view
returns (
address
)
{
return Lib_RLPReader.readAddress(_in);
}
}
......@@ -8,9 +8,9 @@ import { Lib_RLPWriter } from "../../optimistic-ethereum/libraries/rlp/Lib_RLPWr
/**
* @title TestLib_RLPWriter
*/
library TestLib_RLPWriter {
contract TestLib_RLPWriter {
function encodeBytes(
function writeBytes(
bytes memory _in
)
public
......@@ -19,10 +19,10 @@ library TestLib_RLPWriter {
bytes memory _out
)
{
return Lib_RLPWriter.encodeBytes(_in);
return Lib_RLPWriter.writeBytes(_in);
}
function encodeList(
function writeList(
bytes[] memory _in
)
public
......@@ -31,10 +31,10 @@ library TestLib_RLPWriter {
bytes memory _out
)
{
return Lib_RLPWriter.encodeList(_in);
return Lib_RLPWriter.writeList(_in);
}
function encodeString(
function writeString(
string memory _in
)
public
......@@ -43,10 +43,10 @@ library TestLib_RLPWriter {
bytes memory _out
)
{
return Lib_RLPWriter.encodeString(_in);
return Lib_RLPWriter.writeString(_in);
}
function encodeAddress(
function writeAddress(
address _in
)
public
......@@ -55,10 +55,10 @@ library TestLib_RLPWriter {
bytes memory _out
)
{
return Lib_RLPWriter.encodeAddress(_in);
return Lib_RLPWriter.writeAddress(_in);
}
function encodeUint(
function writeUint(
uint _in
)
public
......@@ -67,10 +67,10 @@ library TestLib_RLPWriter {
bytes memory _out
)
{
return Lib_RLPWriter.encodeUint(_in);
return Lib_RLPWriter.writeUint(_in);
}
function encodeInt(
function writeInt(
int _in
)
public
......@@ -79,10 +79,10 @@ library TestLib_RLPWriter {
bytes memory _out
)
{
return Lib_RLPWriter.encodeInt(_in);
return Lib_RLPWriter.writeInt(_in);
}
function encodeBool(
function writeBool(
bool _in
)
public
......@@ -91,6 +91,6 @@ library TestLib_RLPWriter {
bytes memory _out
)
{
return Lib_RLPWriter.encodeBool(_in);
return Lib_RLPWriter.writeBool(_in);
}
}
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_EthMerkleTrie } from "../../optimistic-ethereum/libraries/trie/Lib_EthMerkleTrie.sol";
import { Lib_OVMCodec } from "../../optimistic-ethereum/libraries/codec/Lib_OVMCodec.sol";
/**
* @title TestLib_EthMerkleTrie
*/
library TestLib_EthMerkleTrie {
function proveAccountStorageSlotValue(
address _address,
bytes32 _key,
bytes32 _value,
bytes memory _stateTrieWitness,
bytes memory _storageTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bool)
{
return Lib_EthMerkleTrie.proveAccountStorageSlotValue(
_address,
_key,
_value,
_stateTrieWitness,
_storageTrieWitness,
_stateTrieRoot
);
}
function updateAccountStorageSlotValue(
address _address,
bytes32 _key,
bytes32 _value,
bytes memory _stateTrieWitness,
bytes memory _storageTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bytes32)
{
return Lib_EthMerkleTrie.updateAccountStorageSlotValue(
_address,
_key,
_value,
_stateTrieWitness,
_storageTrieWitness,
_stateTrieRoot
);
}
function proveAccountState(
address _address,
Lib_OVMCodec.EVMAccount memory _accountState,
Lib_OVMCodec.ProofMatrix memory _proofMatrix,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bool)
{
return Lib_EthMerkleTrie.proveAccountState(
_address,
_accountState,
_proofMatrix,
_stateTrieWitness,
_stateTrieRoot
);
}
function proveAccountState(
address _address,
Lib_OVMCodec.EVMAccount memory _accountState,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bool)
{
return Lib_EthMerkleTrie.proveAccountState(
_address,
_accountState,
_stateTrieWitness,
_stateTrieRoot
);
}
function proveAccountState(
address _address,
Lib_OVMCodec.Account memory _accountState,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bool)
{
return Lib_EthMerkleTrie.proveAccountState(
_address,
_accountState,
_stateTrieWitness,
_stateTrieRoot
);
}
function proveAccountNonce(
address _address,
uint256 _nonce,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bool)
{
return Lib_EthMerkleTrie.proveAccountNonce(
_address,
_nonce,
_stateTrieWitness,
_stateTrieRoot
);
}
function proveAccountBalance(
address _address,
uint256 _balance,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bool)
{
return Lib_EthMerkleTrie.proveAccountBalance(
_address,
_balance,
_stateTrieWitness,
_stateTrieRoot
);
}
function proveAccountStorageRoot(
address _address,
bytes32 _storageRoot,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bool)
{
return Lib_EthMerkleTrie.proveAccountStorageRoot(
_address,
_storageRoot,
_stateTrieWitness,
_stateTrieRoot
);
}
function proveAccountCodeHash(
address _address,
bytes32 _codeHash,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bool)
{
return Lib_EthMerkleTrie.proveAccountCodeHash(
_address,
_codeHash,
_stateTrieWitness,
_stateTrieRoot
);
}
function updateAccountState(
address _address,
Lib_OVMCodec.EVMAccount memory _accountState,
Lib_OVMCodec.ProofMatrix memory _proofMatrix,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bytes32)
{
return Lib_EthMerkleTrie.updateAccountState(
_address,
_accountState,
_proofMatrix,
_stateTrieWitness,
_stateTrieRoot
);
}
function updateAccountState(
address _address,
Lib_OVMCodec.EVMAccount memory _accountState,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bytes32)
{
return Lib_EthMerkleTrie.updateAccountState(
_address,
_accountState,
_stateTrieWitness,
_stateTrieRoot
);
}
function updateAccountState(
address _address,
Lib_OVMCodec.Account memory _accountState,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bytes32)
{
return Lib_EthMerkleTrie.updateAccountState(
_address,
_accountState,
_stateTrieWitness,
_stateTrieRoot
);
}
function updateAccountNonce(
address _address,
uint256 _nonce,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bytes32)
{
return Lib_EthMerkleTrie.updateAccountNonce(
_address,
_nonce,
_stateTrieWitness,
_stateTrieRoot
);
}
function updateAccountBalance(
address _address,
uint256 _balance,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bytes32)
{
return Lib_EthMerkleTrie.updateAccountBalance(
_address,
_balance,
_stateTrieWitness,
_stateTrieRoot
);
}
function updateAccountStorageRoot(
address _address,
bytes32 _storageRoot,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bytes32)
{
return Lib_EthMerkleTrie.updateAccountStorageRoot(
_address,
_storageRoot,
_stateTrieWitness,
_stateTrieRoot
);
}
function updateAccountCodeHash(
address _address,
bytes32 _codeHash,
bytes memory _stateTrieWitness,
bytes32 _stateTrieRoot
)
public
view
returns (bytes32)
{
return Lib_EthMerkleTrie.updateAccountCodeHash(
_address,
_codeHash,
_stateTrieWitness,
_stateTrieRoot
);
}
}
......@@ -7,7 +7,7 @@ import { Lib_MerkleTrie } from "../../optimistic-ethereum/libraries/trie/Lib_Mer
/**
* @title TestLib_MerkleTrie
*/
library TestLib_MerkleTrie {
contract TestLib_MerkleTrie {
function verifyInclusionProof(
bytes memory _key,
......@@ -31,7 +31,6 @@ library TestLib_MerkleTrie {
function verifyExclusionProof(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root
)
......@@ -43,7 +42,6 @@ library TestLib_MerkleTrie {
{
return Lib_MerkleTrie.verifyExclusionProof(
_key,
_value,
_proof,
_root
);
......
......@@ -8,7 +8,7 @@ import { Lib_SecureMerkleTrie } from "../../optimistic-ethereum/libraries/trie/L
/**
* @title TestLib_SecureMerkleTrie
*/
library TestLib_SecureMerkleTrie {
contract TestLib_SecureMerkleTrie {
function verifyInclusionProof(
bytes memory _key,
......@@ -32,7 +32,6 @@ library TestLib_SecureMerkleTrie {
function verifyExclusionProof(
bytes memory _key,
bytes memory _value,
bytes memory _proof,
bytes32 _root
)
......@@ -44,7 +43,6 @@ library TestLib_SecureMerkleTrie {
{
return Lib_SecureMerkleTrie.verifyExclusionProof(
_key,
_value,
_proof,
_root
);
......
......@@ -7,7 +7,7 @@ import { Lib_Bytes32Utils } from "../../optimistic-ethereum/libraries/utils/Lib_
/**
* @title TestLib_Byte32Utils
*/
library TestLib_Bytes32Utils {
contract TestLib_Bytes32Utils {
function toBool(
bytes32 _in
......
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.7.0;
pragma experimental ABIEncoderV2;
/* Library Imports */
import { Lib_BytesUtils } from "../../optimistic-ethereum/libraries/utils/Lib_BytesUtils.sol";
......@@ -7,7 +8,7 @@ import { Lib_BytesUtils } from "../../optimistic-ethereum/libraries/utils/Lib_By
/**
* @title TestLib_BytesUtils
*/
library TestLib_BytesUtils {
contract TestLib_BytesUtils {
function concat(
bytes memory _preBytes,
......@@ -39,24 +40,10 @@ library TestLib_BytesUtils {
);
}
function slice(
bytes memory _bytes,
uint256 _start
)
public
pure
returns (bytes memory)
{
return Lib_BytesUtils.slice(
_bytes,
_start
);
}
function toBytes32(
bytes memory _bytes
)
internal
public
pure
returns (bytes32)
{
......
......@@ -7,7 +7,7 @@ import { Lib_ECDSAUtils } from "../../optimistic-ethereum/libraries/utils/Lib_EC
/**
* @title TestLib_ECDSAUtils
*/
library TestLib_ECDSAUtils {
contract TestLib_ECDSAUtils {
function recover(
bytes memory _message,
......
......@@ -8,7 +8,7 @@ import { Lib_EthUtils } from "../../optimistic-ethereum/libraries/utils/Lib_EthU
/**
* @title TestLib_EthUtils
*/
library TestLib_EthUtils {
contract TestLib_EthUtils {
function getCode(
address _address,
......
......@@ -8,7 +8,7 @@ import { Lib_MerkleUtils } from "../../optimistic-ethereum/libraries/utils/Lib_M
/**
* @title TestLib_MerkleUtils
*/
library TestLib_MerkleUtils {
contract TestLib_MerkleUtils {
function getMerkleRoot(
bytes32[] memory _hashes
......
......@@ -7,15 +7,18 @@
"build": "yarn run build:contracts && yarn run build:typescript && yarn run build:copy",
"build:typescript": "tsc -p .",
"build:contracts": "buidler compile",
"build:dump": "ts-node \"bin/take-dump.ts\"",
"build:copy": "copyfiles -u 2 \"contracts/optimistic-ethereum/**/*.sol\" \"build/contracts\"",
"test": "yarn run test:contracts",
"test:contracts": "buidler test \"test/contracts/OVM/chain/OVM_StateCommitmentChain.spec.ts\" --show-stack-traces",
"lint": "tslint --format stylish --project .",
"fix": "prettier --config prettier-config.json --write \"buidler.config.ts\" \"{src,test}/**/*.ts\"",
"test:contracts": "buidler test --show-stack-traces",
"lint": "yarn run lint:typescript",
"lint:typescript": "tslint --format stylish --project .",
"lint:fix": "yarn run lint:fix:typescript",
"lint:fix:typescript": "prettier --config prettier-config.json --write \"buidler.config.ts\" \"{src,test}/**/*.ts\"",
"clean": "rm -rf ./artifacts ./build ./cache"
},
"devDependencies": {
"@eth-optimism/smock": "^0.1.0",
"@eth-optimism/smock": "^0.0.2",
"@nomiclabs/buidler": "^1.4.4",
"@nomiclabs/buidler-ethers": "^2.0.0",
"@nomiclabs/buidler-waffle": "^2.0.0",
......@@ -30,9 +33,15 @@
"ethereum-waffle": "3.0.0",
"ethers": "5.0.0",
"fs-extra": "^9.0.1",
"ganache-core": "^2.12.1",
"lodash": "^4.17.20",
"merkle-patricia-tree": "git+https://github.com/kfichter/merkle-patricia-tree",
"mkdirp": "^1.0.4",
"mocha": "^8.1.1",
"prettier": "^2.1.2",
"random-bytes-seed": "^1.0.3",
"rlp": "^2.2.6",
"seedrandom": "^3.0.5",
"ts-node": "^9.0.0",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
......
import * as path from 'path'
import { ethers, ContractFactory, Signer } from 'ethers'
import { Interface } from 'ethers/lib/utils'
export const getContractDefinition = (name: string): any => {
return require(path.join(__dirname, '../artifacts', `${name}.json`))
}
export const getContractInterface = (name: string): Interface => {
const definition = getContractDefinition(name)
return new ethers.utils.Interface(definition.abi)
}
export const getContractFactory = (
name: string,
signer?: Signer
): ContractFactory => {
const definition = getContractDefinition(name)
const contractInterface = getContractInterface(name)
return new ContractFactory(contractInterface, definition.bytecode, signer)
}
/* External Imports */
import { Signer, ContractFactory, Contract } from 'ethers'
/* Internal Imports */
import { getContractFactory } from '../contract-defs'
export interface RollupDeployConfig {
deploymentSigner: Signer
ovmGasMeteringConfig: {
minTransactionGasLimit: number
maxTransactionGasLimit: number
maxGasPerQueuePerEpoch: number
secondsPerEpoch: number
}
transactionChainConfig: {
sequencer: string | Signer
forceInclusionPeriodSeconds: number
}
whitelistConfig: {
owner: string | Signer
allowArbitraryContractDeployment: boolean
}
}
export interface ContractDeployParameters {
factory: ContractFactory
params?: any[]
afterDeploy?: (contracts?: { [name: string]: Contract }) => Promise<void>
}
export interface ContractDeployConfig {
[name: string]: ContractDeployParameters
}
export const makeContractDeployConfig = async (
config: RollupDeployConfig,
AddressManager: Contract
): Promise<ContractDeployConfig> => {
return {
OVM_L1CrossDomainMessenger: {
factory: getContractFactory('OVM_L1CrossDomainMessenger'),
params: [AddressManager.address],
},
OVM_L2CrossDomainMessenger: {
factory: getContractFactory('OVM_L2CrossDomainMessenger'),
params: [AddressManager.address],
},
OVM_CanonicalTransactionChain: {
factory: getContractFactory('OVM_CanonicalTransactionChain'),
params: [
AddressManager.address,
config.transactionChainConfig.forceInclusionPeriodSeconds,
],
afterDeploy: async (): Promise<void> => {
const sequencer = config.transactionChainConfig.sequencer
const sequencerAddress =
typeof sequencer === 'string'
? sequencer
: await sequencer.getAddress()
await AddressManager.setAddress('Sequencer', sequencerAddress)
},
},
OVM_StateCommitmentChain: {
factory: getContractFactory('OVM_StateCommitmentChain'),
params: [AddressManager.address],
},
OVM_ExecutionManager: {
factory: getContractFactory('OVM_ExecutionManager'),
params: [AddressManager.address],
},
OVM_StateManager: {
factory: getContractFactory('OVM_StateManager'),
params: [await config.deploymentSigner.getAddress()],
afterDeploy: async (contracts): Promise<void> => {
await contracts.OVM_StateManager.setExecutionManager(
contracts.OVM_ExecutionManager.address
)
},
},
OVM_StateManagerFactory: {
factory: getContractFactory('OVM_StateManagerFactory'),
},
OVM_L1ToL2TransactionQueue: {
factory: getContractFactory('OVM_L1ToL2TransactionQueue'),
params: [AddressManager.address],
},
OVM_FraudVerifier: {
factory: getContractFactory('OVM_FraudVerifier'),
params: [AddressManager.address],
},
OVM_StateTransitionerFactory: {
factory: getContractFactory('OVM_StateTransitionerFactory'),
},
}
}
/* External Imports */
import { Signer, Contract, ContractFactory } from 'ethers'
/* Internal Imports */
import { RollupDeployConfig, makeContractDeployConfig } from './config'
import { getContractFactory } from '../contract-defs'
export interface DeployResult {
AddressManager: Contract
failedDeployments: string[]
contracts: {
[name: string]: Contract
}
}
export const deploy = async (
config: RollupDeployConfig
): Promise<DeployResult> => {
const Factory__SimpleProxy: ContractFactory = getContractFactory(
'Helper_SimpleProxy',
config.deploymentSigner
)
const AddressManager: Contract = await getContractFactory(
'Lib_AddressManager',
config.deploymentSigner
).deploy()
const contractDeployConfig = await makeContractDeployConfig(
config,
AddressManager
)
const failedDeployments: string[] = []
const contracts: {
[name: string]: Contract
} = {}
for (const [name, contractDeployParameters] of Object.entries(
contractDeployConfig
)) {
const SimpleProxy = await Factory__SimpleProxy.deploy()
await AddressManager.setAddress(name, SimpleProxy.address)
try {
contracts[name] = await contractDeployParameters.factory
.connect(config.deploymentSigner)
.deploy(...contractDeployParameters.params)
await SimpleProxy.setTarget(contracts[name].address)
} catch (err) {
failedDeployments.push(name)
}
}
for (const contractDeployParameters of Object.values(contractDeployConfig)) {
if (contractDeployParameters.afterDeploy) {
await contractDeployParameters.afterDeploy(contracts)
}
}
return {
AddressManager,
failedDeployments,
contracts,
}
}
export { RollupDeployConfig } from './config'
export { deploy } from './deploy'
/* External Imports */
import * as path from 'path'
import { ethers } from 'ethers'
import * as Ganache from 'ganache-core'
/* Internal Imports */
import { deploy, RollupDeployConfig } from './contract-deployment'
import { getContractDefinition } from './contract-defs'
import { keccak256 } from 'ethers/lib/utils'
type Accounts = Array<{
originalAddress: string
address: string
code: string
}>
interface StorageDump {
[key: string]: string
}
export interface StateDump {
contracts: {
ovmExecutionManager: string
ovmStateManager: string
}
accounts: {
[address: string]: {
balance: number
nonce: number
code: string
storage: StorageDump
}
}
}
/**
* Finds the addresses of all accounts changed in the state.
* @param cStateManager Instance of the callback-based internal vm StateManager.
* @returns Array of changed addresses.
*/
const getChangedAccounts = async (cStateManager: any): Promise<string[]> => {
return new Promise<string[]>((resolve, reject) => {
const accounts: string[] = []
const stream = cStateManager._trie.createReadStream()
stream.on('data', (val: any) => {
accounts.push(val.key.toString('hex'))
})
stream.on('end', () => {
resolve(accounts)
})
})
}
/**
* Generates a storage dump for a given address.
* @param cStateManager Instance of the callback-based internal vm StateManager.
* @param address Address to generate a state dump for.
*/
const getStorageDump = async (
cStateManager: any,
address: string
): Promise<StorageDump> => {
return new Promise<StorageDump>((resolve, reject) => {
cStateManager._getStorageTrie(address, (err: any, trie: any) => {
if (err) {
reject(err)
}
const storage: StorageDump = {}
const stream = trie.createReadStream()
stream.on('data', (val: any) => {
storage[val.key.toString('hex')] = val.value.toString('hex')
})
stream.on('end', () => {
resolve(storage)
})
})
})
}
/**
* Replaces old addresses found in a storage dump with new ones.
* @param storageDump Storage dump to sanitize.
* @param accounts Set of accounts to sanitize with.
* @returns Sanitized storage dump.
*/
const sanitizeStorageDump = (
storageDump: StorageDump,
accounts: Accounts
): StorageDump => {
for (const [key, value] of Object.entries(storageDump)) {
let parsedKey = key
let parsedValue = value
for (const account of accounts) {
const re = new RegExp(`${account.originalAddress}`, 'g')
parsedValue = parsedValue.replace(re, account.address)
parsedKey = parsedKey.replace(re, account.address)
}
if (parsedKey !== key) {
delete storageDump[key]
}
storageDump[parsedKey] = parsedValue
}
return storageDump
}
export const makeStateDump = async (): Promise<any> => {
const ganache = (Ganache as any).provider({
gasLimit: 100_000_000,
allowUnlimitedContractSize: true,
accounts: [
{
secretKey:
'0x29f3edee0ad3abf8e2699402e0e28cd6492c9be7eaab00d732a791c33552f797',
balance: 10000000000000000000000000000000000,
},
],
})
const provider = new ethers.providers.Web3Provider(ganache)
const signer = provider.getSigner(0)
const config: RollupDeployConfig = {
deploymentSigner: signer,
ovmGasMeteringConfig: {
minTransactionGasLimit: 0,
maxTransactionGasLimit: 1_000_000_000,
maxGasPerQueuePerEpoch: 1_000_000_000_000,
secondsPerEpoch: 600,
},
transactionChainConfig: {
sequencer: signer,
forceInclusionPeriodSeconds: 600,
},
whitelistConfig: {
owner: signer,
allowArbitraryContractDeployment: true,
},
}
const deploymentResult = await deploy(config)
const pStateManager = ganache.engine.manager.state.blockchain.vm.pStateManager
const cStateManager = pStateManager._wrapped
const ovmExecutionManagerOriginalAddress = deploymentResult.contracts.OVM_ExecutionManager.address
.slice(2)
.toLowerCase()
const ovmExecutionManagerAddress = 'c0dec0dec0dec0dec0dec0dec0dec0dec0de0000'
const ovmStateManagerOriginalAddress = deploymentResult.contracts.OVM_StateManager.address
.slice(2)
.toLowerCase()
const ovmStateManagerAddress = 'c0dec0dec0dec0dec0dec0dec0dec0dec0de0001'
const l2ToL1MessagePasserDef = getContractDefinition(
'OVM_L2ToL1MessagePasser'
)
const l2ToL1MessagePasserHash = keccak256(
l2ToL1MessagePasserDef.deployedBytecode
)
const l2ToL1MessagePasserAddress = '4200000000000000000000000000000000000000'
const l1MessageSenderDef = getContractDefinition('OVM_L1MessageSender')
const l1MessageSenderHash = keccak256(l1MessageSenderDef.deployedBytecode)
const l1MessageSenderAddress = '4200000000000000000000000000000000000001'
const changedAccounts = await getChangedAccounts(cStateManager)
let deadAddressIndex = 0
const accounts: Accounts = []
for (const originalAddress of changedAccounts) {
const code = (
await pStateManager.getContractCode(originalAddress)
).toString('hex')
const codeHash = keccak256('0x' + code)
if (code.length === 0) {
continue
}
// Sorry for this one!
let address = originalAddress
if (codeHash === l2ToL1MessagePasserHash) {
address = l2ToL1MessagePasserAddress
} else if (codeHash === l1MessageSenderHash) {
address = l1MessageSenderAddress
} else if (originalAddress === ovmExecutionManagerOriginalAddress) {
address = ovmExecutionManagerAddress
} else if (originalAddress === ovmStateManagerOriginalAddress) {
address = ovmStateManagerAddress
} else {
address = `deaddeaddeaddeaddeaddeaddeaddeaddead${deadAddressIndex
.toString(16)
.padStart(4, '0')}`
deadAddressIndex++
}
accounts.push({
originalAddress,
address,
code,
})
}
const dump: StateDump = {
contracts: {
ovmExecutionManager: '0x' + ovmExecutionManagerAddress,
ovmStateManager: '0x' + ovmStateManagerAddress,
},
accounts: {},
}
for (const account of accounts) {
const storageDump = sanitizeStorageDump(
await getStorageDump(cStateManager, account.originalAddress),
accounts
)
dump.accounts[account.address] = {
balance: 0,
nonce: 0,
code: account.code,
storage: storageDump,
}
}
return dump
}
export const getLatestStateDump = (): StateDump => {
return require(path.join(__dirname, '../dumps', `state-dump.latest.json`))
}
export * from './contract-defs'
export * from './contract-dumps'
export * from './contract-deployment'
yarn run v1.22.5
$ yarn run test:contracts
$ buidler test "test/contracts/libraries/rlp/Lib_RLPReader.spec.ts" --show-stack-traces
All contracts have already been compiled, skipping compilation.
{
"emptystring": {
"in": [
"0x80"
],
"out": [
""
]
},
"bytestring00": {
"in": [
"0x00"
],
"out": [
"\u0000"
]
},
"bytestring01": {
"in": [
"0x01"
],
"out": [
"\u0001"
]
},
"bytestring7F": {
"in": [
"0x7f"
],
"out": [
""
]
},
"shortstring": {
"in": [
"0x83646f67"
],
"out": [
"dog"
]
},
"shortstring2": {
"in": [
"0xb74c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69"
],
"out": [
"Lorem ipsum dolor sit amet, consectetur adipisicing eli"
]
},
"longstring": {
"in": [
"0xb8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974"
],
"out": [
"Lorem ipsum dolor sit amet, consectetur adipisicing elit"
]
},
"longstring2": {
"in": [
"0xb904004c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742e20437572616269747572206d6175726973206d61676e612c20737573636970697420736564207665686963756c61206e6f6e2c20696163756c697320666175636962757320746f72746f722e2050726f696e20737573636970697420756c74726963696573206d616c6573756164612e204475697320746f72746f7220656c69742c2064696374756d2071756973207472697374697175652065752c20756c7472696365732061742072697375732e204d6f72626920612065737420696d70657264696574206d6920756c6c616d636f7270657220616c6971756574207375736369706974206e6563206c6f72656d2e2041656e65616e2071756973206c656f206d6f6c6c69732c2076756c70757461746520656c6974207661726975732c20636f6e73657175617420656e696d2e204e756c6c6120756c74726963657320747572706973206a7573746f2c20657420706f73756572652075726e6120636f6e7365637465747572206e65632e2050726f696e206e6f6e20636f6e76616c6c6973206d657475732e20446f6e65632074656d706f7220697073756d20696e206d617572697320636f6e67756520736f6c6c696369747564696e2e20566573746962756c756d20616e746520697073756d207072696d697320696e206661756369627573206f726369206c756374757320657420756c74726963657320706f737565726520637562696c69612043757261653b2053757370656e646973736520636f6e76616c6c69732073656d2076656c206d617373612066617563696275732c2065676574206c6163696e6961206c616375732074656d706f722e204e756c6c61207175697320756c747269636965732070757275732e2050726f696e20617563746f722072686f6e637573206e69626820636f6e64696d656e74756d206d6f6c6c69732e20416c697175616d20636f6e73657175617420656e696d206174206d65747573206c75637475732c206120656c656966656e6420707572757320656765737461732e20437572616269747572206174206e696268206d657475732e204e616d20626962656e64756d2c206e6571756520617420617563746f72207472697374697175652c206c6f72656d206c696265726f20616c697175657420617263752c206e6f6e20696e74657264756d2074656c6c7573206c65637475732073697420616d65742065726f732e20437261732072686f6e6375732c206d65747573206163206f726e617265206375727375732c20646f6c6f72206a7573746f20756c747269636573206d657475732c20617420756c6c616d636f7270657220766f6c7574706174"
],
"out": [
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat"
]
},
"zero": {
"in": [
"0x80"
],
"out": [
0
]
},
"smallint": {
"in": [
"0x01"
],
"out": [
1
]
},
"smallint2": {
"in": [
"0x10"
],
"out": [
16
]
},
"smallint3": {
"in": [
"0x4f"
],
"out": [
79
]
},
"smallint4": {
"in": [
"0x7f"
],
"out": [
127
]
},
"mediumint1": {
"in": [
"0x8180"
],
"out": [
128
]
},
"mediumint2": {
"in": [
"0x8203e8"
],
"out": [
1000
]
},
"mediumint3": {
"in": [
"0x830186a0"
],
"out": [
100000
]
},
"mediumint4": {
"in": [
"0x8f102030405060708090a0b0c0d0e0f2"
],
"out": [
"#83729609699884896815286331701780722"
]
},
"mediumint5": {
"in": [
"0x9c0100020003000400050006000700080009000a000b000c000d000e01"
],
"out": [
"#105315505618206987246253880190783558935785933862974822347068935681"
]
},
"emptylist": {
"in": [
"0xc0"
],
"out": [
[]
]
},
"stringlist": {
"in": [
"0xcc83646f6783676f6483636174"
],
"out": [
[
"0x83646f67",
"0x83676f64",
"0x83636174"
]
]
},
"multilist": {
"in": [
"0xc6827a77c10401"
],
"out": [
[
"0x827a77",
"0xc104",
"0x01"
]
]
},
"shortListMax1": {
"in": [
"0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
],
"out": [
[
"0x8461736466",
"0x8471776572",
"0x847a786376",
"0x8461736466",
"0x8471776572",
"0x847a786376",
"0x8461736466",
"0x8471776572",
"0x847a786376",
"0x8461736466",
"0x8471776572"
]
]
},
"longList1": {
"in": [
"0xf840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
],
"out": [
[
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376"
]
]
},
"longList2": {
"in": [
"0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
],
"out": [
[
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376"
]
]
},
"listsoflists": {
"in": [
"0xc4c2c0c0c0"
],
"out": [
[
"0xc2c0c0",
"0xc0"
]
]
},
"listsoflists2": {
"in": [
"0xc7c0c1c0c3c0c1c0"
],
"out": [
[
"0xc0",
"0xc1c0",
"0xc3c0c1c0"
]
]
},
"dictTest1": {
"in": [
"0xecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34"
],
"out": [
[
"0xca846b6579318476616c31",
"0xca846b6579328476616c32",
"0xca846b6579338476616c33",
"0xca846b6579348476616c34"
]
]
}
}
Lib_RLPReader
JSON tests
readList
160
0xc0
0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
should run test: emptylist (58ms)
160
0xcc83646f6783676f6483636174
1
3
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000030000000000000000000000000000000000000000000000000000
1
3
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000030000000000000000000000000000000000000000000000000000
1
3
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000030000000000000000000000000000000000000000000000000000
0x000001000003000001000003000001000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
----
0x0000010000030000010000030000010000030000000000000000000000000000
3
1
----
----
0x0000010000030000010000030000000000000000000000000000000000000000
3
1
----
----
0x0000010000030000000000000000000000000000000000000000000000000000
3
1
----
0x83646f67
0x83676f64
0x83636174
1) should run test: stringlist
160
0xc6827a77c10401
1
2
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000020000000000000000000000000000000000000000000000000000
1
1
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000010000000000000000000000000000000000000000000000000000
0
1
0x0000000000000000000000000000000000000000000000000000000000000000
0x0000000000010000000000000000000000000000000000000000000000000000
0x000001000002000001000001000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
----
0x0000010000020000010000010000000000010000000000000000000000000000
2
1
----
----
0x0000010000010000000000010000000000000000000000000000000000000000
1
1
----
----
0x0000000000010000000000000000000000000000000000000000000000000000
1
0
----
0x827a77
0xc104
0x0100
2) should run test: multilist
160
0xf784617364668471776572847a78637684617364668471776572847a78637684000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
1
4
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000040000000000000000000000000000000000000000000000000000
0x000001000004000001000004000001000004000001000004000001000004000001000004000001000004000001000004000001000004000001000004000001000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
----
0x0000010000040000010000040000010000040000010000040000010000040000
4
1
----
----
0x0000010000040000010000040000010000040000010000040000010000040000
4
1
----
----
0x0000010000040000010000040000010000040000010000040000010000040000
4
1
----
----
0x0000010000040000010000040000010000040000010000040000010000040000
4
1
----
----
0x0000010000040000010000040000010000040000010000040000010000040000
4
1
----
----
0x0000010000040000010000040000010000040000010000040000010000040000
4
1
----
----
0x0000010000040000010000040000010000040000010000040000010000040000
4
1
----
----
0x0000010000040000010000040000010000040000010000040000000000000000
4
1
----
----
0x0000010000040000010000040000010000040000000000000000000000000000
4
1
----
----
0x0000010000040000010000040000000000000000000000000000000000000000
4
1
----
----
0x0000010000040000000000000000000000000000000000000000000000000000
4
1
----
0x8461736466
0x8471776572
0x847a786376
0x8461736466
0x8471776572
0x847a786376
0x8461736466
0x8471776572
0x847a786376
0x8461736466
0x8471776572
3) should run test: shortListMax1
160
0xf840cf84617364668471776572847a786376cf84617364668471776572847a7800000000000000000000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
0x00000100000f00000100000f00000100000f00000100000f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
----
0x00000100000f00000100000f00000100000f00000100000f0000000000000000
15
1
----
----
0x00000100000f00000100000f00000100000f0000000000000000000000000000
15
1
----
----
0x00000100000f00000100000f0000000000000000000000000000000000000000
15
1
----
----
0x00000100000f0000000000000000000000000000000000000000000000000000
15
1
----
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
4) should run test: longList1
160
0xf90200cf84617364668471776572847a786376cf84617364668471776572847a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
1
15
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000f0000000000000000000000000000000000000000000000000000
0x00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f00000100000f
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f00000100000f0000
15
1
----
----
0x00000100000f00000100000f00000100000f00000100000f0000000000000000
15
1
----
----
0x00000100000f00000100000f00000100000f0000000000000000000000000000
15
1
----
----
0x00000100000f00000100000f0000000000000000000000000000000000000000
15
1
----
----
0x00000100000f0000000000000000000000000000000000000000000000000000
15
1
----
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
0xcf84617364668471776572847a786376
5) should run test: longList2
160
0xc4c2c0c0c0
1
2
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000020000000000000000000000000000000000000000000000000000
1
0
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000000000000000000000000000000000000000000000000000000000
0x000001000002000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
----
0x0000010000020000010000000000000000000000000000000000000000000000
2
1
----
----
0x0000010000000000000000000000000000000000000000000000000000000000
0
1
----
0xc2c0c0
0xc0
6) should run test: listsoflists
160
0xc7c0c1c0c3c0c1c0
1
0
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000000000000000000000000000000000000000000000000000000000
1
1
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000010000000000000000000000000000000000000000000000000000
1
3
0x0000000000000000000000000000000000000000000000000000000000000001
0x0000010000030000000000000000000000000000000000000000000000000000
0x000001000000000001000001000001000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
----
0x0000010000000000010000010000010000030000000000000000000000000000
0
1
----
----
0x0000010000010000010000030000000000000000000000000000000000000000
1
1
----
----
0x0000010000030000000000000000000000000000000000000000000000000000
3
1
----
0xc0
0xc1c0
0xc3c0c1c0
7) should run test: listsoflists2
160
0xecca846b6579318476616c31ca846b6579328476616c32ca846b65793384766100000000000000000000000000
1
10
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000a0000000000000000000000000000000000000000000000000000
1
10
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000a0000000000000000000000000000000000000000000000000000
1
10
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000a0000000000000000000000000000000000000000000000000000
1
10
0x0000000000000000000000000000000000000000000000000000000000000001
0x00000100000a0000000000000000000000000000000000000000000000000000
0x00000100000a00000100000a00000100000a00000100000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
----
0x00000100000a00000100000a00000100000a00000100000a0000000000000000
10
1
----
----
0x00000100000a00000100000a00000100000a0000000000000000000000000000
10
1
----
----
0x00000100000a00000100000a0000000000000000000000000000000000000000
10
1
----
----
0x00000100000a0000000000000000000000000000000000000000000000000000
10
1
----
0xca846b6579318476616c31
0xca846b6579328476616c32
0xca846b6579338476616c33
0xca846b6579348476616c34
8) should run test: dictTest1
1 passing (2s)
8 failing
1) Lib_RLPReader
JSON tests
readList
should run test: stringlist:
AssertionError: expected [ Array(1) ] to deeply equal [ Array(1) ]
+ expected - actual
[
[
- "0x83646f67"
- "0x83676f64"
- "0x83636174"
+ "0xcc83646f6783676f6483636174"
+ "0xcc83646f6783676f6483636174"
+ "0xcc83646f6783676f6483636174"
]
]
at Context.<anonymous> (test/helpers/test-runner/json-test-runner.ts:21:100)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
2) Lib_RLPReader
JSON tests
readList
should run test: multilist:
AssertionError: expected [ [ '0x827a77', '0xc104', '0x0100' ] ] to deeply equal [ Array(1) ]
+ expected - actual
[
[
- "0x827a77"
- "0xc104"
- "0x0100"
+ "0xc6827a77c10401"
+ "0xc6827a77c10401"
+ "0xc6827a77c10401"
]
]
at Context.<anonymous> (test/helpers/test-runner/json-test-runner.ts:21:100)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
3) Lib_RLPReader
JSON tests
readList
should run test: shortListMax1:
AssertionError: expected [ Array(1) ] to deeply equal [ Array(1) ]
+ expected - actual
[
[
- "0x8461736466"
- "0x8471776572"
- "0x847a786376"
- "0x8461736466"
- "0x8471776572"
- "0x847a786376"
- "0x8461736466"
- "0x8471776572"
- "0x847a786376"
- "0x8461736466"
- "0x8471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
+ "0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
]
]
at Context.<anonymous> (test/helpers/test-runner/json-test-runner.ts:21:100)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
4) Lib_RLPReader
JSON tests
readList
should run test: longList1:
AssertionError: expected [ Array(1) ] to deeply equal [ Array(1) ]
+ expected - actual
[
[
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
+ "0xf840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
]
]
at Context.<anonymous> (test/helpers/test-runner/json-test-runner.ts:21:100)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
5) Lib_RLPReader
JSON tests
readList
should run test: longList2:
AssertionError: expected [ Array(1) ] to deeply equal [ Array(1) ]
+ expected - actual
[
[
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
- "0xcf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
+ "0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
]
]
at Context.<anonymous> (test/helpers/test-runner/json-test-runner.ts:21:100)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
6) Lib_RLPReader
JSON tests
readList
should run test: listsoflists:
AssertionError: expected [ [ '0xc2c0c0', '0xc0' ] ] to deeply equal [ [ '0xc4c2c0c0c0', '0xc4c2c0c0c0' ] ]
+ expected - actual
[
[
- "0xc2c0c0"
- "0xc0"
+ "0xc4c2c0c0c0"
+ "0xc4c2c0c0c0"
]
]
at Context.<anonymous> (test/helpers/test-runner/json-test-runner.ts:21:100)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
7) Lib_RLPReader
JSON tests
readList
should run test: listsoflists2:
AssertionError: expected [ [ '0xc0', '0xc1c0', '0xc3c0c1c0' ] ] to deeply equal [ Array(1) ]
+ expected - actual
[
[
- "0xc0"
- "0xc1c0"
- "0xc3c0c1c0"
+ "0xc7c0c1c0c3c0c1c0"
+ "0xc7c0c1c0c3c0c1c0"
+ "0xc7c0c1c0c3c0c1c0"
]
]
at Context.<anonymous> (test/helpers/test-runner/json-test-runner.ts:21:100)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
8) Lib_RLPReader
JSON tests
readList
should run test: dictTest1:
AssertionError: expected [ Array(1) ] to deeply equal [ Array(1) ]
+ expected - actual
[
[
- "0xca846b6579318476616c31"
- "0xca846b6579328476616c32"
- "0xca846b6579338476616c33"
- "0xca846b6579348476616c34"
+ "0xecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34"
+ "0xecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34"
+ "0xecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34"
+ "0xecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34"
]
]
at Context.<anonymous> (test/helpers/test-runner/json-test-runner.ts:21:100)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
......@@ -11,6 +11,8 @@ import {
setProxyTarget,
NON_NULL_BYTES32,
ZERO_ADDRESS,
toHexString32,
getEthTime,
} from '../../../helpers'
import { keccak256 } from 'ethers/lib/utils'
......@@ -112,6 +114,7 @@ describe('OVM_StateCommitmentChain', () => {
batch.length
)
await OVM_StateCommitmentChain.appendStateBatch(batch)
batchHeader.extraData = toHexString32(await getEthTime(ethers.provider))
})
describe('when the sender is not the OVM_FraudVerifier', () => {
......
......@@ -71,7 +71,6 @@ const test_run: TestDefinition = {
parameters: [
{
name: 'run => ovmCALL(ADDRESS_1) => ovmADDRESS',
focus: true,
steps: [
{
functionName: 'run',
......
......@@ -17,7 +17,7 @@ describe('OVM_SafetyChecker', () => {
OVM_SafetyChecker = await Factory__OVM_SafetyChecker.deploy()
})
describe('isBytecodeSafe()', () => {
describe.skip('isBytecodeSafe()', () => {
for (const testName of Object.keys(SAFETY_CHECKER_TEST_JSON)) {
const test = SAFETY_CHECKER_TEST_JSON[testName]
it(`should correctly classify: ${testName}`, async () => {
......
......@@ -10,8 +10,8 @@ import { DUMMY_ACCOUNTS, DUMMY_BYTES32, ZERO_ADDRESS } from '../../../helpers'
const EMPTY_ACCOUNT_CODE_HASH =
'0x00004B1DC0DE000000004B1DC0DE000000004B1DC0DE000000004B1DC0DE0000'
const RLP_NULL_HASH =
'0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421'
const KECCAK_256_NULL =
'0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470'
describe('OVM_StateManager', () => {
let signer1: Signer
......@@ -321,7 +321,7 @@ describe('OVM_StateManager', () => {
)
).to.deep.include({
nonce: BigNumber.from(1),
codeHash: RLP_NULL_HASH,
codeHash: KECCAK_256_NULL,
isFresh: true,
})
})
......
......@@ -2,48 +2,24 @@ import { expect } from '../../../setup'
/* External Imports */
import { ethers } from '@nomiclabs/buidler'
import { ContractFactory, Contract, Signer, BigNumber } from 'ethers'
import { ContractFactory, Contract, BigNumber } from 'ethers'
import { smockit, MockContract } from '@eth-optimism/smock'
/* Internal Imports */
/*
import {
getProxyManager,
getMockContract,
MockContract,
ZERO_ADDRESS,
NULL_BYTES32,
NON_NULL_BYTES32,
makeAddressManager,
setProxyTarget,
DUMMY_BATCH_HEADERS,
DUMMY_BATCH_PROOFS,
DUMMY_OVM_TRANSACTIONS,
NON_NULL_BYTES32,
NULL_BYTES32,
} from '../../../helpers'
const DUMMY_BATCH_HEADER = {
batchIndex: 0,
batchRoot: NULL_BYTES32,
batchSize: 0,
prevTotalElements: 0,
extraData: NULL_BYTES32,
}
const DUMMY_BATCH_PROOF = {
index: 0,
siblings: [NULL_BYTES32],
}
const DUMMY_OVM_TRANSACTION = {
timestamp: 0,
queueOrigin: 0,
entrypoint: ZERO_ADDRESS,
origin: ZERO_ADDRESS,
msgSender: ZERO_ADDRESS,
gasLimit: 0,
data: NULL_BYTES32,
}
describe('OVM_FraudVerifier', () => {
let Proxy_Manager: Contract
let AddressManager: Contract
before(async () => {
Proxy_Manager = await getProxyManager()
AddressManager = await makeAddressManager()
})
let Mock__OVM_StateCommitmentChain: MockContract
......@@ -51,49 +27,43 @@ describe('OVM_FraudVerifier', () => {
let Mock__OVM_StateTransitioner: MockContract
let Mock__OVM_StateTransitionerFactory: MockContract
before(async () => {
Mock__OVM_StateCommitmentChain = await getMockContract(
Mock__OVM_StateCommitmentChain = smockit(
await ethers.getContractFactory('OVM_StateCommitmentChain')
)
Mock__OVM_CanonicalTransactionChain = await getMockContract(
Mock__OVM_CanonicalTransactionChain = smockit(
await ethers.getContractFactory('OVM_CanonicalTransactionChain')
)
Mock__OVM_StateTransitioner = await getMockContract(
Mock__OVM_StateTransitioner = smockit(
await ethers.getContractFactory('OVM_StateTransitioner')
)
Mock__OVM_StateTransitionerFactory = await getMockContract(
Mock__OVM_StateTransitionerFactory = smockit(
await ethers.getContractFactory('OVM_StateTransitionerFactory')
)
await setProxyTarget(
Proxy_Manager,
AddressManager,
'OVM_StateCommitmentChain',
Mock__OVM_StateCommitmentChain
)
await setProxyTarget(
Proxy_Manager,
AddressManager,
'OVM_CanonicalTransactionChain',
Mock__OVM_CanonicalTransactionChain
)
await setProxyTarget(
Proxy_Manager,
'OVM_StateTransitioner',
Mock__OVM_StateTransitioner
)
await setProxyTarget(
Proxy_Manager,
AddressManager,
'OVM_StateTransitionerFactory',
Mock__OVM_StateTransitionerFactory
)
Mock__OVM_StateTransitionerFactory.setReturnValues('create', [
Mock__OVM_StateTransitioner.address,
])
Mock__OVM_StateTransitionerFactory.smocked.create.will.return.with(
Mock__OVM_StateTransitioner.address
)
})
let Factory__OVM_FraudVerifier: ContractFactory
......@@ -106,25 +76,27 @@ describe('OVM_FraudVerifier', () => {
let OVM_FraudVerifier: Contract
beforeEach(async () => {
OVM_FraudVerifier = await Factory__OVM_FraudVerifier.deploy(
Proxy_Manager.address
AddressManager.address
)
})
describe('initializeFraudVerification', () => {
describe('when provided an invalid pre-state root inclusion proof', () => {
before(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [false])
Mock__OVM_StateCommitmentChain.smocked.verifyElement.will.return.with(
false
)
})
it('should revert', async () => {
await expect(
OVM_FraudVerifier.initializeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
DUMMY_OVM_TRANSACTION,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0],
DUMMY_OVM_TRANSACTIONS[0],
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0]
)
).to.be.revertedWith('Invalid pre-state root inclusion proof.')
})
......@@ -132,25 +104,27 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid pre-state root inclusion proof', () => {
before(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [true])
Mock__OVM_StateCommitmentChain.smocked.verifyElement.will.return.with(
true
)
})
describe('when provided an invalid transaction inclusion proof', () => {
before(() => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [
false,
])
Mock__OVM_CanonicalTransactionChain.smocked.verifyElement.will.return.with(
false
)
})
it('should revert', async () => {
await expect(
OVM_FraudVerifier.initializeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
DUMMY_OVM_TRANSACTION,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0],
DUMMY_OVM_TRANSACTIONS[0],
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0]
)
).to.be.revertedWith('Invalid transaction inclusion proof.')
})
......@@ -158,20 +132,20 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid transaction inclusion proof', () => {
before(() => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [
true,
])
Mock__OVM_CanonicalTransactionChain.smocked.verifyElement.will.return.with(
true
)
})
it('should deploy a new state transitioner', async () => {
await expect(
OVM_FraudVerifier.initializeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
DUMMY_OVM_TRANSACTION,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0],
DUMMY_OVM_TRANSACTIONS[0],
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0]
)
).to.not.be.reverted
......@@ -185,34 +159,37 @@ describe('OVM_FraudVerifier', () => {
describe('finalizeFraudVerification', () => {
beforeEach(async () => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [true])
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [
true,
])
Mock__OVM_StateCommitmentChain.smocked.verifyElement.will.return.with(
true
)
Mock__OVM_CanonicalTransactionChain.smocked.verifyElement.will.return.with(
true
)
await OVM_FraudVerifier.initializeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
DUMMY_OVM_TRANSACTION,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0],
DUMMY_OVM_TRANSACTIONS[0],
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0]
)
})
describe('when the transition process is not complete', () => {
before(() => {
Mock__OVM_StateTransitioner.setReturnValues('isComplete', [false])
before(async () => {
Mock__OVM_StateTransitioner.smocked.isComplete.will.return.with(false)
})
it('should revert', async () => {
await expect(
OVM_FraudVerifier.finalizeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0],
NON_NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0]
)
).to.be.revertedWith(
'State transition process must be completed prior to finalization.'
......@@ -222,23 +199,23 @@ describe('OVM_FraudVerifier', () => {
describe('when the transition process is complete', () => {
before(() => {
Mock__OVM_StateTransitioner.setReturnValues('isComplete', [true])
Mock__OVM_StateTransitioner.smocked.isComplete.will.return.with(true)
})
describe('when provided an invalid post-state root index', () => {
const batchProof = {
...DUMMY_BATCH_PROOF,
index: DUMMY_BATCH_PROOF.index + 2,
...DUMMY_BATCH_PROOFS[0],
index: DUMMY_BATCH_PROOFS[0].index + 2,
}
it('should revert', async () => {
await expect(
OVM_FraudVerifier.finalizeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0],
NON_NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_HEADERS[0],
batchProof
)
).to.be.revertedWith('Invalid post-state root index.')
......@@ -247,25 +224,25 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid post-state root index', () => {
const batchProof = {
...DUMMY_BATCH_PROOF,
index: DUMMY_BATCH_PROOF.index + 1,
...DUMMY_BATCH_PROOFS[0],
index: DUMMY_BATCH_PROOFS[0].index + 1,
}
describe('when provided an invalid pre-state root inclusion proof', () => {
beforeEach(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [
false,
])
Mock__OVM_StateCommitmentChain.smocked.verifyElement.will.return.with(
false
)
})
it('should revert', async () => {
await expect(
OVM_FraudVerifier.finalizeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0],
NON_NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_HEADERS[0],
batchProof
)
).to.be.revertedWith('Invalid pre-state root inclusion proof.')
......@@ -274,17 +251,16 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid pre-state root inclusion proof', () => {
before(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [
true,
])
Mock__OVM_StateCommitmentChain.smocked.verifyElement.will.return.with(
true
)
})
describe('when provided an invalid post-state root inclusion proof', () => {
beforeEach(() => {
Mock__OVM_StateCommitmentChain.setReturnValues(
'verifyElement',
Mock__OVM_StateCommitmentChain.smocked.verifyElement.will.return.with(
(stateRoot: string, ...args: any) => {
return [stateRoot !== NON_NULL_BYTES32]
return stateRoot !== NON_NULL_BYTES32
}
)
})
......@@ -293,10 +269,10 @@ describe('OVM_FraudVerifier', () => {
await expect(
OVM_FraudVerifier.finalizeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0],
NON_NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_HEADERS[0],
batchProof
)
).to.be.revertedWith('Invalid post-state root inclusion proof.')
......@@ -305,16 +281,15 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid post-state root inclusion proof', () => {
before(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [
true,
])
Mock__OVM_StateCommitmentChain.smocked.verifyElement.will.return.with(
true
)
})
describe('when the provided post-state root does not differ from the computed one', () => {
before(() => {
Mock__OVM_StateTransitioner.setReturnValues(
'getPostStateRoot',
[NON_NULL_BYTES32]
Mock__OVM_StateTransitioner.smocked.getPostStateRoot.will.return.with(
NON_NULL_BYTES32
)
})
......@@ -322,10 +297,10 @@ describe('OVM_FraudVerifier', () => {
await expect(
OVM_FraudVerifier.finalizeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0],
NON_NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_HEADERS[0],
batchProof
)
).to.be.revertedWith(
......@@ -336,29 +311,26 @@ describe('OVM_FraudVerifier', () => {
describe('when the provided post-state root differs from the computed one', () => {
before(() => {
Mock__OVM_StateTransitioner.setReturnValues(
'getPostStateRoot',
[NULL_BYTES32]
Mock__OVM_StateTransitioner.smocked.getPostStateRoot.will.return.with(
NULL_BYTES32
)
})
it('should succeed and attempt to delete a state batch', async () => {
await OVM_FraudVerifier.finalizeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS[0],
NON_NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_HEADERS[0],
batchProof
)
expect(
Mock__OVM_StateCommitmentChain.getCallData(
'deleteStateBatch',
0
)
Mock__OVM_StateCommitmentChain.smocked.deleteStateBatch
.calls[0]
).to.deep.equal([
Object.values(DUMMY_BATCH_HEADER).map((value) => {
Object.values(DUMMY_BATCH_HEADERS[0]).map((value) => {
return Number.isInteger(value)
? BigNumber.from(value)
: value
......@@ -372,4 +344,3 @@ describe('OVM_FraudVerifier', () => {
})
})
})
*/
/* tslint:disable:no-empty */
import { expect } from '../../../setup'
/* External Imports */
import { ethers } from '@nomiclabs/buidler'
import { BigNumber, Contract, ContractFactory } from 'ethers'
/* Internal Imports */
import {
makeAddressManager,
NON_NULL_BYTES32,
NON_ZERO_ADDRESS,
NULL_BYTES32,
setProxyTarget,
TrieTestGenerator,
ZERO_ADDRESS,
} from '../../../helpers'
import {
MockContract,
smockit,
ModifiableContract,
smoddit,
ModifiableContractFactory,
} from '@eth-optimism/smock'
import { keccak256 } from 'ethers/lib/utils'
describe('OVM_StateTransitioner', () => {
let AddressManager: Contract
before(async () => {
AddressManager = await makeAddressManager()
})
let Mock__OVM_ExecutionManager: MockContract
let Mock__OVM_StateManagerFactory: MockContract
let Mock__OVM_StateManager: MockContract
before(async () => {
Mock__OVM_ExecutionManager = smockit(
await ethers.getContractFactory('OVM_ExecutionManager')
)
Mock__OVM_StateManagerFactory = smockit(
await ethers.getContractFactory('OVM_StateManagerFactory')
)
Mock__OVM_StateManager = smockit(
await ethers.getContractFactory('OVM_StateManager')
)
await setProxyTarget(
AddressManager,
'OVM_ExecutionManager',
Mock__OVM_ExecutionManager
)
await setProxyTarget(
AddressManager,
'OVM_StateManagerFactory',
Mock__OVM_StateManagerFactory
)
Mock__OVM_StateManagerFactory.smocked.create.will.return.with(
Mock__OVM_StateManager.address
)
Mock__OVM_StateManager.smocked.putAccount.will.return()
})
let Factory__OVM_StateTransitioner: ModifiableContractFactory
before(async () => {
Factory__OVM_StateTransitioner = await smoddit('OVM_StateTransitioner')
})
let OVM_StateTransitioner: ModifiableContract
beforeEach(async () => {
OVM_StateTransitioner = await Factory__OVM_StateTransitioner.deploy(
AddressManager.address,
0,
NULL_BYTES32,
NULL_BYTES32
)
})
describe('proveContractState', () => {
let ovmContractAddress = NON_ZERO_ADDRESS
let ethContractAddress = ZERO_ADDRESS
let account: any
beforeEach(() => {
Mock__OVM_StateManager.smocked.hasAccount.will.return.with(false)
account = {
nonce: 0,
balance: 0,
storageRoot: NULL_BYTES32,
codeHash: NULL_BYTES32,
}
})
describe('when provided an invalid code hash', () => {
it('should revert', async () => {})
beforeEach(() => {
account.codeHash = NON_NULL_BYTES32
})
it('should revert', async () => {
await expect(
OVM_StateTransitioner.proveContractState(
ovmContractAddress,
ethContractAddress,
account,
'0x'
)
).to.be.revertedWith('Invalid code hash provided.')
})
})
describe('when provided a valid code hash', () => {
beforeEach(async () => {
ethContractAddress = OVM_StateTransitioner.address
account.codeHash = keccak256(
await ethers.provider.getCode(OVM_StateTransitioner.address)
)
})
describe('when provided an invalid account inclusion proof', () => {
it('should revert', async () => {})
const proof = '0x'
it('should revert', async () => {
await expect(
OVM_StateTransitioner.proveContractState(
ovmContractAddress,
ethContractAddress,
account,
proof
)
).to.be.reverted
})
})
describe('when provided a valid account inclusion proof', () => {})
describe('when provided a valid account inclusion proof', () => {
let proof: string
beforeEach(async () => {
const generator = await TrieTestGenerator.fromAccounts({
accounts: [
{
...account,
address: ovmContractAddress,
},
],
secure: true,
})
const test = await generator.makeAccountProofTest(ovmContractAddress)
proof = test.accountTrieWitness
OVM_StateTransitioner = await Factory__OVM_StateTransitioner.deploy(
AddressManager.address,
0,
test.accountTrieRoot,
NULL_BYTES32
)
})
it('should put the account in the state manager', async () => {
await expect(
OVM_StateTransitioner.proveContractState(
ovmContractAddress,
ethContractAddress,
account,
proof
)
).to.not.be.reverted
expect(
Mock__OVM_StateManager.smocked.putAccount.calls[0]
).to.deep.equal([
NON_ZERO_ADDRESS,
[
BigNumber.from(account.nonce),
BigNumber.from(account.balance),
account.storageRoot,
account.codeHash,
ethContractAddress,
false,
],
])
})
})
})
})
describe('proveStorageSlot', () => {
beforeEach(() => {
Mock__OVM_StateManager.smocked.hasContractStorage.will.return.with(false)
})
describe('when the corresponding account is not proven', () => {
it('should revert', async () => {})
beforeEach(() => {
Mock__OVM_StateManager.smocked.hasAccount.will.return.with(false)
})
it('should revert', async () => {
await expect(
OVM_StateTransitioner.proveStorageSlot(
NON_ZERO_ADDRESS,
NON_NULL_BYTES32,
NON_NULL_BYTES32,
'0x'
)
).to.be.revertedWith(
'Contract must be verified before proving a storage slot.'
)
})
})
describe('when the corresponding account is proven', () => {
beforeEach(() => {
Mock__OVM_StateManager.smocked.hasAccount.will.return.with(true)
})
describe('when provided an invalid slot inclusion proof', () => {
it('should revert', async () => {})
let key = keccak256('0x1234')
let val = keccak256('0x5678')
let proof = '0x'
beforeEach(async () => {
const generator = await TrieTestGenerator.fromNodes({
nodes: [
{
key,
val,
},
],
secure: true,
})
const test = await generator.makeInclusionProofTest(0)
Mock__OVM_StateManager.smocked.getAccountStorageRoot.will.return.with(
test.root
)
})
it('should revert', async () => {
await expect(
OVM_StateTransitioner.proveStorageSlot(
ZERO_ADDRESS,
key,
val,
proof
)
).to.be.reverted
})
})
describe('when provided a valid slot inclusion proof', () => {})
describe('when provided a valid slot inclusion proof', () => {
let key = keccak256('0x1234')
let val = keccak256('0x5678')
let proof: string
beforeEach(async () => {
const generator = await TrieTestGenerator.fromNodes({
nodes: [
{
key,
val,
},
],
secure: true,
})
const test = await generator.makeInclusionProofTest(0)
proof = test.proof
Mock__OVM_StateManager.smocked.getAccountStorageRoot.will.return.with(
test.root
)
})
it('should insert the storage slot', async () => {
await expect(
OVM_StateTransitioner.proveStorageSlot(
ZERO_ADDRESS,
key,
val,
proof
)
).to.not.be.reverted
expect(
Mock__OVM_StateManager.smocked.putContractStorage.calls[0]
).to.deep.equal([ZERO_ADDRESS, key, val])
})
})
})
})
......@@ -35,46 +294,280 @@ describe('OVM_StateTransitioner', () => {
})
describe('commitContractState', () => {
describe('when the account was not changed', () => {
it('should revert', async () => {})
beforeEach(async () => {
OVM_StateTransitioner.smodify.set({
phase: 1,
})
})
describe('when the account was changed', () => {
describe('when the account has not been committed', () => {
it('should commit the account and update the state', async () => {})
let ovmContractAddress = NON_ZERO_ADDRESS
let account: any
beforeEach(() => {
Mock__OVM_StateManager.smocked.hasAccount.will.return.with(false)
account = {
nonce: 0,
balance: 0,
storageRoot: NULL_BYTES32,
codeHash: NULL_BYTES32,
}
})
describe('when the account was not changed or has already been committed', () => {
before(() => {
Mock__OVM_StateManager.smocked.commitAccount.will.return.with(false)
})
it('should revert', async () => {
await expect(
OVM_StateTransitioner.commitContractState(
ovmContractAddress,
account,
'0x'
)
).to.be.revertedWith(
'Account was not changed or has already been committed.'
)
})
})
describe('when the account was changed or has not already been committed', () => {
before(() => {
Mock__OVM_StateManager.smocked.commitAccount.will.return.with(true)
})
describe('when given an valid update proof', () => {
let proof: string
let postStateRoot: string
beforeEach(async () => {
const generator = await TrieTestGenerator.fromAccounts({
accounts: [
{
...account,
nonce: 10,
address: ovmContractAddress,
},
],
secure: true,
})
const test = await generator.makeAccountUpdateTest(
ovmContractAddress,
account
)
proof = test.accountTrieWitness
postStateRoot = test.newAccountTrieRoot
OVM_StateTransitioner.smodify.put({
postStateRoot: test.accountTrieRoot,
})
})
describe('when the account was already committed', () => {
it('should revert', () => {})
it('should update the post state root', async () => {
await expect(
OVM_StateTransitioner.commitContractState(
ovmContractAddress,
account,
proof
)
).to.not.be.reverted
expect(await OVM_StateTransitioner.getPostStateRoot()).to.equal(
postStateRoot
)
})
})
})
})
describe('commitStorageSlot', () => {
describe('when the slot was not changed', () => {
it('should revert', async () => {})
beforeEach(() => {
OVM_StateTransitioner.smodify.set({
phase: 1,
})
})
let ovmContractAddress = NON_ZERO_ADDRESS
let account: any
let key = keccak256('0x1234')
let val = keccak256('0x5678')
let newVal = keccak256('0x4321')
beforeEach(() => {
account = {
nonce: 0,
balance: 0,
storageRoot: NULL_BYTES32,
codeHash: NULL_BYTES32,
}
Mock__OVM_StateManager.smocked.getAccount.will.return.with({
...account,
ethAddress: ZERO_ADDRESS,
isFresh: false,
})
})
describe('when the slot was not changed or was already committed', () => {
beforeEach(() => {
Mock__OVM_StateManager.smocked.commitContractStorage.will.return.with(
false
)
})
it('should revert', async () => {
await expect(
OVM_StateTransitioner.commitStorageSlot(
ovmContractAddress,
key,
val,
'0x',
'0x'
)
).to.be.revertedWith(
'Storage slot was not changed or has already been committed.'
)
})
})
describe('when the slot was changed', () => {
describe('when the slot has not been committed', () => {
it('should commit the slot and update the state', async () => {})
describe('when the slot was changed or not already committed', () => {
beforeEach(() => {
Mock__OVM_StateManager.smocked.commitContractStorage.will.return.with(
true
)
})
describe('when the slot was already committed', () => {
it('should revert', () => {})
describe('with a valid proof', () => {
let accountTrieProof: string
let storageTrieProof: string
let postStateRoot: string
beforeEach(async () => {
const storageGenerator = await TrieTestGenerator.fromNodes({
nodes: [
{
key,
val,
},
],
secure: true,
})
const storageTest = await storageGenerator.makeNodeUpdateTest(
key,
newVal
)
const generator = await TrieTestGenerator.fromAccounts({
accounts: [
{
...account,
storageRoot: storageTest.root,
address: ovmContractAddress,
},
],
secure: true,
})
const test = await generator.makeAccountUpdateTest(
ovmContractAddress,
{
...account,
storageRoot: storageTest.newRoot,
}
)
Mock__OVM_StateManager.smocked.getAccount.will.return.with({
...account,
storageRoot: storageTest.root,
ethAddress: ZERO_ADDRESS,
isFresh: false,
})
accountTrieProof = test.accountTrieWitness
storageTrieProof = storageTest.proof
postStateRoot = test.newAccountTrieRoot
OVM_StateTransitioner.smodify.put({
postStateRoot: test.accountTrieRoot,
})
})
it('should commit the slot and update the state', async () => {
await expect(
OVM_StateTransitioner.commitStorageSlot(
ovmContractAddress,
key,
newVal,
accountTrieProof,
storageTrieProof
)
).to.not.be.reverted
})
})
})
})
describe('completeTransition', () => {
beforeEach(() => {
OVM_StateTransitioner.smodify.set({
phase: 1,
})
})
describe('when there are uncommitted accounts', () => {
it('should revert', async () => {})
beforeEach(() => {
Mock__OVM_StateManager.smocked.getTotalUncommittedAccounts.will.return.with(
1
)
Mock__OVM_StateManager.smocked.getTotalUncommittedContractStorage.will.return.with(
0
)
})
it('should revert', async () => {
await expect(
OVM_StateTransitioner.completeTransition()
).to.be.revertedWith(
'All accounts must be committed before completing a transition.'
)
})
})
describe('when there are uncommitted storage slots', () => {
it('should revert', async () => {})
beforeEach(() => {
Mock__OVM_StateManager.smocked.getTotalUncommittedAccounts.will.return.with(
0
)
Mock__OVM_StateManager.smocked.getTotalUncommittedContractStorage.will.return.with(
1
)
})
it('should revert', async () => {
await expect(
OVM_StateTransitioner.completeTransition()
).to.be.revertedWith(
'All storage must be committed before completing a transition.'
)
})
})
describe('when all state changes are committed', () => {})
describe('when all state changes are committed', () => {
beforeEach(() => {
Mock__OVM_StateManager.smocked.getTotalUncommittedAccounts.will.return.with(
0
)
Mock__OVM_StateManager.smocked.getTotalUncommittedContractStorage.will.return.with(
0
)
})
it('should complete the transition', async () => {
await expect(OVM_StateTransitioner.completeTransition()).to.not.be
.reverted
expect(await OVM_StateTransitioner.isComplete()).to.equal(true)
})
})
})
})
/* tslint:disable:no-empty */
import { expect } from '../../../setup'
describe('Lib_OVMCodec', () => {
describe('decodeEOATransaction', () => {
describe('when given a valid RLP-encoded transaction', () => {
it('should return the decoded transaction struct', async () => {})
})
})
describe('encodeTransaction', () => {
it('should ABI encode (packed) the given transaction', async () => {})
})
describe('hashTransaction', () => {
it('should return the hash of the encoded transaction', async () => {})
})
})
/* External Imports */
import * as rlp from 'rlp'
/* Internal Imports */
import { Lib_RLPReader_TEST_JSON } from '../../../data'
import { runJsonTest, toHexString } from '../../../helpers'
describe('Lib_RLPReader', () => {
//console.log(JSON.stringify(Lib_RLPReader_TEST_JSON2, null, 4))
describe('JSON tests', () => {
runJsonTest('TestLib_RLPReader', Lib_RLPReader_TEST_JSON)
})
})
/* tslint:disable:no-empty */
import { expect } from '../../../setup'
/* External Imports */
import { ethers } from '@nomiclabs/buidler'
import { Contract } from 'ethers'
/* Internal Imports */
import { Lib_RLPWriter_TEST_JSON } from '../../../data'
const encode = async (Lib_RLPWriter: Contract, input: any): Promise<void> => {
if (Array.isArray(input)) {
const elements = await Promise.all(
input.map(async (el) => {
return encode(Lib_RLPWriter, el)
})
)
return Lib_RLPWriter.writeList(elements)
} else if (Number.isInteger(input)) {
return Lib_RLPWriter.writeUint(input)
} else if (input[0] === '#') {
return Lib_RLPWriter.writeInt(input.slice(1))
} else {
return Lib_RLPWriter.writeString(input)
}
}
describe('Lib_RLPWriter', () => {
let Lib_RLPWriter: Contract
before(async () => {
Lib_RLPWriter = await (
await ethers.getContractFactory('TestLib_RLPWriter')
).deploy()
})
describe('Official Ethereum RLP Tests', () => {
for (const [key, test] of Object.entries(Lib_RLPWriter_TEST_JSON)) {
it(`should properly encode: ${key}`, async () => {
expect(await encode(Lib_RLPWriter, test.in)).to.equal(test.out)
})
}
})
})
import { expect } from '../../../setup'
/* External Imports */
import { ethers } from '@nomiclabs/buidler'
import { Contract } from 'ethers'
/* Internal Imports */
import { TrieTestGenerator } from '../../../helpers'
const NODE_COUNTS = [1, 2, 128, 256, 512, 1024, 2048, 4096]
describe('Lib_MerkleTrie', () => {
let Lib_MerkleTrie: Contract
before(async () => {
Lib_MerkleTrie = await (
await ethers.getContractFactory('TestLib_MerkleTrie')
).deploy()
})
describe('verifyInclusionProof', () => {
for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes`, () => {
let generator: TrieTestGenerator
before(async () => {
generator = await TrieTestGenerator.fromRandom({
seed: `seed.incluson.${nodeCount}`,
nodeCount,
secure: false,
})
})
for (
let i = 0;
i < nodeCount;
i += nodeCount / (nodeCount > 8 ? 8 : 1)
) {
it(`should correctly prove inclusion for node #${i}`, async () => {
const test = await generator.makeInclusionProofTest(i)
expect(
await Lib_MerkleTrie.verifyInclusionProof(
test.key,
test.val,
test.proof,
test.root
)
).to.equal(true)
})
}
})
}
})
describe('update', () => {
for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes`, () => {
let generator: TrieTestGenerator
before(async () => {
generator = await TrieTestGenerator.fromRandom({
seed: `seed.update.${nodeCount}`,
nodeCount,
secure: false,
})
})
for (
let i = 0;
i < nodeCount;
i += nodeCount / (nodeCount > 8 ? 8 : 1)
) {
it(`should correctly update node #${i}`, async () => {
const test = await generator.makeNodeUpdateTest(
i,
'0x1234123412341234'
)
expect(
await Lib_MerkleTrie.update(
test.key,
test.val,
test.proof,
test.root
)
).to.equal(test.newRoot)
})
}
})
}
})
describe('get', () => {
for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes`, () => {
let generator: TrieTestGenerator
before(async () => {
generator = await TrieTestGenerator.fromRandom({
seed: `seed.get.${nodeCount}`,
nodeCount,
secure: false,
})
})
for (
let i = 0;
i < nodeCount;
i += nodeCount / (nodeCount > 8 ? 8 : 1)
) {
it(`should correctly get the value of node #${i}`, async () => {
const test = await generator.makeInclusionProofTest(i)
expect(
await Lib_MerkleTrie.get(test.key, test.proof, test.root)
).to.deep.equal([true, test.val])
})
}
})
}
})
})
import { expect } from '../../../setup'
/* External Imports */
import { ethers } from '@nomiclabs/buidler'
import { Contract } from 'ethers'
/* Internal Imports */
import { TrieTestGenerator } from '../../../helpers'
const NODE_COUNTS = [1, 2, 128, 256, 512, 1024, 2048, 4096]
describe('Lib_SecureMerkleTrie', () => {
let Lib_SecureMerkleTrie: Contract
before(async () => {
Lib_SecureMerkleTrie = await (
await ethers.getContractFactory('TestLib_SecureMerkleTrie')
).deploy()
})
describe('verifyInclusionProof', () => {
for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes`, () => {
let generator: TrieTestGenerator
before(async () => {
generator = await TrieTestGenerator.fromRandom({
seed: `seed.incluson.${nodeCount}`,
nodeCount,
secure: true,
})
})
for (
let i = 0;
i < nodeCount;
i += nodeCount / (nodeCount > 8 ? 8 : 1)
) {
it(`should correctly prove inclusion for node #${i}`, async () => {
const test = await generator.makeInclusionProofTest(i)
expect(
await Lib_SecureMerkleTrie.verifyInclusionProof(
test.key,
test.val,
test.proof,
test.root
)
).to.equal(true)
})
}
})
}
})
describe('update', () => {
for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes`, () => {
let generator: TrieTestGenerator
before(async () => {
generator = await TrieTestGenerator.fromRandom({
seed: `seed.update.${nodeCount}`,
nodeCount,
secure: true,
})
})
for (
let i = 0;
i < nodeCount;
i += nodeCount / (nodeCount > 8 ? 8 : 1)
) {
it(`should correctly update node #${i}`, async () => {
const test = await generator.makeNodeUpdateTest(
i,
'0x1234123412341234'
)
expect(
await Lib_SecureMerkleTrie.update(
test.key,
test.val,
test.proof,
test.root
)
).to.equal(test.newRoot)
})
}
})
}
})
describe('get', () => {
for (const nodeCount of NODE_COUNTS) {
describe(`inside a trie with ${nodeCount} nodes`, () => {
let generator: TrieTestGenerator
before(async () => {
generator = await TrieTestGenerator.fromRandom({
seed: `seed.get.${nodeCount}`,
nodeCount,
secure: true,
})
})
for (
let i = 0;
i < nodeCount;
i += nodeCount / (nodeCount > 8 ? 8 : 1)
) {
it(`should correctly get the value of node #${i}`, async () => {
const test = await generator.makeInclusionProofTest(i)
expect(
await Lib_SecureMerkleTrie.get(test.key, test.proof, test.root)
).to.deep.equal([true, test.val])
})
}
})
}
})
})
/* Internal Imports */
import { Lib_Bytes32Utils_TEST_JSON } from '../../../data'
import { runJsonTest } from '../../../helpers'
describe('Lib_Bytes32Utils', () => {
describe('JSON tests', () => {
runJsonTest('TestLib_Bytes32Utils', Lib_Bytes32Utils_TEST_JSON)
})
})
/* Internal Imports */
import { Lib_BytesUtils_TEST_JSON } from '../../../data'
import { runJsonTest } from '../../../helpers'
describe('Lib_BytesUtils', () => {
describe('JSON tests', () => {
runJsonTest('TestLib_BytesUtils', Lib_BytesUtils_TEST_JSON)
})
})
/* Internal Imports */
import { Lib_ECDSAUtils_TEST_JSON } from '../../../data'
import { runJsonTest } from '../../../helpers'
describe('Lib_ECDSAUtils', () => {
describe('JSON tests', () => {
runJsonTest('TestLib_ECDSAUtils', Lib_ECDSAUtils_TEST_JSON)
})
})
/* tslint:disable:no-empty */
import { expect } from '../../../setup'
/* External Imports */
import { ethers } from '@nomiclabs/buidler'
import { Contract, Signer } from 'ethers'
/* Internal Imports */
import {
ZERO_ADDRESS,
makeHexString,
fromHexString,
getHexSlice,
} from '../../../helpers'
describe('Lib_EthUtils', () => {
let signer: Signer
before(async () => {
;[signer] = await ethers.getSigners()
})
let Lib_EthUtils: Contract
before(async () => {
Lib_EthUtils = await (
await ethers.getContractFactory('TestLib_EthUtils')
).deploy()
})
describe('getCode(address,uint256,uint256)', () => {
describe('when the contract does not exist', () => {
const address = ZERO_ADDRESS
describe('when offset = 0', () => {
const offset = 0
it('should return length zero bytes', async () => {
const length = 100
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(makeHexString('00', length))
})
})
describe('when offset > 0', () => {
const offset = 50
it('should return length zero bytes', async () => {
const length = 100
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(makeHexString('00', length))
})
})
})
describe('when the account is an EOA', () => {
let address: string
before(async () => {
address = await signer.getAddress()
})
describe('when offset = 0', () => {
const offset = 0
it('should return length zero bytes', async () => {
const length = 100
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(makeHexString('00', length))
})
})
describe('when offset > 0', () => {
const offset = 50
it('should return length zero bytes', async () => {
const length = 100
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(makeHexString('00', length))
})
})
})
describe('when the contract exists', () => {
let address: string
let code: string
let codeLength: number
before(async () => {
address = Lib_EthUtils.address
code = await ethers.provider.getCode(address)
codeLength = fromHexString(code).length
})
describe('when offset = 0', () => {
const offset = 0
describe('when length = 0', () => {
const length = 0
it('should return empty', async () => {
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal('0x')
})
})
describe('when 0 < length < extcodesize(contract)', () => {
let length: number
before(async () => {
length = Math.floor(codeLength / 2)
})
it('should return N bytes from the start of code', async () => {
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(getHexSlice(code, offset, length))
})
})
describe('when length = extcodesize(contract)', () => {
let length: number
before(async () => {
length = codeLength
})
it('should return the full contract code', async () => {
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(code)
})
})
describe('when length > extcodesize(contract)', () => {
let length: number
before(async () => {
length = codeLength * 2
})
it('should return the full contract code padded to length with zero bytes', async () => {
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(code + '00'.repeat(codeLength))
})
})
})
describe('when 0 < offset < extcodesize(contract)', () => {
let offset: number
before(async () => {
offset = Math.floor(codeLength / 2)
})
describe('when length = 0', () => {
const length = 0
it('should return empty', async () => {
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal('0x')
})
})
describe('when 0 < length < extcodesize(contract) - offset', () => {
let length: number
before(async () => {
length = Math.floor((codeLength - offset) / 2)
})
it('should return the selected bytes', async () => {
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(getHexSlice(code, offset, length))
})
})
describe('when length = extcodesize(contract) - offset', () => {
let length: number
before(async () => {
length = codeLength - offset
})
it('should return the selected bytes', async () => {
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(getHexSlice(code, offset, length))
})
})
describe('when length > extcodesize(contract) - offset', () => {
let length: number
let extraLength: number
before(async () => {
length = (codeLength - offset) * 2
extraLength = length - (codeLength - offset)
})
it('should return the selected bytes padded to length with zero bytes', async () => {
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(
getHexSlice(code, offset, codeLength - offset) +
'00'.repeat(extraLength)
)
})
})
})
describe('offset >= extcodesize(contract)', () => {
let offset: number
before(async () => {
offset = codeLength * 2
})
describe('when length = 0', () => {
const length = 0
it('should return empty', async () => {
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal('0x')
})
})
describe('when length > 0', () => {
let length: number
before(async () => {
length = codeLength * 2
})
it('should return length zero bytes', async () => {
expect(
await Lib_EthUtils['getCode(address,uint256,uint256)'](
address,
offset,
length
)
).to.equal(makeHexString('00', length))
})
})
})
})
})
describe('getCode(address)', () => {
describe('when the contract does not exist', () => {})
describe('when the account is an EOA', () => {})
describe('when the contract exists', () => {})
})
describe('getCodeSize', () => {
describe('when the contract does not exist', () => {})
describe('when the account is an EOA', () => {})
describe('when the contract exists', () => {})
})
describe('getCodeHash', () => {
describe('when the contract does not exist', () => {})
describe('when the account is an EOA', () => {})
describe('when the contract exists', () => {})
})
describe('createContract', () => {
describe('it should create the contract', () => {})
})
describe('getAddressForCREATE', () => {
describe('when the nonce is zero', () => {
describe('it should return the correct address', () => {})
})
describe('when the nonce is > 0', () => {
describe('it should return the correct address', () => {})
})
})
describe('getAddressForCREATE2', () => {
describe('when the bytecode is not empty', () => {
describe('when the salt is not zero', () => {
describe('it should return the correct address', () => {})
})
describe('when the salt is zero', () => {
describe('it should return the correct address', () => {})
})
})
describe('when the bytecode is empty', () => {
describe('when the salt is not zero', () => {
describe('it should return the correct address', () => {})
})
describe('when the salt is zero', () => {
describe('it should return the correct address', () => {})
})
})
})
})
import { create2Tests } from './json/create2.test.json'
import { rlpTests } from './json/rlp.test.json'
import { safetyCheckerTests } from './json/safety-checker.test.json'
export const RLP_TEST_JSON = rlpTests
export const CREATE2_TEST_JSON = create2Tests
export const SAFETY_CHECKER_TEST_JSON = safetyCheckerTests
export { tests as Lib_RLPWriter_TEST_JSON } from './json/libraries/rlp/Lib_RLPWriter.test.json'
export { tests as Lib_RLPReader_TEST_JSON } from './json/libraries/rlp/Lib_RLPReader.test.json'
export { tests as Lib_Bytes32Utils_TEST_JSON } from './json/libraries/utils/Lib_Bytes32Utils.test.json'
export { tests as Lib_BytesUtils_TEST_JSON } from './json/libraries/utils/Lib_BytesUtils.test.json'
export { tests as Lib_ECDSAUtils_TEST_JSON } from './json/libraries/utils/Lib_ECDSAUtils.test.json'
export { tests as Lib_MerkleTrie_TEST_JSON } from './json/libraries/trie/Lib_MerkleTrie.test.json'
export { tests as CREATE2_TEST_JSON } from './json/create2.test.json'
export { tests as SAFETY_CHECKER_TEST_JSON } from './json/safety-checker.test.json'
......@@ -2,7 +2,7 @@
"source": "https://eips.ethereum.org/EIPS/eip-1014",
"notes": "added additional tests with more bytecode",
"date": "2020-01-10",
"create2Tests": {
"tests": {
"all zero values": {
"address": "0x0000000000000000000000000000000000000000",
"salt": "0x0000000000000000000000000000000000000000000000000000000000000000",
......
{
"tests": {
"readBool": {
"true": {
"in": [
"0x01"
],
"out": [
true
]
},
"false": {
"in": [
"0x00"
],
"out": [
false
]
}
},
"readAddress": {
"valid address": {
"in": [
"0x941212121212121212121212121212121212121212"
],
"out": [
"0x1212121212121212121212121212121212121212"
]
}
},
"readBytes": {
"bytestring00": {
"in": [
"0x00"
],
"out": [
"0x00"
]
},
"bytestring01": {
"in": [
"0x01"
],
"out": [
"0x01"
]
},
"bytestring7F": {
"in": [
"0x7f"
],
"out": [
"0x7f"
]
}
},
"readString": {
"emptystring": {
"in": [
"0x80"
],
"out": [
""
]
},
"shortstring": {
"in": [
"0x83646f67"
],
"out": [
"dog"
]
},
"shortstring2": {
"in": [
"0xb74c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c69"
],
"out": [
"Lorem ipsum dolor sit amet, consectetur adipisicing eli"
]
},
"longstring": {
"in": [
"0xb8384c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e7365637465747572206164697069736963696e6720656c6974"
],
"out": [
"Lorem ipsum dolor sit amet, consectetur adipisicing elit"
]
},
"longstring2": {
"in": [
"0xb904004c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73656374657475722061646970697363696e6720656c69742e20437572616269747572206d6175726973206d61676e612c20737573636970697420736564207665686963756c61206e6f6e2c20696163756c697320666175636962757320746f72746f722e2050726f696e20737573636970697420756c74726963696573206d616c6573756164612e204475697320746f72746f7220656c69742c2064696374756d2071756973207472697374697175652065752c20756c7472696365732061742072697375732e204d6f72626920612065737420696d70657264696574206d6920756c6c616d636f7270657220616c6971756574207375736369706974206e6563206c6f72656d2e2041656e65616e2071756973206c656f206d6f6c6c69732c2076756c70757461746520656c6974207661726975732c20636f6e73657175617420656e696d2e204e756c6c6120756c74726963657320747572706973206a7573746f2c20657420706f73756572652075726e6120636f6e7365637465747572206e65632e2050726f696e206e6f6e20636f6e76616c6c6973206d657475732e20446f6e65632074656d706f7220697073756d20696e206d617572697320636f6e67756520736f6c6c696369747564696e2e20566573746962756c756d20616e746520697073756d207072696d697320696e206661756369627573206f726369206c756374757320657420756c74726963657320706f737565726520637562696c69612043757261653b2053757370656e646973736520636f6e76616c6c69732073656d2076656c206d617373612066617563696275732c2065676574206c6163696e6961206c616375732074656d706f722e204e756c6c61207175697320756c747269636965732070757275732e2050726f696e20617563746f722072686f6e637573206e69626820636f6e64696d656e74756d206d6f6c6c69732e20416c697175616d20636f6e73657175617420656e696d206174206d65747573206c75637475732c206120656c656966656e6420707572757320656765737461732e20437572616269747572206174206e696268206d657475732e204e616d20626962656e64756d2c206e6571756520617420617563746f72207472697374697175652c206c6f72656d206c696265726f20616c697175657420617263752c206e6f6e20696e74657264756d2074656c6c7573206c65637475732073697420616d65742065726f732e20437261732072686f6e6375732c206d65747573206163206f726e617265206375727375732c20646f6c6f72206a7573746f20756c747269636573206d657475732c20617420756c6c616d636f7270657220766f6c7574706174"
],
"out": [
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur mauris magna, suscipit sed vehicula non, iaculis faucibus tortor. Proin suscipit ultricies malesuada. Duis tortor elit, dictum quis tristique eu, ultrices at risus. Morbi a est imperdiet mi ullamcorper aliquet suscipit nec lorem. Aenean quis leo mollis, vulputate elit varius, consequat enim. Nulla ultrices turpis justo, et posuere urna consectetur nec. Proin non convallis metus. Donec tempor ipsum in mauris congue sollicitudin. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse convallis sem vel massa faucibus, eget lacinia lacus tempor. Nulla quis ultricies purus. Proin auctor rhoncus nibh condimentum mollis. Aliquam consequat enim at metus luctus, a eleifend purus egestas. Curabitur at nibh metus. Nam bibendum, neque at auctor tristique, lorem libero aliquet arcu, non interdum tellus lectus sit amet eros. Cras rhoncus, metus ac ornare cursus, dolor justo ultrices metus, at ullamcorper volutpat"
]
}
},
"readUint256": {
"zero": {
"in": [
"0x80"
],
"out": [
0
]
},
"smallint": {
"in": [
"0x01"
],
"out": [
1
]
},
"smallint2": {
"in": [
"0x10"
],
"out": [
16
]
},
"smallint3": {
"in": [
"0x4f"
],
"out": [
79
]
},
"smallint4": {
"in": [
"0x7f"
],
"out": [
127
]
},
"mediumint1": {
"in": [
"0x8180"
],
"out": [
128
]
},
"mediumint2": {
"in": [
"0x8203e8"
],
"out": [
1000
]
},
"mediumint3": {
"in": [
"0x830186a0"
],
"out": [
100000
]
}
},
"readList": {
"emptylist": {
"in": [
"0xc0"
],
"out": [
[]
]
},
"stringlist": {
"in": [
"0xcc83646f6783676f6483636174"
],
"out": [
[
"0x83646f67",
"0x83676f64",
"0x83636174"
]
]
},
"multilist": {
"in": [
"0xc6827a77c10401"
],
"out": [
[
"0x827a77",
"0xc104",
"0x01"
]
]
},
"shortListMax1": {
"in": [
"0xf784617364668471776572847a78637684617364668471776572847a78637684617364668471776572847a78637684617364668471776572"
],
"out": [
[
"0x8461736466",
"0x8471776572",
"0x847a786376",
"0x8461736466",
"0x8471776572",
"0x847a786376",
"0x8461736466",
"0x8471776572",
"0x847a786376",
"0x8461736466",
"0x8471776572"
]
]
},
"longList1": {
"in": [
"0xf840cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
],
"out": [
[
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376"
]
]
},
"longList2": {
"in": [
"0xf90200cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376cf84617364668471776572847a786376"
],
"out": [
[
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376",
"0xcf84617364668471776572847a786376"
]
]
},
"listsoflists": {
"in": [
"0xc4c2c0c0c0"
],
"out": [
[
"0xc2c0c0",
"0xc0"
]
]
},
"listsoflists2": {
"in": [
"0xc7c0c1c0c3c0c1c0"
],
"out": [
[
"0xc0",
"0xc1c0",
"0xc3c0c1c0"
]
]
},
"dictTest1": {
"in": [
"0xecca846b6579318476616c31ca846b6579328476616c32ca846b6579338476616c33ca846b6579348476616c34"
],
"out": [
[
"0xca846b6579318476616c31",
"0xca846b6579328476616c32",
"0xca846b6579338476616c33",
"0xca846b6579348476616c34"
]
]
}
}
}
}
......@@ -3,7 +3,7 @@
"notes": "Removed BigInt test, since ethers does not support integers over 10^16: https://github.com/ethers-io/ethers.js/issues/418",
"latestcommit": "b2dcd19973637ac05e17646378dac9cbb2927075",
"date": "2020-01-08",
"rlpTests": {
"tests": {
"emptystring": {
"in": "",
"out": "0x80"
......
{
"tests": {
"update": {
"basic leaf value updates": {
"in": [
"0x6b6579316161",
"0x736f6d65206e65772076616c7565",
"0xf8a2a7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080b0ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
"0xc6049f657b848e7a811a366d60dbd8fed5edb1432f493fcd11eb882d2fb38470"
]
},
"new leaf insertions": {
"in": [
"0x6b6579346464",
"0x736f6d65206e65772076616c7565",
"0xf871a7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
"0x2d9bfc0b1e73cf420cb79ec039a28f4449de3fe875f455f34c94a867be300c7b"
]
},
"modifications to extension node": {
"in": [
"0x6b6579316162",
"0x736f6d65206e65772076616c7565",
"0xf8a2a7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080b0ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
"0x0ef0b67d8f45c0e6a1673541196a121bc12639fae8026ac2594961faaa0dbac5"
]
},
"shift existing value to branch": {
"in": [
"0x6b657931616161",
"0x736f6d65206e65772076616c7565",
"0xf8a2a7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080b0ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
"0x4efa4e217b51fa5c79112e45727f7754882db71320275403fb9f2c74686ac577"
]
},
"shift new value to branch": {
"in": [
"0x6b65793161",
"0x736f6d65206e65772076616c7565",
"0xf8a2a7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080b0ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
"0x73fb38b2ad097f755eb8c3485035ee04960717956dd5ccd0ea086afe55538772"
]
},
"arbitrary update (128 nodes)": {
"in": [
"0x38306562633864376331633237656437393930613731633839656164323463636431343836336662626466336662356462316339313632636661633436663833",
"0x66623237633466393532353865363964303232623963373766616132643166356339643030336233616365306662353264373163613635393263326666303134",
"0xf9033db853f851808080a01683853733c3f60794d4c72f7b2f72afdb66c78c003d5447007e6570aabbce488080a075779c9fa7a787bd9e9b4793d8570ab8d00a6da215b1149d8adbffe15b72035c80808080808080808080b90154f90151a0ca8487ac08712727a9f015ea79a5425dff3e2827444594ad319899054bea6726a05bc9e58c52524b0e143297bf4641a131fefdf0457deaf17a06a4ee3d5b47e236a03c79e1171977ad0d6147cd8567dc5a427012007fcfb20e0f9e6c53e8d2783bdfa08b4e2951e45c5323519d148fc7224d2bceff6a1109102e877fcb6172b85270c4a0483a71a1dc202bc4793dda2491e0cf6caa80f4e8c41490faf0ccff36f36ab575a0cfc4cc320fdc887c1a6393d3dfa2e10693570fb9e09814b078a4e22788d7b1baa0db9c9f4674af3d18cc1249ac6712663d7d3241a9b7a358d3b7f287a7abbfed77a07e8f510894db4c610cb31efa5a3fa90776649c92edd4abbd550bc06a7c5f0598a0ad558331f2fff09e6c6c11a6e10f28e248729492349d1e44f7c790fc6630fe25a0a328bd791bddc75a9f835d68807b7dfcdaa232816ef0a8f056b104d566bc5b1b80808080808080b853f851808080a0d4bf75bea1883976cf54999f17b869595c833157bac7733ae45905f7894a63ca8080a0809edbfbc8b6e1bbe5bc8731af253337a57ecc4a2432182650f85a46a97e20f780808080808080808080b8b3f8b1a0922c98754d7ef4b203da9439946a6f7aba8339eb4f065cf83200724d36a9e86380a0437d659b7c49ce690feac212b95ebf84253c55aafc410c3b61321ee11a5d83358080a02eed03a131ad24ed59f25a4b433b0a39e6f3e5e95bc7a0b663c9b6edfae9e47aa0b07d0b40ba348e26858be73fed53d3a6e439c4d05a40e04c7fd53167c8f1d2948080a0f7d7d33621813da6bb91701839fc79fd6d261b2a907a43106d2bc978481238a080808080808080b885f883b83f206562633864376331633237656437393930613731633839656164323463636431343836336662626466336662356462316339313632636661633436663833b84066623237633466393532353865363964303232623963373766616132643166356339643030336233616365306662353264373163613635393263326666303134",
"0xce74ff675fd0b952ecb3f02f5360d50d1b96254f21d0930f2ced2f328553f972"
],
"out": [
"0xce74ff675fd0b952ecb3f02f5360d50d1b96254f21d0930f2ced2f328553f972"
]
},
"arbitrary update (256 nodes)": {
"in": [
"0x30653837306437643232636366313635333231323139333737396537316666376634373930303139626533613839633037616138343262653134643465363937",
"0x39616533313162356138663533333733353135323439383231386663613165323237313763343764326463366135663738323539316433663462326434326134",
"0xf903d5b853f851808080a0939d6c424a8898660e415e2427e923f6f825296f7d2d03a7e870f4de13bdc8248080a09d9ea16458b048e853ee27c96b095519712020e617aaf03de69c71a19850287880808080808080808080b90154f90151a060e0aead56eb92bea0b9233e611a141493ee03864a5b46b54ead8cf4f3fafb41a0275c4007dd73d30b8290c99035cd2d72e6d9a652853253b8176be4eaa6ce03a9a0ed1f9432a10f62ebdf2748baecdbae01df7e4b72b793692f5b46ccb1b41c081ca01f2a5f3f5c4b597bf354e84a8ce80d9a4ffd274045a06ac636e1a394b877aed0a0bd04555f2a1b7d5dbe5b0fd869b9d2d37374f2d23e4ba4e4e695c173614fcf51a0f238e46cad89131c919d406183ef03ed46231a257231bc89bb640af0868768bca0973f643ff33b27848bf26f2d0d3988c05105715c00c2db106fce906983e62ee9a001bdf81f3c1c1bac6428259d6d4e0edbdd8ceb7c1d14866125a0036def676d40a0d8926874fd8a0e0ab8d46c4407ead6c055444c548e8cc4feca97d4a9bfc65f0ca058fea35b638a9b061e597f1ab17820a04c67436c64c575e9d4d3a50c4209ad5980808080808080b853f851808080a00d8de33b14b40038395424871f1daaeed399dc5ea7873b16fb56fab0beb68c9e8080a0443a68a5b803a8a34906d8664c759a4b00f866ff2d78af2298b110b96884ce2580808080808080808080b8b3f8b18080a018c1c3076c61714d6dc546ac283e35b5876708f8162559b5054e902975436a41a018085b2e94545aae48c1ec8e972ca02c8f6cded9d2f6033c1b0209ad20ff4be2a02cbfcfa4580c95efc154891b19b6458f073126beeeee7e1fb0c232e9bdb7839ea0a862ecc9386c6d0fcad6fedf47ad8c15ee45a88e8a031a6320f7bb22b6bd3ab7a08687183169c39a78988413c75facc0424a563312425ad5249c1bd865de459d4880808080808080808080a3e213a0cb71f0cc92c51e0d8eb9dd47e461f2077bfbe01f2125f181a69ca866f131f0d4b873f871a0d6883f50188ca6cee1d5bce7f2deaa67b04a9c82606f88bc7b597866ecdd41878080808080a0bb16a4c9def487361c336de32752a110a711dda21c1155663772db84392b085e80a0d7a33b3192a85c741c3494463098dfaf7f342ea1def97b44be03091a4e1cf9b68080808080808080b884f882b83e2037306437643232636366313635333231323139333737396537316666376634373930303139626533613839633037616138343262653134643465363937b84039616533313162356138663533333733353135323439383231386663613165323237313763343764326463366135663738323539316433663462326434326134",
"0x1d1c6d6618a09e6d00460ecbb34e07344c1428ada1b33d440e336ae18da193e1"
],
"out": [
"0x1d1c6d6618a09e6d00460ecbb34e07344c1428ada1b33d440e336ae18da193e1"
]
},
"arbitrary update (512 nodes)": {
"in": [
"0x62663635326166303465303333633037373634623665646536643637643936393733393364386438373661656433363833373437393933363536303732366134",
"0x34333837346462663832303033646432306561393631613730666336343163653035303761613539393830376262353565396138383631396231373133333065",
"0xf9032fb853f851808080a0172aa06a9c3bf30cc3fa2521909faa0f755519d56eacdf0dadae12ab4b9eaef88080a0ca59486747b7dd466a0059a2ba4ceabd531192e18c460ac60132b56cfc8a48c080808080808080808080b8d3f8d180a05df972283599f8ffdcb8f9d003bd1aa859942764b1e5db1613d914e16ebd122ea0d57d611996f626f1da73a876f1db74d44a1467d20357247c31c8619a903674fca046bb69112b28082bc8fae40d752b083d7ec3103aa1abf0ab036c961db41ef0f3a0ebeac2aabd3939a84e8a8f4647b27f02d4f6b6df962f5b350282bfa9d291773aa083d6cca4848f341a8003764420b2ad3605425cc23d12afcb65933ab606f339cca03c23d875a3225d63d85ef83fc999121284f31889d8201ac0be9cb1a8d5cd073d80808080808080808080b853f851808080a02a991efab0bb245d1d8908fdb29c9aef8243378f9fb22ea5861b35e355ddc2d18080a0a66cfb941cb9f47af573f8738cd2a56a625392de974e5930e24594e9f258714980808080808080808080b8d3f8d180a0a1e1cf55385e1b6da7cc2fb7aeb59c766f154223fd8821a1914ecbc5927f72f8a0b947c9b788bd2f0ae8f3ffa4078721d266ed88ddda976b66199d9a7d1aa2068fa0d4306d3c5bee7448422edc43f806365de24f17a6c6a0e17e1b3260454a23b9f8a0cb1420601892d3ae953e17cd628428766ec281cc442720df72b6b03a648bea2ba07885db0751e3008e64b587a095c99fd6673f189a23cdd818b7d89943aace6984a0b64746e1e804b6c746ff52316a8428ee3ddcb9e6528b5fc7d5e13e71b22069e680808080808080808080b853f851808080a0d12e64290951bd56fa8626a63e05bcf239a0225d602dd9b9a7e478edb77228428080a00471402a244af307ccb5ee16d236b0278d8c668eb80b7c438bbe35e62c1a5abc80808080808080808080b884f882b83e3635326166303465303333633037373634623665646536643637643936393733393364386438373661656433363833373437393933363536303732366134b84034333837346462663832303033646432306561393631613730666336343163653035303761613539393830376262353565396138383631396231373133333065",
"0x922b383ea8414274391a09d26e26862bcb4018838878177f909e7578486d4101"
],
"out": [
"0x922b383ea8414274391a09d26e26862bcb4018838878177f909e7578486d4101"
]
},
"arbitrary update (1024 nodes)": {
"in": [
"0x63633939363830316465653630663865353732336635303766613037646236653930643737373566366665623564653232346136313762393533333561663861",
"0x34386665633731636135326230306266316233333262623263303961646137353736333635656165623462343663336431326665346134333763336132636339",
"0xf903d8b853f851808080a07dbe425836ecb64269b04bd8bdaaf162e7dc011bc545ea3c114924791b9715f38080a05daae9e121770c2ce2c8aaae5aef8294266cb421e7394d833973b30d292476b880808080808080808080b8d3f8d180a0321c3ed3b4591371add24ae89ac39364c90085e572082704d679d937b8480b0ea08ee53c6695830154881b03611e3b479c095e010c54e4d2f0d98803242beef8eaa07da013493bb886430b15d341bf459fd8af42367cf7e4f86d9f6a3287704008d0a0b2b02fa967f822b5cb0a99274be4064933cb1b51489298767acd3b1d2d17d869a000b574b33dce2ff6e2834990bfffaf726fff5e66a639510bf85db62b9f72a757a00325ca019c291cf1d02b0b55808a12e248595a94333fe0c20a5b0917964fdf9080808080808080808080b853f851808080a0aec555ba5424e2039fd0fab02bc307a75d3295a79c1f90c05bd9259781b2c1478080a09de84124a9512c6d0dcecc7693c1c71e7dae4e87ba93cdef66120a0f34e2165880808080808080808080b8d3f8d180a0fd5d7c497457334ac50c181c07640067cb02623a774cf3043c6fe6444f54425fa0c775c400a320fbedcce51129dabfd3b76495a644c7d0e83a59c14610c1e47ef8a01f30ff4af3bf01e544840ced373297840864672ec1bea4fe3125878ecf7e97d9a09015fce5cfd1a7271c3d3768be994cccbc8d750154c8bc2e0ce0c3ff4ef9386fa00f087471655a490fe86f60c824f47b25fc607dbfe83a4f987f028ac4eb03a3c1a0b72b82b32748b14079f21520ef9a27290ce7064411664f1ae88f5d9e6d45494480808080808080808080b853f851808080a0657b5ebb555e7d04261deefcde723bcd744c85ac1f887acbec03a315215ab5aa8080a0f244b0b57ca617ab32e2b190a9499040e6a98e2e58ee481d89ec9eaa110c5a1b80808080808080808080b853f85180a01275e04aeba9c0367572783ccb1561695d264293a3bc337fb712bbd58efa14f180808080808080a0c709e24f4afc4d46c3412e18ccd20cd1bf1da620129c42da1938b05c7276d19880808080808080b853f851808080a044f42acab8ddedef537f8b1f56c38a38d4667d3a341503eacbdc46386eb215d48080a0c19dc41cabe37a3da398a2d46ca409803cf77db8b7bcbd6acc90f00f8ee9e0ab80808080808080808080b883f881b83d39363830316465653630663865353732336635303766613037646236653930643737373566366665623564653232346136313762393533333561663861b84034386665633731636135326230306266316233333262623263303961646137353736333635656165623462343663336431326665346134333763336132636339",
"0x7cc1d9e4349a14570903256d0662d5c7e26259c23fce53d4e0d1d05b79144651"
],
"out": [
"0x7cc1d9e4349a14570903256d0662d5c7e26259c23fce53d4e0d1d05b79144651"
]
},
"arbitrary update (2048 nodes)": {
"in": [
"0x63616265366136313331376466623239383931636136363563353936643366386534323935336665356530323365356332396163633134653833393030303033",
"0x63303132633333643333393163363537396131383232346564316331356531613935353833333234303032616137383065333632356533393139306238643265",
"0xf903a4b853f851808080a06b1ec163d36f0660cab4ab85a101a2dd24bfa2658e1b722a3a0e3f40ad06a2f28080a05a944280b38ede1983f3dab5166cc620b846e9d3e8425f7d81ce610dd496063380808080808080808080b8d3f8d180a0bfc332079e121621b6a79d574595cca74cef134939aea106bd56202519ebf5baa0b9866e81a81052c8b5f57949466726518aa49ece30ea07fdd5d2834fcfe9676fa0544fed534ae1e285bf78468daf73b18e06fe3af92e30686ddaeae6e2d09642bca0d5227397e6129b675f39f09e9efbc654bf4ff566111be6b1c189c85f9684e86ca0f2ed72bcc8939e9671b1802de95264bccfb9677feed79c9c389191aa2fc1dc72a0d1384e17ccdc5b370fdc94c137a95569b5cd46847499c755f2d269b2dbbc20bc80808080808080808080b853f851808080a0d6d22f3b60400e4091958d2a9e0481c28a5591cc84877c1128ed37bd005fbc8f8080a05b56153cdf09797a3b4c87cadb4d08ba274d864abbda957a2d6320d6ed17dac880808080808080808080b8d3f8d180a042746ed1a4d5569b703154c91a201a1691f76794777cfe693ce357b529f47e16a09a7077c59c45ff2d95732ce9198404c9bae5c996e44271ef7f40b42b2aa7337ca0a5c16713226e147008cae877e7561e3fdd05872e96c729f6cd95f35b272be1cea0790fd15585bfc861cea60558e356f1a80f6da67e21d9b0b89402262d1bfcc585a05a03571e90510329c97a3b2a7720d14851a21b8972e97963c053af4e4e0d1a9ea08d0005d1533fb093fdbad029b4528e50aace6721d9810689d085586770242f5380808080808080808080b853f851808080a07b40b3c18f9cadd46aedac7661cc01579ec5cfe9e60b568cc79ccd84e4b81c7e8080a009e603f66a4b102b5b3c2525fc158ecb695781faba4ac01c5ab20c0b1686722080808080808080808080b873f8718080a0de8f63df18f1f49de180b12a0ced021aa75bc705395bf23f2ca2357c24c6e98580a06ee2f7499d6e5c9e5ee5529d4d40efd76ba7371648816da6c2cedccbfc014e6380a01f54a437431e714f7f9c3c0f79def239851df7d89f9e4520e3dc02bdd349be8180808080808080808080b884f882b83e2065366136313331376466623239383931636136363563353936643366386534323935336665356530323365356332396163633134653833393030303033b84063303132633333643333393163363537396131383232346564316331356531613935353833333234303032616137383065333632356533393139306238643265",
"0x091a8393aaece43e0f6efb3977f15fc6f86709cdd6f8c2ba9245ed2ba841a329"
],
"out": [
"0x091a8393aaece43e0f6efb3977f15fc6f86709cdd6f8c2ba9245ed2ba841a329"
]
}
},
"verifyInclusionProof": {
"basic inclusion proof (node 1 of 3)": {
"in": [
"0x6b6579316161",
"0x303132333435363738393031323334353637383930313233343536373839303132333435363738397878",
"0xf8a2a7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080b0ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
true
]
},
"basic inclusion proof (node 2 of 3)": {
"in": [
"0x6b6579326262",
"0x6176616c32",
"0xf87da7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c33808080808080808080808080808bca83206262856176616c32",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
true
]
},
"basic inclusion proof (node 3 of 3)": {
"in": [
"0x6b6579336363",
"0x6176616c33",
"0xf87da7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c33808080808080808080808080808bca83206363856176616c33",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
true
]
},
"single long key": {
"in": [
"0x6b6579316161",
"0x303132333435363738393031323334353637383930313233343536373839303132333435363738397878",
"0xf5b4f387206b6579316161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878",
"0xf838216fa749aefa91e0b672a9c06d3e6e983f913d7107b5dab4af60b5f5abed"
],
"out": [
true
]
},
"single short key": {
"in": [
"0x6b6579316161",
"0x3031323334",
"0xd08fce87206b6579316161853031323334",
"0x37956bab6bba472308146808d5311ac19cb4a7daae5df7efcc0f32badc97f55e"
],
"out": [
true
]
},
"key in the middle (node 2 of 6)": {
"in": [
"0x6b657931",
"0x30313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67",
"0xf90103a7e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779b873f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080b864f862808080808080a057895fdbd71e2c67c2f9274a56811ff5cf458720a7fa713a135e3890f8cafcf8808080808080808080b130313233343536373839303132333435363738393031323334353637383930313233343536373839566572795f4c6f6e67",
"0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89"
],
"out": [
true
]
},
"key in the middle (node 3 of 6)": {
"in": [
"0x6b6579326262",
"0x6176616c33",
"0xf8c9a7e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779b873f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080a0df808080808080c9823262856176616c338080808080808080808573686f72748ac9823262856176616c33",
"0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89"
],
"out": [
true
]
},
"key in the middle (node 4 of 6)": {
"in": [
"0x6b657932",
"0x73686f7274",
"0xf8bea7e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779b873f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080a0df808080808080c9823262856176616c338080808080808080808573686f7274",
"0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89"
],
"out": [
true
]
},
"key in the middle (node 5 of 6)": {
"in": [
"0x6b6579336363",
"0x6176616c33",
"0xf8e5a7e68416b65793a0f3f387240403976788281c0a6ee5b3fc08360d276039d635bb824ea7e6fed779b873f87180a034d14ccc7685aa2beb64f78b11ee2a335eae82047ef97c79b7dda7f0732b9f4ca05fb052b64e23d177131d9f32e9c5b942209eb7229e9a07c99a5d93245f53af18a09a137197a43a880648d5887cce656a5e6bbbe5e44ecb4f264395ccaddbe1acca80808080808080808080808080b83bf839808080808080c9823363856176616c338080808080808080809f313233343536373839303132333435363738393031323334353637383930318ac9823363856176616c33",
"0xcb65032e2f76c48b82b5c24b3db8f670ce73982869d38cd39a624f23d62a9e89"
],
"out": [
true
]
},
"embedded extension node (node 1 of 3)": {
"in": [
"0x61",
"0x61",
"0xf8389ad916d780c22061c22062c220638080808080808080808080808098d780c22061c22062c220638080808080808080808080808083c22061",
"0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978"
],
"out": [
true
]
},
"embedded extension node (node 2 of 3)": {
"in": [
"0x62",
"0x62",
"0xf8389ad916d780c22061c22062c220638080808080808080808080808098d780c22061c22062c220638080808080808080808080808083c22062",
"0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978"
],
"out": [
true
]
},
"embedded extension node (node 3 of 3)": {
"in": [
"0x63",
"0x63",
"0xf8389ad916d780c22061c22062c220638080808080808080808080808098d780c22061c22062c220638080808080808080808080808083c22063",
"0x72e6c01ad0c9a7b517d4bc68a5b323287fe80f0e68f5415b4b95ecbc8ad83978"
],
"out": [
true
]
},
"arbitrary proof (128 nodes)": {
"in": [
"0x62303236303063643530623533393762316233646561653437336538353661346435383763623634643436393830656434333061343832623832666635343139",
"0x64326331653939666237663661333132666364393263393738366164313935383236333038323066353934616435626566376363643133343463366363663866",
"0xf9029bb853f851808080a0263d78c5fd9968de40bbf3c9e54e46473ef873a6904ddea719e7c3d3dab8add38080a065ee105383f2f9afd87c32dff662715552f56e99619a6743e09386cf62f17fa680808080808080808080b8d3f8d180a0451fb51c00ca685f7a3b19c044491cd8e574f5a971b379249f3cb7a42aa2a13aa079c1b33a8132befd9ee33339a2040bffa955f2d024f81e9c8f8c10401ccbe294a09d80ad4228d7197dea4a8b18f7a99d34f28cb0ac1a5836a7cb93ffbaaf941464a08a56e14745b9622dbc8e80a33e1218e44b16860fd58f951610b963ee32462990a03f7186d3342a4a4084d1e8c22a40675a9df1dc130bd7a31ce2f89fc659de374ba065cbb9b66782fa5c519b78c5b2261ad005c47075b4ee8c08bc71255a4944027680808080808080808080b853f851808080a0e70153be669d9e0419001376857985895f1485f277d814fa41b6171038cae59c8080a01f76b2175e50963b4c2f5f8897eed7a3829cd0727d198138cf723b72ca3468f780808080808080808080b893f891a04ffa3d1d0c9eef905cf8cb924fe74c43715aa85c26c116c91a45e3599ef21e75a0c9b0859699e3d7f8367b4ca50f2b08acf1eea13d1dd0bb9b4155c4f67f4a5eea808080a0abe45f156c2bf6c743021a1aa9701ca27d384413bb25207685e3702791946a5f80a0042d75b1c061f41dcb5589780712929a0dff5ba1574a00fc6dad0ad3b99aa307808080808080808080b885f883b83f203236303063643530623533393762316233646561653437336538353661346435383763623634643436393830656434333061343832623832666635343139b84064326331653939666237663661333132666364393263393738366164313935383236333038323066353934616435626566376363643133343463366363663866",
"0xf450a6e84cd1e88c4736f19e62a46441d7e278d2be7e8031b892c20fdd58d8f0"
],
"out": [
true
]
},
"arbitrary proof (256 nodes)": {
"in": [
"0x64323930653331633662626339626130366139636465396635613463613434653737376133636237646165633937616432356661366264306536376431656539",
"0x36376538393266633931613736666130353365653138653439346565626339333231643936346438643166353630373436336565623334636435346665653938",
"0xf90373b853f851808080a0e82a9307013181b63bc631d9a72d8614ef53e14f57e7057ea40248fd0365716b8080a090721eb78858d84cfac57acc5fbe94ae8dba37b4d07c3e32e41929e20d793c6b80808080808080808080b8d3f8d180a0e8c88de9ecbbf4e12cc6aea87816733a25b50897cce68b04586dda7f69de71cca057b16f8b274f592ce9b76dd99444c506c554ef94e89abfc3f494c2c107402825a0e872edcec2088c1b0e28df3c238dee6326f36f2e6433dd6ba19cd1bc87631e5da041aaf5bd0b0f34049bbdbf1075ed79172bfaa5fc01002172fe58fbe7e2ccc6efa0a3167dd56c5070e353a8916d579f925932014ea982310e518d1916135671cc1ca0bf01933a5eb008945c734b8bd48b63177e9ad957bca3d676ed5eebfdb07367fe80808080808080808080b853f851808080a06f261637fdf4fd2ab7c63f93277ca37890e77c78ae8b132be882dfaf9b6293478080a0ab64547cb8ac7ee4550faaa792bdc6a906765b13c05edca5278ec6f34334f14180808080808080808080b8f3f8f18080a065f9749a6a0b992f5a4353e371d9c63d91648992b1eb6ae01ad8f62c965427a6a09512ebc2ead7a32b012bd5c72415541e4f90ffdf9549a96d884f47c9f2383937a06d6aa51d8d27a8cdc37115bfcbad5b489b95765d153594d77b25c41f7541223aa002554946d309fd21844d842c39e46f093e785403a46afb6957ab397b86c18f09a0a2d639fef7fb5dd52c7a2f3eb0703a0feb0558c524cc143d15ff9825c2c0b484a084f5a69d626b19ef0ae2705491bc237e4745d0d4cdd33a7dc3d1382a6eac0a6c80a03fdb322001905e71930066f5eafa499c9a5015db3a05be5d18ae8c2f46871dc680808080808080a3e213a025e631c84989b7d4360ca2eacc18f8e5ce6ecebb6d46ec6ed90e6c1215a0d53eb853f851808080a01cf50a2d534c03dd42e42986faecd8eb25f414d8e95c43bccd93ab0156f1948b8080808080a0b937b43f8140aa909ee07e2926df642ee3fd037391251943e68d7f3e8a45b10080808080808080b884f882b83e2030653331633662626339626130366139636465396635613463613434653737376133636237646165633937616432356661366264306536376431656539b84036376538393266633931613736666130353365653138653439346565626339333231643936346438643166353630373436336565623334636435346665653938",
"0xd4c61c8eac944a1efd2add3ae58fae739e125fb20eedd6982725ae28e2dd8832"
],
"out": [
true
]
},
"arbitrary proof (512 nodes)": {
"in": [
"0x30643137666135653037613430366166303734353434616163373133393434636366316138333863336261616530653236643533373837333566383931303664",
"0x30666464376438333431346665323264383534636665306232353031623065613864633337626639643738323765366265373631376333616138666132656362",
"0xf90406b853f851808080a0986c43ec04f20a5f840376e88792825cc36ed22d667afc8a4de8ca51a800ff9e8080a09e30593085f4b2f9105fcbab1535fc3830f002f5cce6cfdb28bb47242a5eb0d480808080808080808080b90154f90151a0c3377f117808ffda9540b34bc2462fd550460a184702a0d2b9bb1c08cb1911b2a0fe5312e04360355ebe6ea01af3c7be6330d9bd830921fbb1c00bc9eee79d01f1a07426a671125a91fe569577350bda466a176b86974a2da7fd5a5b3727cb193adaa0b941e322b523b68ae87d92da26e10118db53eb21e73b22d13a27535950bc327aa0244d5539892b472b1b0e42307b2bdf37deb8f884d5e409e562c877d359e5508fa0386c39ea3a957fd00ec258d8544fa27ed0efcb0710b874ba426373327fcf862aa00eb8c7848c95e74162d0418fa2efe365d1403326d52213790f9986b03685021da0fbabd66454942ba322cf8c3f3188cbe6cfc49d7de84068e3badf309bbe315e87a04a6ca2da03c5336b71f0281e4d4e0028a0a9b5cd10abc1fe966f11f6e260af75a0e6461917b4d216eeb2a47dc9ceae5f0d6bc5ee2778749b4edfad0c20e2be1ca480808080808080b853f851808080a0074b266998de98a026f62521d89dbda085bf10e7e1a461fc68f8740800166d738080a010e6611a79918c6e72cb8febcef11148b099a3bf12d8b849176d891d5d1b27da80808080808080808080b8d3f8d180a00e77c34d01560ddc1f0bec7821ce90d52f7d1155678fc0e4ce8be101abe94950a0e1bcc7aadf8bfa98a8d62997aee2eede55b84e056c56e85cc8e34658c79f9845a04ea9ad8b927af52ea15728141ce4209af93e521cf85a5c30c0d3578bf50bdda5a068c96643aa80297b7ea04ba70b40faeb39aa9b600f066c6c21c4c616aeb7f579a0813ed83afaaafabe055a27a2ca52826e9afcd95a700d55c24472a72486b275cca0b3c8c7ddf792c658c18b6da0c43f2381e35c995544402127de457ad9a69c4cc980808080808080808080b853f851808080a0e3bbd8835493be2266c3a4f4603a3f8318a4295e8f80d3b92b58b854f9f217998080a04b84bac7ffc30073a283ab3fd8d1035225fe2a670f3bc8da6633da2107a6ea1980808080808080808080b853f85180a04864ba68ed6e2baf1614729de3c40162608039dd1a001f4e64f248255a747bce8080a09d6fefed58a095129b74c1e79c16178d14b67fc1f6f82e9f43d9dcda0a9c8b2c808080808080808080808080b884f882b83e2037666135653037613430366166303734353434616163373133393434636366316138333863336261616530653236643533373837333566383931303664b84030666464376438333431346665323264383534636665306232353031623065613864633337626639643738323765366265373631376333616138666132656362",
"0x875642b42ff718ca2298d5c24e3129e470275f7f1bea5e756a620aa6f84d7172"
],
"out": [
true
]
},
"arbitrary proof (1024 nodes)": {
"in": [
"0x30613131623633616333643537616662626264643239623066313930663635303161353939646639646338383865326566633662623734326166393731353035",
"0x38303830666232376435303134393465376330666466346633323437396139656638326564383332616337383036646266303665616338353965376230666133",
"0xf90426b853f851808080a0d4e608f94f154c1086f14a3d0888aed6b264db44e295aeafcffec7af109cb3378080a0f35bba5f59720501bc9322f7489dd67e6e7d3182f3a0803d58881ea678c51a4580808080808080808080b90154f90151a0aca67bc56654411de846fb02d7fe66c3834d03519b0f58ecb86ccccc17dc1399a0a9856669cad391a03c193ec6dec2bc15bbcea1acff562aa322181d34bc15eae4a03ec4276daba3e20c341125fd1c239a3a59c68eaa8e662e04da9ee64555889b1ca0e53bd7370aab8439016df7bac1123e86aaab5f7d5fd7f70af271ba448716f627a0c3c137d47a74805600496927e626ea4e79e2abeb2cb7f24a746d9662de860693a09cd8e70d490b419266d209ca8830451e80a35378a57de1a3261c29f36a8ad480a02eed65535212cbad5b39bc59f4cb452839b94e15d852437c9b5075ab34ed78cba07137faf42fdeca8e0e6cad69be7a5d3b29dad2b5f881eae0261106f5e2afb017a0b0900dd08af215ddf59cb4aeff3367d4444bcfec999dc1241721500347dbb7dba03c57e508e13cd3ffec967ede493c43d0563eb2c67c4667bff443ae2546b75b5b80808080808080b853f851808080a051e8a2f385000faf1d92de1b23944ebd993dbed3b6b2db2c20a489a953c3f0828080a0760a75a384b342463c2c480a7875f967b8e2d664449b929cf2e4b1b884adb46e80808080808080808080b8d3f8d180a0ecb828ea580e16d237d4434fa01cd0712d6fda158bd8dc12a44d43736093ca80a02c3e341ba7cbb05876636d05ab2e0374f59b92fe21dfe74309ce1fe56edf692fa054a1b2ea1e057917e392a0c2c429e6b031c3f4a3cd1d9c36f2c45875ab6dfd25a007b648f34e53427c6770f1c556945d34f050f07a14f900fb852e7c514b45b068a0d4687eaa067aa1867147553a6dfc8e9d18c4afac87d44da258ecb35e5f96d89ba0d94e3a9ca51e70cda51dc56181afeb455774020367b71bc2d443c68cf563d6ce80808080808080808080b853f851808080a0185913e6e8315626922bbda00b2bc25841199d74af4083112ec596c446a3f1228080a035640fa9723db26d80b30ddcfca810e4782bb9f15a623d22050c443483ee653180808080808080808080b873f871a04f84c13bcdec814ba4ca136f37f40cb23ec1243577d2c0a06cc09bc8451e58e2a01544eae89eca15f429e589675458d781bcb94ac146fd84b3753acd5f255023c580a0bfcff9408e67a35a633ab460d44cccae0588ff8fccd0ae52311d55bcfa9ef57280808080808080808080808080b884f882b83e2031623633616333643537616662626264643239623066313930663635303161353939646639646338383865326566633662623734326166393731353035b84038303830666232376435303134393465376330666466346633323437396139656638326564383332616337383036646266303665616338353965376230666133",
"0xbe40ba4e41f77aa0c9760c2632971ea92b6c2ddcab3ba6939ab3f644aba1d0c5"
],
"out": [
true
]
},
"arbitrary proof (2048 nodes)": {
"in": [
"0x39633962623638323335393839323064623565323666306633636437626665343137366232343163383963333565373061323134373033643136356361616466",
"0x64393730343035346366613034306461346630373835313765316164363863336535316130336334396565373664396532393863396664656665663238333634",
"0xf90446b853f851808080a047cb3fcbe8077e8b5ccb4bd11d4e0385d26d4787259fbecd00406f4e4ceaac3a8080a04e1ee8279d78768445fdca4279172e63bdc4fa45ffe4793833e742dd532f7b3280808080808080808080b90154f90151a085f4a041e77f796039ac0e9b9ec972c7844dceb86b78e0d4d375d23497f67571a07fc1b9fba3de725d8419c6cfdc1c18c881800b320a4f197d944f8aefdcacb839a047b8c3b56ce6ab98642a461be1e87a09670a0e5b10766c11628e4aed02e58d96a0fa9f4f1db6f160f63ad02561c84c2926c0f91e28d592b7e5f25ab10e19247b00a0efd94cabb8fe54c224676c4a2d3fdaef7f797730aff42f05332b9897ad42b7fba0133ecca6da5528773f28e5640bd73c93215158193e5fcd5f57b40bd14cbee2b2a01d3919603586ebd347a0fbd6309adf42915432af91b6e1db6c49d25670754d6fa087b9cbe0cd61776540a84140464b7ba454009f2c18c828923145c419df478364a03a8b63739f9b25d5ec9182054c2511101152c5f7a0f4691ff7a014271c576fe9a082e004fb330f1e80956d1ef078f20efbec693528966d39f5a43ed12db482ef2c80808080808080b853f851808080a013d63cdd329388e9ad63e9e463355ef3f7bcc934aab10df83d0a92c6c0df99248080a0b9200cf83d6c887765012fa60ef295ad3394e34767e1f36dce1e951f08db820880808080808080808080b8d3f8d180a0047ba91080246e4bb0d7b8d6293449da0c4d04547627ffba0c73d9b36c0fc3faa0544c5e09b3c8e026b6752c057796e60978551d6ce77ccb6d26b71541cbf0ca13a02acf313da117de9e79c9fa88722d3146b240fafee0e4b37e8d1d2b4335d3c69da03f3ddc358c86b9b6ee2ba6eaa060ff3ed101626d26fcf25b9aafc867ea3b7bf5a0b65f0b79df2b27069da6070228c218026d501bee60b69b77c370b7450f027c87a0f659a7dea2ce9afe7753880268fbc913caf6d3fc4026d80934761046dcc2920b80808080808080808080b853f851808080a01c635a046d3838114189b399619b8f7d3bd0efe01152ab66a0d84be2686da2d28080a0fb27c1c13e354fe60d19fa2e7df2ea4688c656f4a6303445802e5dcf5fbdd8fe80808080808080808080b893f891a06740882da49a2e1ff126e3ba6fac2d2bb7d6dc8275585f3ede5b64c58bda2b338080a0402217be9e51170cd6a8a04dc94c9d0e8f8bb6c11f8b47a912334c1bba1653e6808080a0f3ef10a49d2164f97ae2fd436ec32ff14158ec1d3a435ac7a57b4388d8a43af680a06d650f375a4af0b5098322bb24a7cc880009bc7d1cdc5e829acb57f88f1f1e7180808080808080b884f882b83e2062623638323335393839323064623565323666306633636437626665343137366232343163383963333565373061323134373033643136356361616466b84064393730343035346366613034306461346630373835313765316164363863336535316130336334396565373664396532393863396664656665663238333634",
"0xcd3b3e76709fd984090ceffa27db7ece94d425d044bee7c68d18b03234915f94"
],
"out": [
true
]
}
},
"verifyExclusionProof": {
"existing key, different value": {
"in": [
"0x6b6579316161",
"0x6e6f742074686520636f72726563742076616c7565",
"0xf8a2a7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080b0ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
true
]
},
"non-existent extension of a leaf": {
"in": [
"0x6b657931616162",
"0x736f6d65206172626974726172792076616c7565",
"0xf8a2a7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080b0ef83206161aa303132333435363738393031323334353637383930313233343536373839303132333435363738397878",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
true
]
},
"non-existent extension of a branch": {
"in": [
"0x6b6579346464",
"0x736f6d65206172626974726172792076616c7565",
"0xf871a7e68416b65793a03101b4447781f1e6c51ce76c709274fc80bd064f3a58ff981b6015348a826386b847f84580a0582eed8dd051b823d13f8648cdcd08aa2d8dac239f458863c4620e8c4d605debca83206262856176616c32ca83206363856176616c3380808080808080808080808080",
"0xd582f99275e227a1cf4284899e5ff06ee56da8859be71b553397c69151bc942f"
],
"out": [
true
]
}
}
}
}
\ No newline at end of file
{
"tests": {
"toBool": {
"input bytes32 of 0": {
"in": ["0x0000000000000000000000000000000000000000000000000000000000000000"],
"out": [false]
},
"input bytes32 of 1": {
"in": ["0x0000000000000000000000000000000000000000000000000000000000000001"],
"out": [true]
},
"input bytes32 > 1": {
"in": ["0x1212121212121212121212121212121212121212121212121212121212121212"],
"out": [true]
},
"input bytes32 > 1, last byte 0": {
"in": ["0x1212121212121212121212121212121212121212121212121212121212121200"],
"out": [true]
}
},
"fromBool": {
"input false": {
"in": [false],
"out": ["0x0000000000000000000000000000000000000000000000000000000000000000"]
},
"input true": {
"in": [true],
"out": ["0x0000000000000000000000000000000000000000000000000000000000000001"]
}
},
"toAddress": {
"input bytes32 address": {
"in": ["0x0000000000000000000000001212121212121212121212121212121212121212"],
"out": ["0x1212121212121212121212121212121212121212"]
},
"input full bytes32": {
"in": ["0x1212121212121212121212121212121212121212121212121212121212121212"],
"out": ["0x1212121212121212121212121212121212121212"]
}
},
"fromAddress": {
"input address": {
"in": ["0x1212121212121212121212121212121212121212"],
"out": ["0x1212121212121212121212121212121212121212000000000000000000000000"]
}
}
}
}
{
"tests": {
"concat": {
"two non-empty inputs": {
"in": ["0x1234", "0x5678"],
"out": ["0x12345678"]
},
"two empty inputs": {
"in": ["0x", "0x"],
"out": ["0x"]
},
"first empty, second non-empty": {
"in": ["0x1234", "0x"],
"out": ["0x1234"]
},
"first non-empty, second empty": {
"in": ["0x", "0x5678"],
"out": ["0x5678"]
}
},
"slice": {
"start zero, length = 0": {
"in": ["0x12345678", 0, 0],
"out": ["0x"]
},
"start zero, length = input.length": {
"in": ["0x12345678", 0, 4],
"out": ["0x12345678"]
},
"start zero, length > 0 and length < input.length": {
"in": ["0x12345678", 0, 2],
"out": ["0x1234"]
},
"start zero, length > input.length": {
"in": ["0x12345678", 0, 5],
"revert": "Read out of bounds"
},
"start > 0 and <= input.length, length = 0": {
"in": ["0x12345678", 2, 0],
"out": ["0x"]
},
"start > 0 and <= input.length, length = input.length - start": {
"in": ["0x12345678", 2, 2],
"out": ["0x5678"]
},
"start > 0 and <= input.length, length < input.length - start": {
"in": ["0x12345678", 2, 1],
"out": ["0x56"]
},
"start > 0 and <= input.length, length > input.length - start": {
"in": ["0x12345678", 2, 3],
"revert": "Read out of bounds"
},
"start > input.length": {
"in": ["0x12345678", 5, 1],
"revert":"Read out of bounds"
}
},
"toBytes32": {
"input.length < 32 bytes": {
"in": ["0x1234"],
"out": ["0x1234000000000000000000000000000000000000000000000000000000000000"]
},
"input.length = 32 bytes": {
"in": ["0x1234123412341234123412341234123412341234123412341234123412341234"],
"out": ["0x1234123412341234123412341234123412341234123412341234123412341234"]
},
"input.length > 32 bytes": {
"in": ["0x12341234123412341234123412341234123412341234123412341234123412345678567856785678567856785678567856785678567856785678567856785678"],
"out": ["0x1234123412341234123412341234123412341234123412341234123412341234"]
}
},
"toUint256": {
"input.length < 32 bytes": {
"in": ["0x000000000000000000000000000000000000000000000000000000001234"],
"out": [305397760]
},
"input.length = 32 bytes": {
"in": ["0x0000000000000000000000000000000000000000000000000000000000001234"],
"out": [4660]
},
"input.length > 32 bytes": {
"in": ["0x00000000000000000000000000000000000000000000000000000000000012345678567856785678567856785678567856785678567856785678567856785678"],
"out": [4660]
}
},
"toNibbles": {
"one byte": {
"in": ["0xff"],
"out": ["0x0f0f"]
},
"two bytes": {
"in": ["0xffff"],
"out": ["0x0f0f0f0f"]
},
"four bytes": {
"in": ["0xffffffff"],
"out": ["0x0f0f0f0f0f0f0f0f"]
}
},
"fromNibbles": {
"two nibbles": {
"in": ["0x0f0f"],
"out": ["0xff"]
},
"four nibbles": {
"in": ["0x0f0f0f0f"],
"out": ["0xffff"]
},
"eight nibbles": {
"in": ["0x0f0f0f0f0f0f0f0f"],
"out": ["0xffffffff"]
}
},
"equal": {
"same inputs": {
"in": ["0x1234", "0x1234"],
"out": [true]
},
"different inputs": {
"in": ["0x1234", "0x4567"],
"out": [false]
}
}
}
}
{
"tests": {
"recover": {
"standard hash, valid signature": {
"in": [
"0xf83d80808094121212121212121212121212121212121212121280a0bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a6c8080",
false,
"0xfc",
"0x057bf1c0edf0a9002a79f8c9b39683f6453a18e73e02364270a2b6ee8117f11a",
"0x5f8181365a222c7b05a84c29a29754e6a925952d3bf4bd65a6259ef37ee048e3",
"0x6c"
],
"out": [
"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff"
]
},
"standard hash, invalid v parameter": {
"in": [
"0xf83d80808094121212121212121212121212121212121212121280a0bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a6c8080",
false,
"0x00",
"0x057bf1c0edf0a9002a79f8c9b39683f6453a18e73e02364270a2b6ee8117f11a",
"0x5f8181365a222c7b05a84c29a29754e6a925952d3bf4bd65a6259ef37ee048e3",
"0x6c"
],
"out": [
"0x0000000000000000000000000000000000000000"
]
},
"standard hash, invalid r parameter": {
"in": [
"0xf83d80808094121212121212121212121212121212121212121280a0bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a6c8080",
false,
"0xfc",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x5f8181365a222c7b05a84c29a29754e6a925952d3bf4bd65a6259ef37ee048e3",
"0x6c"
],
"out": [
"0x0000000000000000000000000000000000000000"
]
},
"standard hash, invalid s parameter": {
"in": [
"0xf83d80808094121212121212121212121212121212121212121280a0bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a6c8080",
false,
"0xfc",
"0x057bf1c0edf0a9002a79f8c9b39683f6453a18e73e02364270a2b6ee8117f11a",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x6c"
],
"out": [
"0x0000000000000000000000000000000000000000"
]
},
"standard hash, invalid chainid parameter": {
"in": [
"0xf83d80808094121212121212121212121212121212121212121280a0bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a6c8080",
false,
"0xfc",
"0x057bf1c0edf0a9002a79f8c9b39683f6453a18e73e02364270a2b6ee8117f11a",
"0x5f8181365a222c7b05a84c29a29754e6a925952d3bf4bd65a6259ef37ee048e3",
"0x00"
],
"out": [
"0x0000000000000000000000000000000000000000"
]
},
"standard hash, invalid message": {
"in": [
"0x0000000000000000000000000000000000000000000000000000000000000000",
false,
"0xfc",
"0x057bf1c0edf0a9002a79f8c9b39683f6453a18e73e02364270a2b6ee8117f11a",
"0x5f8181365a222c7b05a84c29a29754e6a925952d3bf4bd65a6259ef37ee048e3",
"0x6c"
],
"out": [
"0x1397890fcfC2D7563Aa01cE93A217b9809D3447B"
]
},
"eth signed message hash, valid signature": {
"in": [
"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000121212121212121212121212121212121212121200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a",
true,
"0x1c",
"0xe5a2edb71b6d76a8aacd59467d3063fd455ca13a4e9cb57da6f25849d40e4e2a",
"0x5465373d68d521845e3ffd2baf4c51f3d21c990914c09490b32ffc0b322dbf98",
"0x6c"
],
"out": [
"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff"
]
},
"eth signed message hash, invalid v parameter": {
"in": [
"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000121212121212121212121212121212121212121200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a",
true,
"0x00",
"0xe5a2edb71b6d76a8aacd59467d3063fd455ca13a4e9cb57da6f25849d40e4e2a",
"0x5465373d68d521845e3ffd2baf4c51f3d21c990914c09490b32ffc0b322dbf98",
"0x6c"
],
"out": [
"0x0000000000000000000000000000000000000000"
]
},
"eth signed message hash, invalid r parameter": {
"in": [
"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000121212121212121212121212121212121212121200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a",
true,
"0x1c",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x5465373d68d521845e3ffd2baf4c51f3d21c990914c09490b32ffc0b322dbf98",
"0x6c"
],
"out": [
"0x0000000000000000000000000000000000000000"
]
},
"eth signed message hash, invalid s parameter": {
"in": [
"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c000000000000000000000000121212121212121212121212121212121212121200000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000020bc36789e7a1e281436464229828f817d6612f7b477d66591ff96a9e064bcc98a",
true,
"0x1c",
"0xe5a2edb71b6d76a8aacd59467d3063fd455ca13a4e9cb57da6f25849d40e4e2a",
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x6c"
],
"out": [
"0x0000000000000000000000000000000000000000"
]
},
"eth signed message hash, invalid message": {
"in": [
"0x0000000000000000000000000000000000000000000000000000000000000000",
true,
"0x1c",
"0xe5a2edb71b6d76a8aacd59467d3063fd455ca13a4e9cb57da6f25849d40e4e2a",
"0x5465373d68d521845e3ffd2baf4c51f3d21c990914c09490b32ffc0b322dbf98",
"0x6c"
],
"out": [
"0xf8bd1421f9D28C8F58f33B25a6faB16F3f89b749"
]
}
}
}
}
{
"safetyCheckerTests": {
"tests": {
"single opcode blacklisted: ADDRESS": {
"in": "0x30",
"out": false
......
import { NULL_BYTES32 } from '../constants'
export const DUMMY_BATCH_HEADERS = [
{
batchIndex: 0,
batchRoot: NULL_BYTES32,
batchSize: 0,
prevTotalElements: 0,
extraData: NULL_BYTES32,
},
]
export const DUMMY_BATCH_PROOFS = [
{
index: 0,
siblings: [NULL_BYTES32],
},
]
......@@ -2,3 +2,5 @@ export * from './accounts'
export * from './bytes32'
export * from './context'
export * from './bytecode'
export * from './batches'
export * from './transactions'
import { ZERO_ADDRESS, NULL_BYTES32 } from '../constants'
export const DUMMY_OVM_TRANSACTIONS = [
{
timestamp: 0,
number: 0,
l1QueueOrigin: 0,
l1Txorigin: ZERO_ADDRESS,
entrypoint: ZERO_ADDRESS,
gasLimit: 0,
data: NULL_BYTES32,
},
]
......@@ -5,3 +5,4 @@ export * from './resolver'
export * from './utils'
export * from './codec'
export * from './test-runner'
export * from './trie'
......@@ -7,10 +7,11 @@ export const setProxyTarget = async (
name: string,
target: Contract
): Promise<void> => {
const SimpleProxy = await (
const SimpleProxy: Contract = await (
await ethers.getContractFactory('Helper_SimpleProxy')
).deploy(target.address)
).deploy()
await SimpleProxy.setTarget(target.address)
await AddressManager.setAddress(name, SimpleProxy.address)
}
......
export * from './test-runner'
export * from './test.types'
export * from './json-test-runner'
import { expect } from '../../setup'
/* External Imports */
import { ethers } from '@nomiclabs/buidler'
import { Contract, BigNumber } from 'ethers'
export const runJsonTest = (contractName: string, json: any): void => {
let contract: Contract
before(async () => {
contract = await (await ethers.getContractFactory(contractName)).deploy()
})
for (const [functionName, functionTests] of Object.entries(json)) {
describe(functionName, () => {
for (const [key, test] of Object.entries(functionTests)) {
it(`should run test: ${key}`, async () => {
if (test.revert) {
await expect(contract.functions[functionName](...test.in)).to.be
.reverted
} else {
expect(
await contract.functions[functionName](...test.in)
).to.deep.equal(
test.out.map((out: any) => {
if (typeof out === 'number') {
return BigNumber.from(out)
} else {
return out
}
})
)
}
})
}
})
}
}
......@@ -144,18 +144,31 @@ export class ExecutionManagerTestRunner {
return
}
const AddressManager = await (
await ethers.getContractFactory('Lib_AddressManager')
).deploy()
this.contracts.OVM_SafetyChecker = await (
await ethers.getContractFactory('OVM_SafetyChecker')
).deploy()
await AddressManager.setAddress(
'OVM_SafetyChecker',
this.contracts.OVM_SafetyChecker.address
)
this.contracts.OVM_ExecutionManager = await (
await smoddit('OVM_ExecutionManager')
).deploy(this.contracts.OVM_SafetyChecker.address)
).deploy(AddressManager.address)
this.contracts.OVM_StateManager = await (
await smoddit('OVM_StateManager')
).deploy(this.contracts.OVM_ExecutionManager.address)
this.contracts.Helper_TestRunner = await (
await ethers.getContractFactory('Helper_TestRunner')
).deploy()
this.contracts.Factory__Helper_TestRunner_CREATE = await ethers.getContractFactory(
'Helper_TestRunner_CREATE'
)
......
export * from './trie-test-generator'
/* External Imports */
import * as rlp from 'rlp'
import { default as seedbytes } from 'random-bytes-seed'
import { SecureTrie, BaseTrie } from 'merkle-patricia-tree'
/* Internal Imports */
import { fromHexString, toHexString } from '../utils'
import { NULL_BYTES32 } from '../constants'
export interface TrieNode {
key: string
val: string
}
export interface InclusionProofTest {
key: string
val: string
proof: string
root: string
}
export interface NodeUpdateTest extends InclusionProofTest {
newRoot: string
}
export interface EthereumAccount {
address?: string
nonce: number
balance: number
codeHash: string
storageRoot?: string
storage?: TrieNode[]
}
export interface AccountProofTest {
address: string
account: EthereumAccount
accountTrieWitness: string
accountTrieRoot: string
}
export interface AccountUpdateTest extends AccountProofTest {
newAccountTrieRoot: string
}
const rlpEncodeAccount = (account: EthereumAccount): string => {
return toHexString(
rlp.encode([
account.nonce,
account.balance,
account.storageRoot || NULL_BYTES32,
account.codeHash || NULL_BYTES32,
])
)
}
const rlpDecodeAccount = (encoded: string): EthereumAccount => {
const decoded = rlp.decode(fromHexString(encoded)) as any
return {
nonce: decoded[0].length ? parseInt(decoded[0], 16) : 0,
balance: decoded[1].length ? parseInt(decoded[1], 16) : 0,
storageRoot: decoded[2].length ? toHexString(decoded[2]) : NULL_BYTES32,
codeHash: decoded[3].length ? toHexString(decoded[3]) : NULL_BYTES32,
}
}
const makeTrie = async (
nodes: TrieNode[],
secure?: boolean
): Promise<{
trie: SecureTrie | BaseTrie
TrieClass: any
}> => {
const TrieClass = secure ? SecureTrie : BaseTrie
const trie = new TrieClass()
for (const node of nodes) {
await trie.put(fromHexString(node.key), fromHexString(node.val))
}
return {
trie,
TrieClass,
}
}
export class TrieTestGenerator {
constructor(
public _TrieClass: any,
public _trie: SecureTrie | BaseTrie,
public _nodes: TrieNode[],
public _subGenerators?: TrieTestGenerator[]
) {}
static async fromNodes(opts: {
nodes: TrieNode[]
secure?: boolean
}): Promise<TrieTestGenerator> {
const { trie, TrieClass } = await makeTrie(opts.nodes, opts.secure)
return new TrieTestGenerator(TrieClass, trie, opts.nodes)
}
static async fromRandom(opts: {
seed: string
nodeCount: number
secure?: boolean
keySize?: number
valSize?: number
}): Promise<TrieTestGenerator> {
const getRandomBytes = seedbytes(opts.seed)
const nodes: TrieNode[] = [...Array(opts.nodeCount)].map(() => {
return {
key: toHexString(getRandomBytes(opts.keySize || 32)),
val: toHexString(getRandomBytes(opts.valSize || 32)),
}
})
return TrieTestGenerator.fromNodes({
nodes,
secure: opts.secure,
})
}
static async fromAccounts(opts: {
accounts: EthereumAccount[]
secure?: boolean
}): Promise<TrieTestGenerator> {
const subGenerators: TrieTestGenerator[] = []
for (const account of opts.accounts) {
if (account.storage) {
const subGenerator = await TrieTestGenerator.fromNodes({
nodes: account.storage,
secure: opts.secure,
})
account.storageRoot = toHexString(subGenerator._trie.root)
subGenerators.push(subGenerator)
}
}
const nodes = opts.accounts.map((account) => {
return {
key: account.address,
val: rlpEncodeAccount(account),
}
})
const { trie, TrieClass } = await makeTrie(nodes, opts.secure)
return new TrieTestGenerator(TrieClass, trie, nodes, subGenerators)
}
public async makeInclusionProofTest(
key: string | number
): Promise<InclusionProofTest> {
if (typeof key === 'number') {
key = this._nodes[key].key
}
const trie = this._trie.copy()
const proof = await this.prove(key)
const val = await trie.get(fromHexString(key))
return {
proof: toHexString(rlp.encode(proof)),
key: toHexString(key),
val: toHexString(val),
root: toHexString(trie.root),
}
}
public async makeAllInclusionProofTests(): Promise<InclusionProofTest[]> {
return Promise.all(
this._nodes.map(async (node) => {
return this.makeInclusionProofTest(node.key)
})
)
}
public async makeNodeUpdateTest(
key: string | number,
val: string
): Promise<NodeUpdateTest> {
if (typeof key === 'number') {
key = this._nodes[key].key
}
const trie = this._trie.copy()
const proof = await this.prove(key)
const oldRoot = trie.root
await trie.put(fromHexString(key), fromHexString(val))
const newRoot = trie.root
return {
proof: toHexString(rlp.encode(proof)),
key: toHexString(key),
val: toHexString(val),
root: toHexString(oldRoot),
newRoot: toHexString(newRoot),
}
}
public async makeAccountProofTest(
address: string | number
): Promise<AccountProofTest> {
if (typeof address === 'number') {
address = this._nodes[address].key
}
const trie = this._trie.copy()
const proof = await this.prove(address)
const account = await trie.get(fromHexString(address))
return {
address,
account: rlpDecodeAccount(toHexString(account)),
accountTrieWitness: toHexString(rlp.encode(proof)),
accountTrieRoot: toHexString(trie.root),
}
}
public async makeAccountUpdateTest(
address: string | number,
account: EthereumAccount
): Promise<AccountUpdateTest> {
if (typeof address === 'number') {
address = this._nodes[address].key
}
const trie = this._trie.copy()
const proof = await this.prove(address)
const oldRoot = trie.root
await trie.put(
fromHexString(address),
fromHexString(rlpEncodeAccount(account))
)
const newRoot = trie.root
return {
address,
account,
accountTrieWitness: toHexString(rlp.encode(proof)),
accountTrieRoot: toHexString(oldRoot),
newAccountTrieRoot: toHexString(newRoot),
}
}
private async prove(key: string): Promise<any> {
return this._TrieClass.prove(this._trie, fromHexString(key))
}
}
/* External Imports */
import { BigNumber } from 'ethers'
/**
* Converts a string or buffer to a '0x'-prefixed hex string.
* @param buf String or buffer to convert.
......@@ -19,3 +22,23 @@ export const fromHexString = (str: string | Buffer): Buffer => {
return Buffer.from(str)
}
export const toHexString32 = (
input: Buffer | string | number,
padRight = false
): string => {
if (typeof input === 'number') {
input = BigNumber.from(input).toHexString()
}
input = toHexString(input).slice(2)
return '0x' + (padRight ? input.padEnd(64, '0') : input.padStart(64, '0'))
}
export const getHexSlice = (
input: Buffer | string,
start: number,
length: number
): string => {
return toHexString(fromHexString(input).slice(start, start + length))
}
......@@ -39,7 +39,16 @@
resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89"
integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==
"@ethereum-waffle/chai@^3.0.0":
"@eth-optimism/smock@^0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@eth-optimism/smock/-/smock-0.0.2.tgz#58b9b28885fef1b08c5b13cb31bf614635027d90"
integrity sha512-6Wn4h8ZuDqZlNq2lF1Mov78b41S7g4xXWXBOqqS5T+d0yC2V6Ao9XIJBheBS6l1cCN8tFNR47zdlmOCRSDX7sw==
dependencies:
ethereum-waffle "^3"
ethers "^5"
fs-extra "^9.0.1"
"@ethereum-waffle/chai@^3.0.0", "@ethereum-waffle/chai@^3.1.1":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.1.1.tgz#2d2594e19613cdee0eaa1a38fc8dac31f66460e6"
integrity sha512-gbpjfIz+XhM9sH8BtBiRmK+eU6WuAWPK5TqIMR7QwzcGQ4XkIoFzACRNc/kxnV5f9Townpgr7yp0yzbzJJCWiw==
......@@ -47,7 +56,7 @@
"@ethereum-waffle/provider" "^3.1.1"
ethers "^5.0.0"
"@ethereum-waffle/compiler@^3.0.0":
"@ethereum-waffle/compiler@^3.0.0", "@ethereum-waffle/compiler@^3.1.1":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@ethereum-waffle/compiler/-/compiler-3.1.1.tgz#df3dba3c5dc556afe04f259e0789c16bc34333f5"
integrity sha512-vneBsbR7VaqZ0cDJRc+pr7aU6ZB8uO2h4ScKsn3GQIXE1GYB4i9eUxvRkdi5t/cS7YufnmUyKQU/IyAjivDcWw==
......@@ -70,7 +79,7 @@
"@ensdomains/resolver" "^0.2.4"
ethers "^5.0.1"
"@ethereum-waffle/mock-contract@^3.0.0":
"@ethereum-waffle/mock-contract@^3.0.0", "@ethereum-waffle/mock-contract@^3.1.1":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@ethereum-waffle/mock-contract/-/mock-contract-3.1.1.tgz#ae0fe5bcdb7a0ba64069098394ea4e54a02ed293"
integrity sha512-by4eUeL7FGQzczi4nM94YcnYWV9EPsjx9WI9A66LzLHHPdEyIvAUZyyBQ+9hLYwUqJ78ppLoVx+xYWEagHx/jg==
......@@ -784,6 +793,17 @@ abstract-leveldown@^5.0.0, abstract-leveldown@~5.0.0:
dependencies:
xtend "~4.0.0"
abstract-leveldown@^6.2.1:
version "6.3.0"
resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a"
integrity sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==
dependencies:
buffer "^5.5.0"
immediate "^3.2.3"
level-concat-iterator "~2.0.0"
level-supports "~1.0.0"
xtend "~4.0.0"
abstract-leveldown@~2.6.0:
version "2.6.3"
resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz#1c5e8c6a5ef965ae8c35dfb3a8770c476b82c4b8"
......@@ -791,6 +811,17 @@ abstract-leveldown@~2.6.0:
dependencies:
xtend "~4.0.0"
abstract-leveldown@~6.2.1:
version "6.2.3"
resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz#036543d87e3710f2528e47040bc3261b77a9a8eb"
integrity sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==
dependencies:
buffer "^5.5.0"
immediate "^3.2.3"
level-concat-iterator "~2.0.0"
level-supports "~1.0.0"
xtend "~4.0.0"
accepts@~1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
......@@ -2540,6 +2571,14 @@ deferred-leveldown@~4.0.0:
abstract-leveldown "~5.0.0"
inherits "^2.0.3"
deferred-leveldown@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058"
integrity sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==
dependencies:
abstract-leveldown "~6.2.1"
inherits "^2.0.3"
define-properties@^1.1.2, define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
......@@ -2715,6 +2754,16 @@ encoding-down@5.0.4, encoding-down@~5.0.0:
level-errors "^2.0.0"
xtend "^4.0.1"
encoding-down@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/encoding-down/-/encoding-down-6.3.0.tgz#b1c4eb0e1728c146ecaef8e32963c549e76d082b"
integrity sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==
dependencies:
abstract-leveldown "^6.2.1"
inherits "^2.0.3"
level-codec "^9.0.0"
level-errors "^2.0.0"
encoding@^0.1.11:
version "0.1.13"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
......@@ -3072,6 +3121,17 @@ ethereum-waffle@3.0.0:
"@ethereum-waffle/provider" "^3.0.0"
ethers "^5.0.1"
ethereum-waffle@^3:
version "3.1.1"
resolved "https://registry.yarnpkg.com/ethereum-waffle/-/ethereum-waffle-3.1.1.tgz#2a63475104281dca1fd2ffed12ab8f6605219d51"
integrity sha512-kiJo7PPGKsRfNiQOB8Z/ogLTHrU7Cj7VOZrdU3nyx9xXobkTFN9F9FcwdYZRg3gw3C1XnuOd18Jk2hPfuQbORA==
dependencies:
"@ethereum-waffle/chai" "^3.1.1"
"@ethereum-waffle/compiler" "^3.1.1"
"@ethereum-waffle/mock-contract" "^3.1.1"
"@ethereum-waffle/provider" "^3.1.1"
ethers "^5.0.1"
ethereumjs-abi@0.6.5:
version "0.6.5"
resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.5.tgz#5a637ef16ab43473fa72a29ad90871405b3f5241"
......@@ -3088,15 +3148,7 @@ ethereumjs-abi@0.6.7:
bn.js "^4.11.8"
ethereumjs-util "^6.0.0"
ethereumjs-abi@^0.6.8:
version "0.6.8"
resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae"
integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==
dependencies:
bn.js "^4.11.8"
ethereumjs-util "^6.0.0"
"ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git":
ethereumjs-abi@^0.6.8, "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git":
version "0.6.8"
resolved "git+https://github.com/ethereumjs/ethereumjs-abi.git#1ce6a1d64235fabe2aaf827fd606def55693508f"
dependencies:
......@@ -3222,7 +3274,7 @@ ethereumjs-util@^5.0.0, ethereumjs-util@^5.0.1, ethereumjs-util@^5.1.1, ethereum
rlp "^2.0.0"
safe-buffer "^5.1.1"
ethereumjs-util@^7.0.2:
ethereumjs-util@^7.0.0, ethereumjs-util@^7.0.2:
version "7.0.5"
resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.0.5.tgz#bc6e178dedbccc4b188c9ae6ae38db1906884b7b"
integrity sha512-gLLZVXYUHR6pamO3h/+M1jzKz7qE20PKFyFKtq1PrIHA6wcLI96mDz96EMkkhXfrpk30rhpkw0iRnzxKhqaIdQ==
......@@ -3322,7 +3374,7 @@ ethers@5.0.0:
"@ethersproject/web" "^5.0.0"
"@ethersproject/wordlists" "^5.0.0"
ethers@^5.0.0, ethers@^5.0.1:
ethers@^5, ethers@^5.0.0, ethers@^5.0.1:
version "5.0.14"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.0.14.tgz#fc33613ff3c1eb04c481f32083f2be315079e2a2"
integrity sha512-6WkoYwAURTr/4JiSZlrMJ9mm3pBv/bWrOu7sVXdLGw9QU4cp/GDZVrKKnh5GafMTzanuNBJoaEanPCjsbe4Mig==
......@@ -3821,7 +3873,7 @@ functional-red-black-tree@^1.0.1, functional-red-black-tree@~1.0.1:
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
ganache-core@^2.10.2:
ganache-core@^2.10.2, ganache-core@^2.12.1:
version "2.12.1"
resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.12.1.tgz#c21e8f7eca6e15f13756a353928357e0b8960d9e"
integrity sha512-gycoVl3TChAbL6ZZQrK1gS2cNMheX+JXVBKTpMAzuLHwb5gE1CB1s6YYN3F7rB86opaEuldCSuTJK1dv4xYRAw==
......@@ -4905,6 +4957,11 @@ level-codec@~7.0.0:
resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-7.0.1.tgz#341f22f907ce0f16763f24bddd681e395a0fb8a7"
integrity sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==
level-concat-iterator@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz#1d1009cf108340252cb38c51f9727311193e6263"
integrity sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==
level-errors@^1.0.3:
version "1.1.2"
resolved "https://registry.yarnpkg.com/level-errors/-/level-errors-1.1.2.tgz#4399c2f3d3ab87d0625f7e3676e2d807deff404d"
......@@ -4954,6 +5011,15 @@ level-iterator-stream@~3.0.0:
readable-stream "^2.3.6"
xtend "^4.0.0"
level-iterator-stream@~4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz#7ceba69b713b0d7e22fcc0d1f128ccdc8a24f79c"
integrity sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==
dependencies:
inherits "^2.0.4"
readable-stream "^3.4.0"
xtend "^4.0.2"
level-mem@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-3.0.1.tgz#7ce8cf256eac40f716eb6489654726247f5a89e5"
......@@ -4962,6 +5028,22 @@ level-mem@^3.0.1:
level-packager "~4.0.0"
memdown "~3.0.0"
level-mem@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/level-mem/-/level-mem-5.0.1.tgz#c345126b74f5b8aa376dc77d36813a177ef8251d"
integrity sha512-qd+qUJHXsGSFoHTziptAKXoLX87QjR7v2KMbqncDXPxQuCdsQlzmyX+gwrEHhlzn08vkf8TyipYyMmiC6Gobzg==
dependencies:
level-packager "^5.0.3"
memdown "^5.0.0"
level-packager@^5.0.3:
version "5.1.1"
resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-5.1.1.tgz#323ec842d6babe7336f70299c14df2e329c18939"
integrity sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==
dependencies:
encoding-down "^6.3.0"
levelup "^4.3.2"
level-packager@~4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/level-packager/-/level-packager-4.0.1.tgz#7e7d3016af005be0869bc5fa8de93d2a7f56ffe6"
......@@ -4993,6 +5075,13 @@ level-sublevel@6.6.4:
typewiselite "~1.0.0"
xtend "~4.0.0"
level-supports@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d"
integrity sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==
dependencies:
xtend "^4.0.2"
level-ws@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-0.0.0.tgz#372e512177924a00424b0b43aef2bb42496d228b"
......@@ -5010,6 +5099,15 @@ level-ws@^1.0.0:
readable-stream "^2.2.8"
xtend "^4.0.1"
level-ws@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-2.0.0.tgz#207a07bcd0164a0ec5d62c304b4615c54436d339"
integrity sha512-1iv7VXx0G9ec1isqQZ7y5LmoZo/ewAsyDHNA8EFDW5hqH2Kqovm33nSFkSdnLLAK+I5FlT+lo5Cw9itGe+CpQA==
dependencies:
inherits "^2.0.3"
readable-stream "^3.1.0"
xtend "^4.0.1"
levelup@3.1.1, levelup@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/levelup/-/levelup-3.1.1.tgz#c2c0b3be2b4dc316647c53b42e2f559e232d2189"
......@@ -5033,6 +5131,17 @@ levelup@^1.2.1:
semver "~5.4.1"
xtend "~4.0.0"
levelup@^4.3.2:
version "4.4.0"
resolved "https://registry.yarnpkg.com/levelup/-/levelup-4.4.0.tgz#f89da3a228c38deb49c48f88a70fb71f01cafed6"
integrity sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==
dependencies:
deferred-leveldown "~5.3.0"
level-errors "~2.0.0"
level-iterator-stream "~4.0.0"
level-supports "~1.0.0"
xtend "~4.0.0"
lines-and-columns@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
......@@ -5219,6 +5328,18 @@ memdown@^1.0.0:
ltgt "~2.2.0"
safe-buffer "~5.1.1"
memdown@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/memdown/-/memdown-5.1.0.tgz#608e91a9f10f37f5b5fe767667a8674129a833cb"
integrity sha512-B3J+UizMRAlEArDjWHTMmadet+UKwHd3UjMgGBkZcKAxAYVPS9o0Yeiha4qvz7iGiL2Sb3igUft6p7nbFWctpw==
dependencies:
abstract-leveldown "~6.2.1"
functional-red-black-tree "~1.0.1"
immediate "~3.2.3"
inherits "~2.0.1"
ltgt "~2.2.0"
safe-buffer "~5.2.0"
memdown@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/memdown/-/memdown-3.0.0.tgz#93aca055d743b20efc37492e9e399784f2958309"
......@@ -5268,6 +5389,17 @@ merkle-patricia-tree@^3.0.0:
rlp "^2.0.0"
semaphore ">=1.0.1"
"merkle-patricia-tree@git+https://github.com/kfichter/merkle-patricia-tree":
version "3.0.0"
resolved "git+https://github.com/kfichter/merkle-patricia-tree#ebd10c405be8ae909f1f82dea275a0e9ec1c8e46"
dependencies:
ethereumjs-util "^7.0.0"
level-mem "^5.0.1"
level-ws "^2.0.0"
readable-stream "^3.6.0"
rlp "^2.2.4"
semaphore-async-await "^1.5.1"
methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
......@@ -6251,6 +6383,11 @@ querystring@0.2.0:
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
random-bytes-seed@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/random-bytes-seed/-/random-bytes-seed-1.0.3.tgz#126f1201dba2ec70cd0784f94a810396cad24a15"
integrity sha512-O+eniMt8Sj2iAn2q1x5VEirS/XvbtwYcXNDbOAcRtGN+OhC48cmzS5ksf9qEHRVKC1I8A4qzjucNVElddofB0A==
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.0.6, randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
......@@ -6331,7 +6468,7 @@ readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.2.2, readable
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^3.0.6, readable-stream@^3.6.0:
readable-stream@^3.0.6, readable-stream@^3.1.0, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
......@@ -6534,7 +6671,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
hash-base "^3.0.0"
inherits "^2.0.1"
rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3, rlp@^2.2.4:
rlp@^2.0.0, rlp@^2.2.1, rlp@^2.2.2, rlp@^2.2.3, rlp@^2.2.4, rlp@^2.2.6:
version "2.2.6"
resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.6.tgz#c80ba6266ac7a483ef1e69e8e2f056656de2fb2c"
integrity sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==
......@@ -6601,6 +6738,11 @@ seedrandom@3.0.1:
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.1.tgz#eb3dde015bcf55df05a233514e5df44ef9dce083"
integrity sha512-1/02Y/rUeU1CJBAGLebiC5Lbo5FnB22gQbIFFYTLkwvp1xdABZJH1sn4ZT1MzXmPpzv+Rf/Lu2NcsLJiK4rcDg==
seedrandom@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7"
integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==
seek-bzip@^1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.6.tgz#35c4171f55a680916b52a07859ecf3b5857f21c4"
......@@ -6608,6 +6750,11 @@ seek-bzip@^1.0.5:
dependencies:
commander "^2.8.1"
semaphore-async-await@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/semaphore-async-await/-/semaphore-async-await-1.5.1.tgz#857bef5e3644601ca4b9570b87e9df5ca12974fa"
integrity sha1-hXvvXjZEYBykuVcLh+nfXKEpdPo=
semaphore@>=1.0.1, semaphore@^1.0.3, semaphore@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/semaphore/-/semaphore-1.1.0.tgz#aaad8b86b20fe8e9b32b16dc2ee682a8cd26a8aa"
......@@ -8106,7 +8253,7 @@ xhr@^2.0.4, xhr@^2.2.0, xhr@^2.3.3:
parse-headers "^2.0.0"
xtend "^4.0.0"
xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1:
xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment