From a7d9bca63fe891664297d973d5d9c1324d248dd1 Mon Sep 17 00:00:00 2001 From: Everton Fraga Date: Mon, 4 May 2020 16:32:52 -0400 Subject: [PATCH 01/31] vm: v4.2.0 release notes --- packages/vm/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/vm/CHANGELOG.md b/packages/vm/CHANGELOG.md index 1eee8b4b327..8ad95def3ca 100644 --- a/packages/vm/CHANGELOG.md +++ b/packages/vm/CHANGELOG.md @@ -21,6 +21,7 @@ This is a maintenance release preceding the v5. - Properly copying BigNumbers on stack. PR [#733](https://github.com/ethereumjs/ethereumjs-vm/pull/733) + - Fixes installation on Node 12, by bumping `level` dependency from `^4.0.0` to `^6.0.0` PR [#662](https://github.com/ethereumjs/ethereumjs-vm/pull/662) @@ -147,7 +148,7 @@ Added EIPs: - [EIP-152](https://eips.ethereum.org/EIPS/eip-152): Blake 2b `F` precompile, PR [#584](https://github.com/ethereumjs/ethereumjs-vm/pull/584) - [EIP-1108](https://eips.ethereum.org/EIPS/eip-1108): Reduce `alt_bn128` - precompile gas costs, + precompile gas costs, PR [#540](https://github.com/ethereumjs/ethereumjs-vm/pull/540) (already released in `v4.0.0`) - [EIP-1344](https://eips.ethereum.org/EIPS/eip-1344): Add ChainID Opcode, From debe1562f1589956075f002e7e32b1c3db39c79e Mon Sep 17 00:00:00 2001 From: jochem-brouwer Date: Thu, 30 Apr 2020 19:45:00 +0200 Subject: [PATCH 02/31] vm: explicitly duplicate bignumbers on stack (#733) * explicitly duplicate bignumbers on stack * vm: add test to check for internally editing stack items Co-authored-by: Ev --- packages/vm/tests/api/evm/stack.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/vm/tests/api/evm/stack.js b/packages/vm/tests/api/evm/stack.js index 7e8d981000c..635a2f332f5 100644 --- a/packages/vm/tests/api/evm/stack.js +++ b/packages/vm/tests/api/evm/stack.js @@ -3,6 +3,7 @@ const BN = require('bn.js') const Stack = require('../../../dist/evm/stack').default const VM = require('../../../dist/index').default const PStateManager = require('../../../dist/state/promisified').default + const { createAccount } = require('../utils') tape('Stack', t => { @@ -131,11 +132,11 @@ tape('Stack', t => { DUP1 DUP1 PUSH1 0x01 - CALLER + CALLER DUP3 CALL stack: [0, CALLER, 1, 0, 0, 0, 0, 0] POP pop the call result (1) - PUSH1 0x00 + PUSH1 0x00 MSTORE we now expect that the stack (prior to MSTORE) is [0, 0] PUSH1 0x20 PUSH1 0x00 @@ -144,6 +145,7 @@ tape('Stack', t => { const state = new PStateManager(vm.stateManager) await state.putAccount(addr, account) await state.putContractCode(addr, Buffer.from(code, 'hex')) + const runCallArgs = { caller: caller, gasLimit: new BN(0xffffffffff), @@ -152,7 +154,7 @@ tape('Stack', t => { } try { const res = await vm.runCall(runCallArgs) - const executionReturnValue = res.execResult.returnValue + const executionReturnValue = res.execResult.returnValue st.assert(executionReturnValue.equals(expectedReturnValue)) st.end() } catch(e) { From 2046561c73aee968d751d4007fdda0215390ba19 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Fri, 25 Sep 2020 12:00:40 -0400 Subject: [PATCH 03/31] Updated to use state dump method --- lib/ovm/contracts/defs/ExecutionManager.json | 445 +++++++++++++++++++ lib/ovm/contracts/defs/StateManager.json | 283 ++++++++++++ lib/ovm/contracts/index.ts | 8 + lib/ovm/ovm-state-manager.ts | 106 +++++ lib/ovm/utils/buffer-utils.ts | 15 + lib/ovm/utils/constants.ts | 6 + lib/ovm/utils/logger.ts | 53 +++ package.json | 32 +- packages/vm/lib/evm/eei.ts | 8 + packages/vm/lib/evm/evm.ts | 70 ++- packages/vm/lib/evm/message.ts | 44 ++ packages/vm/lib/exceptions.ts | 3 + packages/vm/lib/index.ts | 134 +++++- 13 files changed, 1146 insertions(+), 61 deletions(-) create mode 100644 lib/ovm/contracts/defs/ExecutionManager.json create mode 100644 lib/ovm/contracts/defs/StateManager.json create mode 100644 lib/ovm/contracts/index.ts create mode 100644 lib/ovm/ovm-state-manager.ts create mode 100644 lib/ovm/utils/buffer-utils.ts create mode 100644 lib/ovm/utils/constants.ts create mode 100644 lib/ovm/utils/logger.ts diff --git a/lib/ovm/contracts/defs/ExecutionManager.json b/lib/ovm/contracts/defs/ExecutionManager.json new file mode 100644 index 00000000000..cf888ff9a64 --- /dev/null +++ b/lib/ovm/contracts/defs/ExecutionManager.json @@ -0,0 +1,445 @@ +{ + "contractName": "ExecutionManager", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_addressResolver", + "type": "address" + }, + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "OvmTxBaseGasFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "OvmTxMaxGas", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "GasRateLimitEpochSeconds", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "MaxSequencedGasPerEpoch", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "MaxQueuedGasPerEpoch", + "type": "uint256" + } + ], + "internalType": "struct DataTypes.GasMeterConfig", + "name": "_gasMeterConfig", + "type": "tuple" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_queueOrigin", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_ovmEntrypoint", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_callBytes", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_v", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_s", + "type": "bytes32" + } + ], + "name": "executeEOACall", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "uint256", + "name": "_timestamp", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_queueOrigin", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_ovmEntrypoint", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_callBytes", + "type": "bytes" + }, + { + "internalType": "address", + "name": "_fromAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_l1MsgSenderAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "_allowRevert", + "type": "bool" + } + ], + "name": "executeTransaction", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "getL1MessageSender", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "getStateManagerAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "isStaticContext", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ovmADDRESS", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ovmBlockGasLimit", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "ovmCALL", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ovmCALLER", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ovmCHAINID", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "ovmCREATE", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "ovmCREATE2", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "ovmDELEGATECALL", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "ovmEXTCODECOPY", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "ovmEXTCODEHASH", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "ovmEXTCODESIZE", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ovmGASLIMIT", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ovmNUMBER", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ovmORIGIN", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ovmQueueOrigin", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "ovmSLOAD", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "ovmSSTORE", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [], + "name": "ovmSTATICCALL", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "ovmTIMESTAMP", + "outputs": [], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "_callData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_v", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "_r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_s", + "type": "bytes32" + } + ], + "name": "recoverEOAAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "name": "resolveContract", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_stateManagerAddress", + "type": "address" + } + ], + "name": "setStateManager", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60806040523480156200001157600080fd5b506040516200343e3803806200343e83398101604081905262000034916200042d565b600080546001600160a01b0319166001600160a01b0385161781556200005962000275565b905060015b6014816001600160a01b03161015620000e257604051636b8b57e160e01b81526001600160a01b03831690636b8b57e190620000a19084908190600401620004ed565b600060405180830381600087803b158015620000bc57600080fd5b505af1158015620000d1573d6000803e3d6000fd5b5050600190920191506200005e9050565b50600030604051620000f4906200033e565b620001009190620004dd565b604051809103906000f0801580156200011d573d6000803e3d6000fd5b50604051636b8b57e160e01b81529091506001600160a01b03831690636b8b57e1906200015590602160991b90859060040162000513565b600060405180830381600087803b1580156200017057600080fd5b505af115801562000185573d6000803e3d6000fd5b505050506000306040516200019a906200034c565b620001a69190620004dd565b604051809103906000f080158015620001c3573d6000803e3d6000fd5b50604051636b8b57e160e01b81529091506001600160a01b03841690636b8b57e1906200020b9073420000000000000000000000000000000000000190859060040162000513565b600060405180830381600087803b1580156200022657600080fd5b505af11580156200023b573d6000803e3d6000fd5b50506101a460025550508351600b555050506020810151600c556040810151600d556060810151600e5560800151600f5550620006049050565b6000620002ac6040518060400160405280600c81526020016b29ba30ba32a6b0b730b3b2b960a11b815250620002b160201b60201c565b905090565b6000805460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190620002e490859060040162000532565b60206040518083038186803b158015620002fd57600080fd5b505afa15801562000312573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525062000338919081019062000404565b92915050565b6102978062002f4a83390190565b61025d80620031e183390190565b80516200033881620005df565b600060a082840312156200037a57600080fd5b6200038660a062000545565b90506000620003968484620003f7565b8252506020620003a984848301620003f7565b6020830152506040620003bf84828501620003f7565b6040830152506060620003d584828501620003f7565b6060830152506080620003eb84828501620003f7565b60808301525092915050565b80516200033881620005f9565b6000602082840312156200041757600080fd5b60006200042584846200035a565b949350505050565b600080600060e084860312156200044357600080fd5b60006200045186866200035a565b935050602062000464868287016200035a565b9250506040620004778682870162000367565b9150509250925092565b6200048c816200058e565b82525050565b6200048c8162000579565b6000620004aa826200056c565b620004b6818562000570565b9350620004c8818560208601620005a2565b620004d381620005d5565b9093019392505050565b6020810162000338828462000492565b60408101620004fd828562000481565b6200050c602083018462000481565b9392505050565b6040810162000523828562000492565b6200050c602083018462000492565b602080825281016200050c81846200049d565b6040518181016001600160401b03811182821017156200056457600080fd5b604052919050565b5190565b90815260200190565b60006001600160a01b03821662000338565b90565b600062000338826000620003388262000579565b60005b83811015620005bf578181015183820152602001620005a5565b83811115620005cf576000848401525b50505050565b601f01601f191690565b620005ea8162000579565b8114620005f657600080fd5b50565b620005ea816200058b565b61293680620006146000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806373509064116100f9578063bdbf8c3611610097578063d203410611610071578063d2034106146102aa578063d8178e3d146102b2578063f55c5c72146102ba578063fbb0f79d146102cd576101a9565b8063bdbf8c3614610292578063c3382d0f1461029a578063c8645416146102a2576101a9565b80638e03b2d1116100d35780638e03b2d114610272578063905802561461027a578063996d79a514610282578063b0168ba31461028a576101a9565b8063735090641461024f57806377a5a62f146102575780637aec0a921461026a576101a9565b806345e97ddb116101665780634c6d7c84116101405780634c6d7c84146102195780635a98c361146102215780635c8e0129146102295780635cbccd461461023c576101a9565b806345e97ddb1461020157806349d65ff9146102095780634ba8746f14610211576101a9565b8063035a2005146101ae57806316902d57146101cc57806320160f3a146101d657806320966208146101de578063232cdee6146101e657806328dcb2a0146101f9575b600080fd5b6101b66102d5565b6040516101c39190612651565b60405180910390f35b6101d46102e6565b005b6101d4610331565b6101d461033f565b6101b66101f4366004611eb9565b6103e5565b6101d461046e565b6101d4610511565b6101d46105e1565b6101d4610796565b6101d46107a4565b6101d461089b565b6101d4610237366004611f8d565b6108a9565b6101d461024a366004612041565b610b52565b6101d4610c4e565b6101d4610265366004611e04565b610c90565b6101d4610cf5565b6101d4610dbd565b6101d4610e6b565b6101d4610e7a565b6101d4610ebc565b6101d4610eca565b6101d4610ed8565b6101d4610f7e565b6101b6610fa5565b6101d461103a565b6101b66102c8366004611eee565b6110ab565b6101d46112ed565b6000806102e06113fe565b91505090565b6008546001600160a01b03166103175760405162461bcd60e51b815260040161030e9061270c565b60405180910390fd5b6008546040516001600160a01b0390911680825290602081f35b600a54604051818152602081f35b60006103496113fe565b6006546040516362c510a360e01b815291925060048035926000926001600160a01b03808716936362c510a393610386939092169187910161267a565b602060405180830381600087803b1580156103a057600080fd5b505af11580156103b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103d89190810190611e66565b9050604051818152602081f35b6000805460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906104169085906004016126fb565b60206040518083038186803b15801561042e57600080fd5b505afa158015610442573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104669190810190611e2a565b90505b919050565b60006104786113fe565b60015490915060ff161561049e5760405162461bcd60e51b815260040161030e906127cb565b6006546040516339e503ab60e01b81526004803592602435926001600160a01b03808716936339e503ab936104da939216918791879101612695565b600060405180830381600087803b1580156104f457600080fd5b505af1158015610508573d6000803e3d6000fd5b50505050505050565b600061051b6113fe565b604080516023193680830182019093529293509101906010358260248337604051633dec5d8560e01b8152606082901c906000906001600160a01b03871690633dec5d859061056e908590600401612651565b602060405180830381600087803b15801561058857600080fd5b505af115801561059c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105c09190810190611e2a565b905060008086866000855af16040513d6000823e816105dd573d81fd5b3d81f35b60006105eb6113fe565b60015490915060ff16156106055760405160008152602081f35b604051600319360180825280600460208401378101602081016040819052600654630e7d0fff60e01b9091526001600160a01b0390811691600091851690630e7d0fff90610657908590602401612651565b602060405180830381600087803b15801561067157600080fd5b505af1158015610685573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106a99190810190611e66565b905060006106b78383611432565b90506106c381856114ce565b6040516333dda11760e11b81526001600160a01b038616906367bb422e906106ef908490600401612651565b600060405180830381600087803b15801561070957600080fd5b505af115801561071d573d6000803e3d6000fd5b505060405163d909aa5360e01b81526001600160a01b038816925063d909aa53915061074d908690600401612651565b600060405180830381600087803b15801561076757600080fd5b505af115801561077b573d6000803e3d6000fd5b50506040516001600160a01b03841680825292509050602081f35b600c54604051818152602081f35b60006107ae6113fe565b604080516023193680830182019093529293509101906010358260248337606081901c6000806107dd8361172f565b915091506000876001600160a01b0316633dec5d85856040518263ffffffff1660e01b815260040161080f9190612651565b602060405180830381600087803b15801561082957600080fd5b505af115801561083d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108619190810190611e2a565b9050606060008060008a8a6000875af160405192503d6000843e80610884573d83fd5b50503d8181016040526108978585611763565b8082f35b600454604051818152602081f35b60006108b36113fe565b90506108c58860008987876000611794565b6108ce8461172f565b5060009050806001600160a01b038816158015610a36576108ed6117e2565b6001600160a01b031663b1540a01886040518263ffffffff1660e01b81526004016109189190612651565b60206040518083038186803b15801561093057600080fd5b505afa158015610944573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109689190810190611e48565b6109845760405162461bcd60e51b815260040161030e9061272c565b60e06040516109929061263b565b6040518091039020901c9250875160040191506000610a2e88866001600160a01b0316630e7d0fff8b6040518263ffffffff1660e01b81526004016109d79190612651565b602060405180830381600087803b1580156109f157600080fd5b505af1158015610a05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a299190810190611e66565b611432565b905050610ab6565b60e0604051610a4490612646565b6040519081900381208a5163d909aa5360e01b8352921c9450602490910192506001600160a01b0385169063d909aa5390610a83908a90600401612651565b600060405180830381600087803b158015610a9d57600080fd5b505af1158015610ab1573d6000803e3d6000fd5b505050505b80610ac657888852600319909701965b6001811415610ad657601c880197505b8260181c88538260101c60018901538260081c600289015382600389015360006060818080868d82305af192503d9050604051915060208201816000823e8183528101604052602082016001841415610b2d578181f35b6001891415610b3a578181fd5b5082610b4257005b5050505050505050505050505050565b6000610b5c6113fe565b90506000610b6e8888888888886110ab565b90506001600160a01b038116610b965760405162461bcd60e51b815260040161030e9061274c565b604051630e7d0fff60e01b81526001600160a01b03831690630e7d0fff90610bc2908490600401612651565b602060405180830381600087803b158015610bdc57600080fd5b505af1158015610bf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c149190810190611e66565b8814610c325760405162461bcd60e51b815260040161030e9061273c565b610c428a8a8989856000806108a9565b50505050505050505050565b6007546001600160a01b0316610c765760405162461bcd60e51b815260040161030e9061271c565b6007546040516001600160a01b0390911680825290602081f35b600054604051639b2ea4bd60e01b81526001600160a01b0390911690639b2ea4bd90610cc09084906004016127ac565b600060405180830381600087803b158015610cda57600080fd5b505af1158015610cee573d6000803e3d6000fd5b5050505050565b6000610cff6113fe565b604051633dec5d8560e01b815290915060103590606082901c906000906001600160a01b03851690633dec5d8590610d3b908590600401612651565b602060405180830381600087803b158015610d5557600080fd5b505af1158015610d69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d8d9190810190611e2a565b90506000846001600160a01b031663dfcac77d836040518263ffffffff1660e01b81526004016103869190612651565b6000610dc76113fe565b604051633dec5d8560e01b8152909150601035906024359060443590606084901c906000906001600160a01b03871690633dec5d8590610e0b908590600401612651565b602060405180830381600087803b158015610e2557600080fd5b505af1158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e5d9190810190611e2a565b9050604051838582843c8381f35b6040516101a480825290602081f35b6006546001600160a01b0316610ea25760405162461bcd60e51b815260040161030e9061279c565b6006546040516001600160a01b0390911680825290602081f35b600554604051818152602081f35b600354604051818152602081f35b6000610ee26113fe565b604051633dec5d8560e01b815290915060103590606082901c906000906001600160a01b03851690633dec5d8590610f1e908590600401612651565b602060405180830381600087803b158015610f3857600080fd5b505af1158015610f4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f709190810190611e2a565b9050604051813b8152602081f35b60015460009060ff16610f92576000610f95565b60015b60ff169050604051818152602081f35b6006546000906001600160a01b03166001602160991b0114610fd95760405162461bcd60e51b815260040161030e906127db565b6009546001600160a01b03166110015760405162461bcd60e51b815260040161030e9061275c565b6007546001600160a01b03161561102a5760405162461bcd60e51b815260040161030e9061278c565b506009546001600160a01b031690565b60015460ff16156110515760405160008152602081f35b604051602319360180825260043590806024602085013782016020016040526006546001600160a01b03166000611089828486611816565b905061109581856114ce565b6040516001600160a01b03821680825290602081f35b604080516009808252610140820190925260009160609190816020015b60608152602001906001900390816110c85790505090506110e888611867565b816000815181106110f557fe5b602002602001018190525061110a6000611867565b8160018151811061111757fe5b6020026020010181905250611130600b60010154611867565b8160028151811061113d57fe5b60209081029190910101526001600160a01b03871661117d576111606000611867565b8160038151811061116d57fe5b602002602001018190525061119f565b6111868761187a565b8160038151811061119357fe5b60200260200101819052505b6111a96000611867565b816004815181106111b657fe5b60200260200101819052506111ca86611899565b816005815181106111d757fe5b60200260200101819052506111ef6001800154611867565b816006815181106111fc57fe5b60200260200101819052506112116000611867565b8160078151811061121e57fe5b60200260200101819052506112336000611867565b8160088151811061124057fe5b60200260200101819052506060611256826118e2565b905060008160405160200161126b919061262f565b604051602081830303815290604052805190602001209050600181600860018001546002028a03038888604051600081526020016040526040516112b294939291906126bd565b6020604051602081039080840390855afa1580156112d4573d6000803e3d6000fd5b5050604051601f1901519b9a5050505050505050505050565b60006112f76113fe565b6040805160231936808301820190935292935091019060103582602483376001805460ff198116821790915560ff16606082901c6000806113378361172f565b915091506000886001600160a01b0316633dec5d85856040518263ffffffff1660e01b81526004016113699190612651565b602060405180830381600087803b15801561138357600080fd5b505af1158015611397573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113bb9190810190611e2a565b9050606060008060008b8b6000875af160405192503d6000843e3d9150806113e1573d83fd5b506113ec8585611763565b6001805460ff19168815151790558082f35b600061142d6040518060400160405280600c81526020016b29ba30ba32a6b0b730b3b2b960a11b8152506103e5565b905090565b60408051600280825260608281019093526000929190816020015b606081526020019060019003908161144d57905050905061146d8461187a565b8160008151811061147a57fe5b602002602001018190525061148e83611867565b8160018151811061149b57fe5b602002602001018190525060606114b1826118e2565b90506114c38180519060200120611905565b925050505b92915050565b60006114d86113fe565b905060006114e4611911565b6040516352275acd60e11b81529091506001600160a01b0382169063a44eb59a906115139086906004016126fb565b60206040518083038186803b15801561152b57600080fd5b505afa15801561153f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115639190810190611e48565b61157f5760405162461bcd60e51b815260040161030e9061277c565b60008061158b8661172f565b91509150600061159a86611941565b90506060856001600160a01b031663d7b5555e836040518263ffffffff1660e01b81526004016115ca9190612651565b600060405180830381600087803b1580156115e457600080fd5b505af11580156115f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116209190810190611e84565b6040516352275acd60e11b81529091506001600160a01b0386169063a44eb59a9061164f9084906004016126fb565b60206040518083038186803b15801561166757600080fd5b505afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061169f9190810190611e48565b6116bb5760405162461bcd60e51b815260040161030e9061276c565b604051636b8b57e160e01b81526001600160a01b03871690636b8b57e1906116e9908b90869060040161265f565b600060405180830381600087803b15801561170357600080fd5b505af1158015611717573d6000803e3d6000fd5b505050506117258484611763565b5050505050505050565b60068054600780546001600160a01b03198084166001600160a01b0396871617909455918416928216831790559190911691565b600680546001600160a01b039283166001600160a01b03199182161790915560078054939092169216919091179055565b61179f600080611763565b600395909555600493909355600591909155600880546001600160a01b039283166001600160a01b03199182161790915560098054929093169116179055600a55565b600061142d6040518060400160405280601181526020017011195c1b1bde595c95da1a5d195b1a5cdd607a1b8152506103e5565b60008060ff60f81b8585858051906020012060405160200161183b94939291906125e7565b60405160208183030381529060405280519060200120905061185c81611905565b9150505b9392505050565b606061046661187583611952565b611899565b60408051600560a21b8318601482015260348101909152606090611860815b606080825160011480156118c157506080836000815181106118b757fe5b016020015160f81c105b156118cd575081610466565b6118606118dc84516080611a44565b84611b7d565b6060806118ee83611bfa565b90506118606118ff825160c0611a44565b82611b7d565b6001600160a01b031690565b600061142d6040518060400160405280600d81526020016c29b0b332ba3ca1b432b1b5b2b960991b8152506103e5565b60008151602083016000f092915050565b60408051602080825281830190925260609182919060208201818038833950505060208101849052905060005b60208110156119b55781818151811061199457fe5b01602001516001600160f81b031916156119ad576119b5565b60010161197f565b6060816020036040519080825280601f01601f1916602001820160405280156119e5576020820181803883390190505b50905060005b8151811015611a3b578351600184019385918110611a0557fe5b602001015160f81c60f81b828281518110611a1c57fe5b60200101906001600160f81b031916908160001a9053506001016119eb565b50949350505050565b6060806038841015611a9e576040805160018082528183019092529060208201818038833901905050905082840160f81b81600081518110611a8257fe5b60200101906001600160f81b031916908160001a905350611860565b600060015b808681611aac57fe5b0415611ac15760019091019061010002611aa3565b816001016040519080825280601f01601f191660200182016040528015611aef576020820181803883390190505b50925084820160370160f81b83600081518110611b0857fe5b60200101906001600160f81b031916908160001a905350600190505b818111611b74576101008183036101000a8781611b3d57fe5b0481611b4557fe5b0660f81b838281518110611b5557fe5b60200101906001600160f81b031916908160001a905350600101611b24565b50509392505050565b6060806040519050835180825260208201818101602087015b81831015611bae578051835260209283019201611b96565b50855184518101855292509050808201602086015b81831015611bdb578051835260209283019201611bc3565b508651929092011591909101601f01601f191660405250905092915050565b6060815160001415611c1b5750604080516000815260208101909152610469565b6000805b8351811015611c4e57838181518110611c3457fe5b602002602001015151820191508080600101915050611c1f565b6060826040519080825280601f01601f191660200182016040528015611c7b576020820181803883390190505b50600092509050602081015b8551831015611a3b576060868481518110611c9e57fe5b602002602001015190506000602082019050611cbc83828451611ce4565b878581518110611cc857fe5b6020026020010151518301925050508280600101935050611c87565b8282825b60208110611d07578151835260209283019290910190601f1901611ce8565b905182516020929092036101000a6000190180199091169116179052505050565b80356114c8816128ca565b80516114c8816128ca565b80356114c8816128e1565b80516114c8816128e1565b80356114c8816128ea565b80516114c8816128ea565b600082601f830112611d7b57600080fd5b8135611d8e611d8982612812565b6127eb565b91508082526020830160208301858383011115611daa57600080fd5b611db583828461286d565b50505092915050565b600082601f830112611dcf57600080fd5b8151611ddd611d8982612812565b91508082526020830160208301858383011115611df957600080fd5b611db5838284612879565b600060208284031215611e1657600080fd5b6000611e228484611d28565b949350505050565b600060208284031215611e3c57600080fd5b6000611e228484611d33565b600060208284031215611e5a57600080fd5b6000611e228484611d49565b600060208284031215611e7857600080fd5b6000611e228484611d5f565b600060208284031215611e9657600080fd5b815167ffffffffffffffff811115611ead57600080fd5b611e2284828501611dbe565b600060208284031215611ecb57600080fd5b813567ffffffffffffffff811115611ee257600080fd5b611e2284828501611d6a565b60008060008060008060c08789031215611f0757600080fd5b6000611f138989611d54565b9650506020611f2489828a01611d28565b955050604087013567ffffffffffffffff811115611f4157600080fd5b611f4d89828a01611d6a565b9450506060611f5e89828a01611d54565b9350506080611f6f89828a01611d54565b92505060a0611f8089828a01611d54565b9150509295509295509295565b600080600080600080600060e0888a031215611fa857600080fd5b6000611fb48a8a611d54565b9750506020611fc58a828b01611d54565b9650506040611fd68a828b01611d28565b955050606088013567ffffffffffffffff811115611ff357600080fd5b611fff8a828b01611d6a565b94505060806120108a828b01611d28565b93505060a06120218a828b01611d28565b92505060c06120328a828b01611d3e565b91505092959891949750929550565b600080600080600080600080610100898b03121561205e57600080fd5b600061206a8b8b611d54565b985050602061207b8b828c01611d54565b975050604061208c8b828c01611d54565b965050606061209d8b828c01611d28565b955050608089013567ffffffffffffffff8111156120ba57600080fd5b6120c68b828c01611d6a565b94505060a06120d78b828c01611d54565b93505060c06120e88b828c01611d54565b92505060e06120f98b828c01611d54565b9150509295985092959890939650565b61211281612847565b82525050565b61211261212482612847565b6128a9565b61211261213582612857565b612864565b61211281612864565b61211261213582612864565b600061215a8261283a565b612164818561283e565b9350612174818560208601612879565b61217d816128ba565b9093019392505050565b60006121928261283a565b61219c8185610469565b93506121ac818560208601612879565b9290920192915050565b60006121c360328361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527132bc34b9ba32b73a103a3c27b934b3b4b71760711b602082015260400192915050565b600061221760338361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527232bc34b9ba32b73a1036b9b3a9b2b73232b91760691b602082015260400192915050565b600061226c602b8361283e565b7f53656e646572206e6f7420616c6c6f77656420746f206465706c6f79206e657781526a20636f6e7472616374732160a81b602082015260400192915050565b60006122b960108361283e565b6f496e636f7272656374206e6f6e63652160801b815260200192915050565b60006122e5600b83610469565b6a6f766d435245415445282960a81b8152600b0192915050565b600061230c601b8361283e565b7f4661696c656420746f207265636f766572207369676e61747572650000000000815260200192915050565b6000612345600983610469565b686f766d43414c4c282960b81b815260090192915050565b600061236a60188361283e565b7f4c314d65737361676553656e646572206e6f7420736574210000000000000000815260200192915050565b60006123a360308361283e565b7f436f6e74726163742072756e74696d6520286465706c6f79656429206279746581526f636f6465206973206e6f74207361666560801b602082015260400192915050565b60006123f560298361283e565b7f436f6e747261637420696e697420286372656174696f6e2920636f6465206973815268206e6f74207361666560b81b602082015260400192915050565b600061244060378361283e565b7f4c314d65737361676553656e646572206f6e6c792061636365737369626c652081527f696e20656e747279706f696e7420636f6e747261637421000000000000000000602082015260400192915050565b600061249f603b8361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527f6578697374656e74206f766d416374697665436f6e74726163742e0000000000602082015260400192915050565b60006124fe600c8361283e565b6b29ba30ba32a6b0b730b3b2b960a11b815260200192915050565b6000612526602c8361283e565b7f43616e6e6f742063616c6c205353544f52452066726f6d2077697468696e206181526b1029aa20aa24a1a1a0a6261760a11b602082015260400192915050565b6000612574604f8361283e565b7f4f6e6c7920746865204c314d65737361676553656e64657220707265636f6d7081527f696c6520697320616c6c6f77656420746f2063616c6c206765744c314d65737360208201526e61676553656e646572282e2e2e292160881b604082015260600192915050565b61211281612867565b60006125f38287612129565b6001820191506126038286612118565b6014820191506126138285612143565b6020820191506126238284612143565b50602001949350505050565b60006118608284612187565b60006114c8826122d8565b60006114c882612338565b602081016114c88284612109565b6040810161266d8285612109565b6118606020830184612109565b604081016126888285612109565b611860602083018461213a565b606081016126a38286612109565b6126b0602083018561213a565b611e22604083018461213a565b608081016126cb828761213a565b6126d860208301866125de565b6126e5604083018561213a565b6126f2606083018461213a565b95945050505050565b60208082528101611860818461214f565b60208082528101610466816121b6565b602080825281016104668161220a565b602080825281016104668161225f565b60208082528101610466816122ac565b60208082528101610466816122ff565b602080825281016104668161235d565b6020808252810161046681612396565b60208082528101610466816123e8565b6020808252810161046681612433565b6020808252810161046681612492565b604080825281016127bc816124f1565b90506114c86020830184612109565b6020808252810161046681612519565b6020808252810161046681612567565b60405181810167ffffffffffffffff8111828210171561280a57600080fd5b604052919050565b600067ffffffffffffffff82111561282957600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b600061046682611905565b151590565b6001600160f81b03191690565b90565b60ff1690565b82818337506000910152565b60005b8381101561289457818101518382015260200161287c565b838111156128a3576000848401525b50505050565b6000610466826000610466826128c4565b601f01601f191690565b60601b90565b6128d381612847565b81146128de57600080fd5b50565b6128d381612852565b6128d38161286456fea365627a7a72315820628c4900b986bf0fde8d4e9f7d6dc9c4d2ef2b8c923c1a6f6ded2288ba095dc66c6578706572696d656e74616cf564736f6c634300050f0040608060405234801561001057600080fd5b506040516102973803806102978339818101604052602081101561003357600080fd5b5051600180546001600160a01b0319166001600160a01b03909216919091179055610234806100636000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063cafa81dc14610030575b600080fd5b6100d66004803603602081101561004657600080fd5b81019060208101813564010000000081111561006157600080fd5b82018360208201111561007357600080fd5b8035906020019184600183028401116401000000008311171561009557600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506100d8945050505050565b005b60008054600181019091557f47b65c6c9adf9c9a1f4d661cea00e3a0be49b77b90d9b5a02347d55cbfb7c3f59061010d6101a8565b8360405180848152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610169578181015183820152602001610151565b50505050905090810190601f1680156101965780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a150565b604080516a6f766d43414c4c4552282960a81b8152905190819003600b0181206001548183526000926001600160a01b03909116908390806207a12081368186885af1806101f4573d82fd5b50519450505050509056fea265627a7a72315820343803a12ea2d9c56741a67958dea5bb2201f31f4037ba697412498df5f96e6764736f6c634300050f0032608060405234801561001057600080fd5b5060405161025d38038061025d83398101604081905261002f91610065565b600080546001600160a01b0319166001600160a01b03929092169190911790556100b3565b805161005f8161009c565b92915050565b60006020828403121561007757600080fd5b60006100838484610054565b949350505050565b60006001600160a01b03821661005f565b6100a58161008b565b81146100b057600080fd5b50565b61019b806100c26000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d203410614610030575b600080fd5b61003861004e565b6040516100459190610122565b60405180910390f35b60008060009054906101000a90046001600160a01b03166001600160a01b031663d20341066040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561009f57600080fd5b505af11580156100b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506100d791908101906100ed565b905090565b80516100e781610141565b92915050565b6000602082840312156100ff57600080fd5b600061010b84846100dc565b949350505050565b61011c81610130565b82525050565b602081016100e78284610113565b60006001600160a01b0382166100e7565b61014a81610130565b811461015557600080fd5b5056fea365627a7a723158203fee4ffc5bf216e9ed2244978d45a942231af338f679eb4dd6c6e15b664459196c6578706572696d656e74616cf564736f6c634300050f0040", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c806373509064116100f9578063bdbf8c3611610097578063d203410611610071578063d2034106146102aa578063d8178e3d146102b2578063f55c5c72146102ba578063fbb0f79d146102cd576101a9565b8063bdbf8c3614610292578063c3382d0f1461029a578063c8645416146102a2576101a9565b80638e03b2d1116100d35780638e03b2d114610272578063905802561461027a578063996d79a514610282578063b0168ba31461028a576101a9565b8063735090641461024f57806377a5a62f146102575780637aec0a921461026a576101a9565b806345e97ddb116101665780634c6d7c84116101405780634c6d7c84146102195780635a98c361146102215780635c8e0129146102295780635cbccd461461023c576101a9565b806345e97ddb1461020157806349d65ff9146102095780634ba8746f14610211576101a9565b8063035a2005146101ae57806316902d57146101cc57806320160f3a146101d657806320966208146101de578063232cdee6146101e657806328dcb2a0146101f9575b600080fd5b6101b66102d5565b6040516101c39190612651565b60405180910390f35b6101d46102e6565b005b6101d4610331565b6101d461033f565b6101b66101f4366004611eb9565b6103e5565b6101d461046e565b6101d4610511565b6101d46105e1565b6101d4610796565b6101d46107a4565b6101d461089b565b6101d4610237366004611f8d565b6108a9565b6101d461024a366004612041565b610b52565b6101d4610c4e565b6101d4610265366004611e04565b610c90565b6101d4610cf5565b6101d4610dbd565b6101d4610e6b565b6101d4610e7a565b6101d4610ebc565b6101d4610eca565b6101d4610ed8565b6101d4610f7e565b6101b6610fa5565b6101d461103a565b6101b66102c8366004611eee565b6110ab565b6101d46112ed565b6000806102e06113fe565b91505090565b6008546001600160a01b03166103175760405162461bcd60e51b815260040161030e9061270c565b60405180910390fd5b6008546040516001600160a01b0390911680825290602081f35b600a54604051818152602081f35b60006103496113fe565b6006546040516362c510a360e01b815291925060048035926000926001600160a01b03808716936362c510a393610386939092169187910161267a565b602060405180830381600087803b1580156103a057600080fd5b505af11580156103b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103d89190810190611e66565b9050604051818152602081f35b6000805460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906104169085906004016126fb565b60206040518083038186803b15801561042e57600080fd5b505afa158015610442573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104669190810190611e2a565b90505b919050565b60006104786113fe565b60015490915060ff161561049e5760405162461bcd60e51b815260040161030e906127cb565b6006546040516339e503ab60e01b81526004803592602435926001600160a01b03808716936339e503ab936104da939216918791879101612695565b600060405180830381600087803b1580156104f457600080fd5b505af1158015610508573d6000803e3d6000fd5b50505050505050565b600061051b6113fe565b604080516023193680830182019093529293509101906010358260248337604051633dec5d8560e01b8152606082901c906000906001600160a01b03871690633dec5d859061056e908590600401612651565b602060405180830381600087803b15801561058857600080fd5b505af115801561059c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105c09190810190611e2a565b905060008086866000855af16040513d6000823e816105dd573d81fd5b3d81f35b60006105eb6113fe565b60015490915060ff16156106055760405160008152602081f35b604051600319360180825280600460208401378101602081016040819052600654630e7d0fff60e01b9091526001600160a01b0390811691600091851690630e7d0fff90610657908590602401612651565b602060405180830381600087803b15801561067157600080fd5b505af1158015610685573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106a99190810190611e66565b905060006106b78383611432565b90506106c381856114ce565b6040516333dda11760e11b81526001600160a01b038616906367bb422e906106ef908490600401612651565b600060405180830381600087803b15801561070957600080fd5b505af115801561071d573d6000803e3d6000fd5b505060405163d909aa5360e01b81526001600160a01b038816925063d909aa53915061074d908690600401612651565b600060405180830381600087803b15801561076757600080fd5b505af115801561077b573d6000803e3d6000fd5b50506040516001600160a01b03841680825292509050602081f35b600c54604051818152602081f35b60006107ae6113fe565b604080516023193680830182019093529293509101906010358260248337606081901c6000806107dd8361172f565b915091506000876001600160a01b0316633dec5d85856040518263ffffffff1660e01b815260040161080f9190612651565b602060405180830381600087803b15801561082957600080fd5b505af115801561083d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108619190810190611e2a565b9050606060008060008a8a6000875af160405192503d6000843e80610884573d83fd5b50503d8181016040526108978585611763565b8082f35b600454604051818152602081f35b60006108b36113fe565b90506108c58860008987876000611794565b6108ce8461172f565b5060009050806001600160a01b038816158015610a36576108ed6117e2565b6001600160a01b031663b1540a01886040518263ffffffff1660e01b81526004016109189190612651565b60206040518083038186803b15801561093057600080fd5b505afa158015610944573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109689190810190611e48565b6109845760405162461bcd60e51b815260040161030e9061272c565b60e06040516109929061263b565b6040518091039020901c9250875160040191506000610a2e88866001600160a01b0316630e7d0fff8b6040518263ffffffff1660e01b81526004016109d79190612651565b602060405180830381600087803b1580156109f157600080fd5b505af1158015610a05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a299190810190611e66565b611432565b905050610ab6565b60e0604051610a4490612646565b6040519081900381208a5163d909aa5360e01b8352921c9450602490910192506001600160a01b0385169063d909aa5390610a83908a90600401612651565b600060405180830381600087803b158015610a9d57600080fd5b505af1158015610ab1573d6000803e3d6000fd5b505050505b80610ac657888852600319909701965b6001811415610ad657601c880197505b8260181c88538260101c60018901538260081c600289015382600389015360006060818080868d82305af192503d9050604051915060208201816000823e8183528101604052602082016001841415610b2d578181f35b6001891415610b3a578181fd5b5082610b4257005b5050505050505050505050505050565b6000610b5c6113fe565b90506000610b6e8888888888886110ab565b90506001600160a01b038116610b965760405162461bcd60e51b815260040161030e9061274c565b604051630e7d0fff60e01b81526001600160a01b03831690630e7d0fff90610bc2908490600401612651565b602060405180830381600087803b158015610bdc57600080fd5b505af1158015610bf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c149190810190611e66565b8814610c325760405162461bcd60e51b815260040161030e9061273c565b610c428a8a8989856000806108a9565b50505050505050505050565b6007546001600160a01b0316610c765760405162461bcd60e51b815260040161030e9061271c565b6007546040516001600160a01b0390911680825290602081f35b600054604051639b2ea4bd60e01b81526001600160a01b0390911690639b2ea4bd90610cc09084906004016127ac565b600060405180830381600087803b158015610cda57600080fd5b505af1158015610cee573d6000803e3d6000fd5b5050505050565b6000610cff6113fe565b604051633dec5d8560e01b815290915060103590606082901c906000906001600160a01b03851690633dec5d8590610d3b908590600401612651565b602060405180830381600087803b158015610d5557600080fd5b505af1158015610d69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d8d9190810190611e2a565b90506000846001600160a01b031663dfcac77d836040518263ffffffff1660e01b81526004016103869190612651565b6000610dc76113fe565b604051633dec5d8560e01b8152909150601035906024359060443590606084901c906000906001600160a01b03871690633dec5d8590610e0b908590600401612651565b602060405180830381600087803b158015610e2557600080fd5b505af1158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e5d9190810190611e2a565b9050604051838582843c8381f35b6040516101a480825290602081f35b6006546001600160a01b0316610ea25760405162461bcd60e51b815260040161030e9061279c565b6006546040516001600160a01b0390911680825290602081f35b600554604051818152602081f35b600354604051818152602081f35b6000610ee26113fe565b604051633dec5d8560e01b815290915060103590606082901c906000906001600160a01b03851690633dec5d8590610f1e908590600401612651565b602060405180830381600087803b158015610f3857600080fd5b505af1158015610f4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f709190810190611e2a565b9050604051813b8152602081f35b60015460009060ff16610f92576000610f95565b60015b60ff169050604051818152602081f35b6006546000906001600160a01b03166001602160991b0114610fd95760405162461bcd60e51b815260040161030e906127db565b6009546001600160a01b03166110015760405162461bcd60e51b815260040161030e9061275c565b6007546001600160a01b03161561102a5760405162461bcd60e51b815260040161030e9061278c565b506009546001600160a01b031690565b60015460ff16156110515760405160008152602081f35b604051602319360180825260043590806024602085013782016020016040526006546001600160a01b03166000611089828486611816565b905061109581856114ce565b6040516001600160a01b03821680825290602081f35b604080516009808252610140820190925260009160609190816020015b60608152602001906001900390816110c85790505090506110e888611867565b816000815181106110f557fe5b602002602001018190525061110a6000611867565b8160018151811061111757fe5b6020026020010181905250611130600b60010154611867565b8160028151811061113d57fe5b60209081029190910101526001600160a01b03871661117d576111606000611867565b8160038151811061116d57fe5b602002602001018190525061119f565b6111868761187a565b8160038151811061119357fe5b60200260200101819052505b6111a96000611867565b816004815181106111b657fe5b60200260200101819052506111ca86611899565b816005815181106111d757fe5b60200260200101819052506111ef6001800154611867565b816006815181106111fc57fe5b60200260200101819052506112116000611867565b8160078151811061121e57fe5b60200260200101819052506112336000611867565b8160088151811061124057fe5b60200260200101819052506060611256826118e2565b905060008160405160200161126b919061262f565b604051602081830303815290604052805190602001209050600181600860018001546002028a03038888604051600081526020016040526040516112b294939291906126bd565b6020604051602081039080840390855afa1580156112d4573d6000803e3d6000fd5b5050604051601f1901519b9a5050505050505050505050565b60006112f76113fe565b6040805160231936808301820190935292935091019060103582602483376001805460ff198116821790915560ff16606082901c6000806113378361172f565b915091506000886001600160a01b0316633dec5d85856040518263ffffffff1660e01b81526004016113699190612651565b602060405180830381600087803b15801561138357600080fd5b505af1158015611397573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113bb9190810190611e2a565b9050606060008060008b8b6000875af160405192503d6000843e3d9150806113e1573d83fd5b506113ec8585611763565b6001805460ff19168815151790558082f35b600061142d6040518060400160405280600c81526020016b29ba30ba32a6b0b730b3b2b960a11b8152506103e5565b905090565b60408051600280825260608281019093526000929190816020015b606081526020019060019003908161144d57905050905061146d8461187a565b8160008151811061147a57fe5b602002602001018190525061148e83611867565b8160018151811061149b57fe5b602002602001018190525060606114b1826118e2565b90506114c38180519060200120611905565b925050505b92915050565b60006114d86113fe565b905060006114e4611911565b6040516352275acd60e11b81529091506001600160a01b0382169063a44eb59a906115139086906004016126fb565b60206040518083038186803b15801561152b57600080fd5b505afa15801561153f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115639190810190611e48565b61157f5760405162461bcd60e51b815260040161030e9061277c565b60008061158b8661172f565b91509150600061159a86611941565b90506060856001600160a01b031663d7b5555e836040518263ffffffff1660e01b81526004016115ca9190612651565b600060405180830381600087803b1580156115e457600080fd5b505af11580156115f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116209190810190611e84565b6040516352275acd60e11b81529091506001600160a01b0386169063a44eb59a9061164f9084906004016126fb565b60206040518083038186803b15801561166757600080fd5b505afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061169f9190810190611e48565b6116bb5760405162461bcd60e51b815260040161030e9061276c565b604051636b8b57e160e01b81526001600160a01b03871690636b8b57e1906116e9908b90869060040161265f565b600060405180830381600087803b15801561170357600080fd5b505af1158015611717573d6000803e3d6000fd5b505050506117258484611763565b5050505050505050565b60068054600780546001600160a01b03198084166001600160a01b0396871617909455918416928216831790559190911691565b600680546001600160a01b039283166001600160a01b03199182161790915560078054939092169216919091179055565b61179f600080611763565b600395909555600493909355600591909155600880546001600160a01b039283166001600160a01b03199182161790915560098054929093169116179055600a55565b600061142d6040518060400160405280601181526020017011195c1b1bde595c95da1a5d195b1a5cdd607a1b8152506103e5565b60008060ff60f81b8585858051906020012060405160200161183b94939291906125e7565b60405160208183030381529060405280519060200120905061185c81611905565b9150505b9392505050565b606061046661187583611952565b611899565b60408051600560a21b8318601482015260348101909152606090611860815b606080825160011480156118c157506080836000815181106118b757fe5b016020015160f81c105b156118cd575081610466565b6118606118dc84516080611a44565b84611b7d565b6060806118ee83611bfa565b90506118606118ff825160c0611a44565b82611b7d565b6001600160a01b031690565b600061142d6040518060400160405280600d81526020016c29b0b332ba3ca1b432b1b5b2b960991b8152506103e5565b60008151602083016000f092915050565b60408051602080825281830190925260609182919060208201818038833950505060208101849052905060005b60208110156119b55781818151811061199457fe5b01602001516001600160f81b031916156119ad576119b5565b60010161197f565b6060816020036040519080825280601f01601f1916602001820160405280156119e5576020820181803883390190505b50905060005b8151811015611a3b578351600184019385918110611a0557fe5b602001015160f81c60f81b828281518110611a1c57fe5b60200101906001600160f81b031916908160001a9053506001016119eb565b50949350505050565b6060806038841015611a9e576040805160018082528183019092529060208201818038833901905050905082840160f81b81600081518110611a8257fe5b60200101906001600160f81b031916908160001a905350611860565b600060015b808681611aac57fe5b0415611ac15760019091019061010002611aa3565b816001016040519080825280601f01601f191660200182016040528015611aef576020820181803883390190505b50925084820160370160f81b83600081518110611b0857fe5b60200101906001600160f81b031916908160001a905350600190505b818111611b74576101008183036101000a8781611b3d57fe5b0481611b4557fe5b0660f81b838281518110611b5557fe5b60200101906001600160f81b031916908160001a905350600101611b24565b50509392505050565b6060806040519050835180825260208201818101602087015b81831015611bae578051835260209283019201611b96565b50855184518101855292509050808201602086015b81831015611bdb578051835260209283019201611bc3565b508651929092011591909101601f01601f191660405250905092915050565b6060815160001415611c1b5750604080516000815260208101909152610469565b6000805b8351811015611c4e57838181518110611c3457fe5b602002602001015151820191508080600101915050611c1f565b6060826040519080825280601f01601f191660200182016040528015611c7b576020820181803883390190505b50600092509050602081015b8551831015611a3b576060868481518110611c9e57fe5b602002602001015190506000602082019050611cbc83828451611ce4565b878581518110611cc857fe5b6020026020010151518301925050508280600101935050611c87565b8282825b60208110611d07578151835260209283019290910190601f1901611ce8565b905182516020929092036101000a6000190180199091169116179052505050565b80356114c8816128ca565b80516114c8816128ca565b80356114c8816128e1565b80516114c8816128e1565b80356114c8816128ea565b80516114c8816128ea565b600082601f830112611d7b57600080fd5b8135611d8e611d8982612812565b6127eb565b91508082526020830160208301858383011115611daa57600080fd5b611db583828461286d565b50505092915050565b600082601f830112611dcf57600080fd5b8151611ddd611d8982612812565b91508082526020830160208301858383011115611df957600080fd5b611db5838284612879565b600060208284031215611e1657600080fd5b6000611e228484611d28565b949350505050565b600060208284031215611e3c57600080fd5b6000611e228484611d33565b600060208284031215611e5a57600080fd5b6000611e228484611d49565b600060208284031215611e7857600080fd5b6000611e228484611d5f565b600060208284031215611e9657600080fd5b815167ffffffffffffffff811115611ead57600080fd5b611e2284828501611dbe565b600060208284031215611ecb57600080fd5b813567ffffffffffffffff811115611ee257600080fd5b611e2284828501611d6a565b60008060008060008060c08789031215611f0757600080fd5b6000611f138989611d54565b9650506020611f2489828a01611d28565b955050604087013567ffffffffffffffff811115611f4157600080fd5b611f4d89828a01611d6a565b9450506060611f5e89828a01611d54565b9350506080611f6f89828a01611d54565b92505060a0611f8089828a01611d54565b9150509295509295509295565b600080600080600080600060e0888a031215611fa857600080fd5b6000611fb48a8a611d54565b9750506020611fc58a828b01611d54565b9650506040611fd68a828b01611d28565b955050606088013567ffffffffffffffff811115611ff357600080fd5b611fff8a828b01611d6a565b94505060806120108a828b01611d28565b93505060a06120218a828b01611d28565b92505060c06120328a828b01611d3e565b91505092959891949750929550565b600080600080600080600080610100898b03121561205e57600080fd5b600061206a8b8b611d54565b985050602061207b8b828c01611d54565b975050604061208c8b828c01611d54565b965050606061209d8b828c01611d28565b955050608089013567ffffffffffffffff8111156120ba57600080fd5b6120c68b828c01611d6a565b94505060a06120d78b828c01611d54565b93505060c06120e88b828c01611d54565b92505060e06120f98b828c01611d54565b9150509295985092959890939650565b61211281612847565b82525050565b61211261212482612847565b6128a9565b61211261213582612857565b612864565b61211281612864565b61211261213582612864565b600061215a8261283a565b612164818561283e565b9350612174818560208601612879565b61217d816128ba565b9093019392505050565b60006121928261283a565b61219c8185610469565b93506121ac818560208601612879565b9290920192915050565b60006121c360328361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527132bc34b9ba32b73a103a3c27b934b3b4b71760711b602082015260400192915050565b600061221760338361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527232bc34b9ba32b73a1036b9b3a9b2b73232b91760691b602082015260400192915050565b600061226c602b8361283e565b7f53656e646572206e6f7420616c6c6f77656420746f206465706c6f79206e657781526a20636f6e7472616374732160a81b602082015260400192915050565b60006122b960108361283e565b6f496e636f7272656374206e6f6e63652160801b815260200192915050565b60006122e5600b83610469565b6a6f766d435245415445282960a81b8152600b0192915050565b600061230c601b8361283e565b7f4661696c656420746f207265636f766572207369676e61747572650000000000815260200192915050565b6000612345600983610469565b686f766d43414c4c282960b81b815260090192915050565b600061236a60188361283e565b7f4c314d65737361676553656e646572206e6f7420736574210000000000000000815260200192915050565b60006123a360308361283e565b7f436f6e74726163742072756e74696d6520286465706c6f79656429206279746581526f636f6465206973206e6f74207361666560801b602082015260400192915050565b60006123f560298361283e565b7f436f6e747261637420696e697420286372656174696f6e2920636f6465206973815268206e6f74207361666560b81b602082015260400192915050565b600061244060378361283e565b7f4c314d65737361676553656e646572206f6e6c792061636365737369626c652081527f696e20656e747279706f696e7420636f6e747261637421000000000000000000602082015260400192915050565b600061249f603b8361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527f6578697374656e74206f766d416374697665436f6e74726163742e0000000000602082015260400192915050565b60006124fe600c8361283e565b6b29ba30ba32a6b0b730b3b2b960a11b815260200192915050565b6000612526602c8361283e565b7f43616e6e6f742063616c6c205353544f52452066726f6d2077697468696e206181526b1029aa20aa24a1a1a0a6261760a11b602082015260400192915050565b6000612574604f8361283e565b7f4f6e6c7920746865204c314d65737361676553656e64657220707265636f6d7081527f696c6520697320616c6c6f77656420746f2063616c6c206765744c314d65737360208201526e61676553656e646572282e2e2e292160881b604082015260600192915050565b61211281612867565b60006125f38287612129565b6001820191506126038286612118565b6014820191506126138285612143565b6020820191506126238284612143565b50602001949350505050565b60006118608284612187565b60006114c8826122d8565b60006114c882612338565b602081016114c88284612109565b6040810161266d8285612109565b6118606020830184612109565b604081016126888285612109565b611860602083018461213a565b606081016126a38286612109565b6126b0602083018561213a565b611e22604083018461213a565b608081016126cb828761213a565b6126d860208301866125de565b6126e5604083018561213a565b6126f2606083018461213a565b95945050505050565b60208082528101611860818461214f565b60208082528101610466816121b6565b602080825281016104668161220a565b602080825281016104668161225f565b60208082528101610466816122ac565b60208082528101610466816122ff565b602080825281016104668161235d565b6020808252810161046681612396565b60208082528101610466816123e8565b6020808252810161046681612433565b6020808252810161046681612492565b604080825281016127bc816124f1565b90506114c86020830184612109565b6020808252810161046681612519565b6020808252810161046681612567565b60405181810167ffffffffffffffff8111828210171561280a57600080fd5b604052919050565b600067ffffffffffffffff82111561282957600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b600061046682611905565b151590565b6001600160f81b03191690565b90565b60ff1690565b82818337506000910152565b60005b8381101561289457818101518382015260200161287c565b838111156128a3576000848401525b50505050565b6000610466826000610466826128c4565b601f01601f191690565b60601b90565b6128d381612847565b81146128de57600080fd5b50565b6128d381612852565b6128d38161286456fea365627a7a72315820628c4900b986bf0fde8d4e9f7d6dc9c4d2ef2b8c923c1a6f6ded2288ba095dc66c6578706572696d656e74616cf564736f6c634300050f0040", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/lib/ovm/contracts/defs/StateManager.json b/lib/ovm/contracts/defs/StateManager.json new file mode 100644 index 00000000000..54648e511ac --- /dev/null +++ b/lib/ovm/contracts/defs/StateManager.json @@ -0,0 +1,283 @@ +{ + "contractName": "FullStateManager", + "abi": [ + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_ovmContractAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_codeContractAddress", + "type": "address" + } + ], + "name": "associateCodeContract", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_ovmContractAddress", + "type": "address" + } + ], + "name": "getCodeContractAddressFromOvmAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_codeContractAddress", + "type": "address" + } + ], + "name": "getCodeContractBytecode", + "outputs": [ + { + "internalType": "bytes", + "name": "codeContractBytecode", + "type": "bytes" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_codeContractAddress", + "type": "address" + } + ], + "name": "getCodeContractHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "_codeContractHash", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_codeContractAddress", + "type": "address" + } + ], + "name": "getOvmAddressFromCodeContractAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_ovmContractAddress", + "type": "address" + } + ], + "name": "getOvmContractNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "_ovmContractAddress", + "type": "address" + } + ], + "name": "getOvmContractNonceView", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_ovmContractAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + } + ], + "name": "getStorage", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "internalType": "address", + "name": "_ovmContractAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + } + ], + "name": "getStorageView", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_ovmContractAddress", + "type": "address" + } + ], + "name": "incrementOvmContractNonce", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_ovmContractAddress", + "type": "address" + } + ], + "name": "registerCreatedContract", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_ovmContractAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + } + ], + "name": "setOvmContractNonce", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_ovmContractAddress", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_slot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "_value", + "type": "bytes32" + } + ], + "name": "setStorage", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610580806100206000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806367bb422e1161008c578063ac6c266611610066578063ac6c26661461017e578063d7b5555e14610191578063d909aa53146101b1578063dfcac77d146101c4576100cf565b806367bb422e146101455780636b8b57e114610158578063807de2351461016b576100cf565b80630e7d0fff146100d457806339e503ab146100fd5780633dec5d851461011257806349677085146101325780635f78dd86146100d457806362c510a314610132575b600080fd5b6100e76100e236600461035e565b6101d7565b6040516100f49190610499565b60405180910390f35b61011061010b3660046103ee565b6101f2565b005b61012561012036600461035e565b610216565b6040516100f4919061048b565b6100e76101403660046103be565b610234565b61011061015336600461035e565b61025d565b610110610166366004610384565b610260565b61012561017936600461035e565b6102a8565b61011061018c3660046103be565b6102c6565b6101a461019f36600461035e565b6102e2565b6040516100f491906104a7565b6101106101bf36600461035e565b610309565b6100e76101d236600461035e565b61032c565b6001600160a01b031660009081526001602052604090205490565b6001600160a01b039092166000908152602081815260408083209383529290522055565b6001600160a01b039081166000908152600260205260409020541690565b6001600160a01b0382166000908152602081815260408083208484529091529020545b92915050565b50565b6001600160a01b0391821660008181526002602090815260408083208054969095166001600160a01b0319968716811790955593825260039052919091208054909216179055565b6001600160a01b039081166000908152600360205260409020541690565b6001600160a01b03909116600090815260016020526040902055565b60408051603f833b908101601f191682019092528181529080600060208401853c50919050565b6001600160a01b0316600090815260016020819052604090912080549091019055565b60006060610339836102e2565b80516020909101209392505050565b803561025781610520565b803561025781610534565b60006020828403121561037057600080fd5b600061037c8484610348565b949350505050565b6000806040838503121561039757600080fd5b60006103a38585610348565b92505060206103b485828601610348565b9150509250929050565b600080604083850312156103d157600080fd5b60006103dd8585610348565b92505060206103b485828601610353565b60008060006060848603121561040357600080fd5b600061040f8686610348565b935050602061042086828701610353565b925050604061043186828701610353565b9150509250925092565b610444816104cc565b82525050565b610444816104d7565b600061045e826104bf565b61046881856104c3565b93506104788185602086016104e6565b61048181610516565b9093019392505050565b60208101610257828461043b565b60208101610257828461044a565b602080825281016104b88184610453565b9392505050565b5190565b90815260200190565b6000610257826104da565b90565b6001600160a01b031690565b60005b838110156105015781810151838201526020016104e9565b83811115610510576000848401525b50505050565b601f01601f191690565b610529816104cc565b811461025d57600080fd5b610529816104d756fea365627a7a7231582078d85385ce2d2bcfae3c4055bedfb19da2b7eacfdb01fa1e853b31dc6b773c556c6578706572696d656e74616cf564736f6c634300050f0040", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c806367bb422e1161008c578063ac6c266611610066578063ac6c26661461017e578063d7b5555e14610191578063d909aa53146101b1578063dfcac77d146101c4576100cf565b806367bb422e146101455780636b8b57e114610158578063807de2351461016b576100cf565b80630e7d0fff146100d457806339e503ab146100fd5780633dec5d851461011257806349677085146101325780635f78dd86146100d457806362c510a314610132575b600080fd5b6100e76100e236600461035e565b6101d7565b6040516100f49190610499565b60405180910390f35b61011061010b3660046103ee565b6101f2565b005b61012561012036600461035e565b610216565b6040516100f4919061048b565b6100e76101403660046103be565b610234565b61011061015336600461035e565b61025d565b610110610166366004610384565b610260565b61012561017936600461035e565b6102a8565b61011061018c3660046103be565b6102c6565b6101a461019f36600461035e565b6102e2565b6040516100f491906104a7565b6101106101bf36600461035e565b610309565b6100e76101d236600461035e565b61032c565b6001600160a01b031660009081526001602052604090205490565b6001600160a01b039092166000908152602081815260408083209383529290522055565b6001600160a01b039081166000908152600260205260409020541690565b6001600160a01b0382166000908152602081815260408083208484529091529020545b92915050565b50565b6001600160a01b0391821660008181526002602090815260408083208054969095166001600160a01b0319968716811790955593825260039052919091208054909216179055565b6001600160a01b039081166000908152600360205260409020541690565b6001600160a01b03909116600090815260016020526040902055565b60408051603f833b908101601f191682019092528181529080600060208401853c50919050565b6001600160a01b0316600090815260016020819052604090912080549091019055565b60006060610339836102e2565b80516020909101209392505050565b803561025781610520565b803561025781610534565b60006020828403121561037057600080fd5b600061037c8484610348565b949350505050565b6000806040838503121561039757600080fd5b60006103a38585610348565b92505060206103b485828601610348565b9150509250929050565b600080604083850312156103d157600080fd5b60006103dd8585610348565b92505060206103b485828601610353565b60008060006060848603121561040357600080fd5b600061040f8686610348565b935050602061042086828701610353565b925050604061043186828701610353565b9150509250925092565b610444816104cc565b82525050565b610444816104d7565b600061045e826104bf565b61046881856104c3565b93506104788185602086016104e6565b61048181610516565b9093019392505050565b60208101610257828461043b565b60208101610257828461044a565b602080825281016104b88184610453565b9392505050565b5190565b90815260200190565b6000610257826104da565b90565b6001600160a01b031690565b60005b838110156105015781810151838201526020016104e9565b83811115610510576000848401525b50505050565b601f01601f191690565b610529816104cc565b811461025d57600080fd5b610529816104d756fea365627a7a7231582078d85385ce2d2bcfae3c4055bedfb19da2b7eacfdb01fa1e853b31dc6b773c556c6578706572696d656e74616cf564736f6c634300050f0040", + "linkReferences": {}, + "deployedLinkReferences": {} + } + \ No newline at end of file diff --git a/lib/ovm/contracts/index.ts b/lib/ovm/contracts/index.ts new file mode 100644 index 00000000000..50241ea2c42 --- /dev/null +++ b/lib/ovm/contracts/index.ts @@ -0,0 +1,8 @@ +/* External Imports */ +import { Interface } from '@ethersproject/abi' + +import * as ExecutionManagerJSON from './defs/ExecutionManager.json' +import * as StateManagerJSON from './defs/StateManager.json' + +export const iExecutionManager = new Interface(ExecutionManagerJSON.abi) +export const iStateManager = new Interface(StateManagerJSON.abi) diff --git a/lib/ovm/ovm-state-manager.ts b/lib/ovm/ovm-state-manager.ts new file mode 100644 index 00000000000..486ce3ee769 --- /dev/null +++ b/lib/ovm/ovm-state-manager.ts @@ -0,0 +1,106 @@ +/* External Imports */ +import BN = require('bn.js') + +/* Internal Imports */ +import VM from '../index' +import Message from '../evm/message' +import { fromHexString, toHexString } from './utils/buffer-utils' +import { NULL_BYTES32 } from './utils/constants' +import { Logger } from './utils/logger' +import { iStateManager } from './contracts' + +// TODO: Add comments here +const logger = new Logger('ethereumjs-ovm:ovm-state-manager') + +export interface OvmStateManagerOpts { + vm: VM +} + +export class OvmStateManager { + public vm: VM + private _iface = iStateManager + private _handlers: { + [name: string]: any + } + + constructor(opts: OvmStateManagerOpts) { + this.vm = opts.vm + + this._handlers = { + associateCodeContract: this.associateCodeContract.bind(this), + setStorage: this.setStorage.bind(this), + getStorage: this.getStorage.bind(this), + getStorageView: this.getStorageView.bind(this), + getOvmContractNonce: this.getOvmContractNonce.bind(this), + getCodeContractBytecode: this.getCodeContractBytecode.bind(this), + registerCreatedContract: this.registerCreatedContract.bind(this), + incrementOvmContractNonce: this.incrementOvmContractNonce.bind(this), + getCodeContractAddressFromOvmAddress: this.getCodeContractAddressFromOvmAddress.bind(this), + } + } + + async handleCall(message: Message): Promise { + const methodId = '0x' + message.data.slice(0, 4).toString('hex') + const fragment = this._iface.getFunction(methodId) + const functionArgs = this._iface.decodeFunctionData(fragment, toHexString(message.data)) + + //logger.log(`Calling function: ${fragment.name} with args ${functionArgs}`) + const ret = await this._handlers[fragment.name](...functionArgs) + const encodedRet = this._iface.encodeFunctionResult(fragment, ret) + //logger.log(`Got result: ${encodedRet}`) + + return fromHexString(encodedRet) + } + + async associateCodeContract( + ovmContractAddress: string, + codeContractAddress: string, + ): Promise { + return + } + + async setStorage(ovmContractAddress: string, slot: string, value: string): Promise { + return this.vm.pStateManager.putContractStorage( + fromHexString(ovmContractAddress), + fromHexString(slot), + fromHexString(value), + ) + } + + async getStorage(ovmContractAddress: string, slot: string): Promise<[string]> { + return this.getStorageView(ovmContractAddress, slot) + } + + async getStorageView(ovmContractAddress: string, slot: string): Promise<[string]> { + const ret = await this.vm.pStateManager.getContractStorage( + fromHexString(ovmContractAddress), + fromHexString(slot), + ) + + return [ret.length ? toHexString(ret) : NULL_BYTES32] + } + + async getOvmContractNonce(ovmContractAddress: string): Promise<[string]> { + const account = await this.vm.pStateManager.getAccount(fromHexString(ovmContractAddress)) + return [account.nonce.length ? toHexString(account.nonce) : '0x00'] + } + + async getCodeContractBytecode(ovmContractAddress: string): Promise<[string]> { + const code = await this.vm.pStateManager.getContractCode(fromHexString(ovmContractAddress)) + return [toHexString(code)] + } + + async registerCreatedContract(ovmContractAddress: string): Promise { + return + } + + async incrementOvmContractNonce(ovmContractAddress: string): Promise { + const account = await this.vm.pStateManager.getAccount(fromHexString(ovmContractAddress)) + account.nonce = new BN(account.nonce).addn(1).toArrayLike(Buffer) + return this.vm.pStateManager.putAccount(fromHexString(ovmContractAddress), account) + } + + async getCodeContractAddressFromOvmAddress(ovmContractAddress: string): Promise<[string]> { + return [ovmContractAddress] + } +} diff --git a/lib/ovm/utils/buffer-utils.ts b/lib/ovm/utils/buffer-utils.ts new file mode 100644 index 00000000000..3f8732f8d34 --- /dev/null +++ b/lib/ovm/utils/buffer-utils.ts @@ -0,0 +1,15 @@ +export const toHexAddress = (buf: any): string => { + return '0x' + buf.toString('hex').padStart(40, '0') +} + +export const toHexString = (buf: any): string => { + return '0x' + buf.toString('hex') +} + +export const fromHexString = (str: string): Buffer => { + return Buffer.from(str.slice(2), 'hex') +} + +export const toAddressBuf = (address: string | Buffer): Buffer => { + return typeof address === 'string' ? fromHexString(address) : address +} diff --git a/lib/ovm/utils/constants.ts b/lib/ovm/utils/constants.ts new file mode 100644 index 00000000000..6db6dfe4a44 --- /dev/null +++ b/lib/ovm/utils/constants.ts @@ -0,0 +1,6 @@ +const makeNullBytes = (length: number): string => { + return '0x' + '00'.repeat(length) +} + +export const NULL_ADDRESS = makeNullBytes(20) +export const NULL_BYTES32 = makeNullBytes(32) diff --git a/lib/ovm/utils/logger.ts b/lib/ovm/utils/logger.ts new file mode 100644 index 00000000000..e5f5b60efc8 --- /dev/null +++ b/lib/ovm/utils/logger.ts @@ -0,0 +1,53 @@ +import debug, { Debugger } from 'debug' +import { v4 as uuidv4 } from 'uuid' + +export class Logger { + private _namespace: string + private _debugger: Debugger + + constructor(namespace: string) { + this._namespace = namespace + this._debugger = debug(namespace) + } + + log(message: string): void { + this._debugger(message) + } + + scope(namespace: string, section?: string, id?: string): ScopedLogger { + id = id || uuidv4() + return new ScopedLogger(`${this._namespace}:${namespace}:${id}`, section) + } + + getNamespace(): string { + return this._namespace + } +} + +export class ScopedLogger extends Logger { + private _section: string + + constructor(namespace: string, section?: string) { + super(namespace) + + this._section = section || namespace + } + + open(): void { + const sectionStartMessage = `BEGIN: ${this._section}` + + this._logSection(sectionStartMessage) + } + + close(): void { + const sectionEndMessage = `END: ${this._section}` + + this._logSection(sectionEndMessage) + } + + private _logSection(message: string): void { + this.log(`------${'-'.repeat(message.length)}------`) + this.log(`----- ${message} -----`) + this.log(`------${'-'.repeat(message.length)}------`) + } +} diff --git a/package.json b/package.json index c8559ad5852..474f7dbfd5d 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "ethereumjs-vm", + "name": "ethereumjs-ovm", "version": "4.2.0", "description": "An Ethereum VM implementation", "main": "dist/index.js", @@ -7,36 +7,6 @@ "files": [ "dist/**/*" ], - "scripts": { - "build": "ethereumjs-config-build", - "prepublishOnly": "npm run lint && npm run build && npm run test:buildIntegrity", - "coverage": "nyc npm run coverage:test && nyc report --reporter=lcov", - "coverage:test": "npm run build && tape './tests/api/**/*.js' ./tests/tester.js --state --dist", - "docs:build": "typedoc lib", - "test:vm": "node ./tests/tester --vm", - "test:state": "ts-node ./tests/tester --state", - "test:state:allForks": "npm run test:state -- --fork=Byzantium && npm run test:state -- --fork=Constantinople && npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=Istanbul && npm run test:state -- --fork=MuirGlacier", - "test:state:selectedForks": "npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=Istanbul && npm run test:state -- --fork=MuirGlacier", - "test:state:slow": "npm run test:state -- --runSkipped=slow", - "test:buildIntegrity": "npm run test:state -- --test='stackOverflow'", - "test:blockchain": "node -r ts-node/register --stack-size=1500 ./tests/tester --blockchain", - "test:API": "npm run build && ts-node ./node_modules/tape/bin/tape './tests/api/**/*.js'", - "test:API:browser": "npm run build && karma start karma.conf.js", - "test": "echo \"[INFO] Generic test cmd not used. See package.json for more specific test run cmds.\"", - "tslint": "ethereumjs-config-tslint", - "tslint:fix": "ethereumjs-config-tslint-fix", - "lint": "ethereumjs-config-lint", - "lint:fix": "ethereumjs-config-lint-fix", - "format": "ethereumjs-config-format", - "format:fix": "ethereumjs-config-format-fix", - "formatTest": "node ./scripts/formatTest", - "tsc": "ethereumjs-config-tsc" - }, - "husky": { - "hooks": { - "pre-push": "npm run lint" - } - }, "scripts": { "postinstall": "npm run bootstrap", "bootstrap": "lerna bootstrap --ignore-scripts --include-dependencies --no-ci --hoist && npm run build", diff --git a/packages/vm/lib/evm/eei.ts b/packages/vm/lib/evm/eei.ts index 83201cd53e6..716f8bc87a9 100644 --- a/packages/vm/lib/evm/eei.ts +++ b/packages/vm/lib/evm/eei.ts @@ -27,6 +27,9 @@ export interface Env { contract: Account // Different than address for DELEGATECALL and CALLCODE codeAddress: Buffer + + // Custom variables + originalTargetAddress: Buffer } /** @@ -402,6 +405,7 @@ export default class EEI { data: data, isStatic: this._env.isStatic, depth: this._env.depth + 1, + originalTargetAddress: this._env.originalTargetAddress, }) return this._baseCall(msg) @@ -420,6 +424,7 @@ export default class EEI { data: data, isStatic: this._env.isStatic, depth: this._env.depth + 1, + originalTargetAddress: this._env.originalTargetAddress, }) return this._baseCall(msg) @@ -439,6 +444,7 @@ export default class EEI { data: data, isStatic: true, depth: this._env.depth + 1, + originalTargetAddress: this._env.originalTargetAddress, }) return this._baseCall(msg) @@ -459,6 +465,7 @@ export default class EEI { isStatic: this._env.isStatic, delegatecall: true, depth: this._env.depth + 1, + originalTargetAddress: this._env.originalTargetAddress, }) return this._baseCall(msg) @@ -520,6 +527,7 @@ export default class EEI { salt: salt, depth: this._env.depth + 1, selfdestruct: selfdestruct, + originalTargetAddress: this._env.originalTargetAddress, }) // empty the return data buffer diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index 52df32be562..d05e060fa36 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -16,6 +16,7 @@ import TxContext from './txContext' import Message from './message' import EEI from './eei' import { default as Interpreter, InterpreterOpts, RunState } from './interpreter' +import { fromHexString, toHexAddress } from '../ovm/utils/buffer-utils' /** * Result of executing a message via the [[EVM]]. @@ -100,6 +101,10 @@ export default class EVM { */ _refund: BN + // Custom variables + _targetMessage: Message | undefined + _targetMessageResult: EVMResult | undefined + constructor(vm: any, txContext: TxContext, block: any) { this._vm = vm this._state = this._vm.stateManager @@ -118,9 +123,28 @@ export default class EVM { await this._state.checkpoint() + if (message.depth === 0) { + message = message.toOvmMessage(this._vm, this._block || new Block()) + } + + let isTargetMessage = !this._targetMessage && message.isTargetMessage() + if (isTargetMessage) { + this._targetMessage = message + } + let result if (message.to) { - result = await this._executeCall(message) + if (message.to.equals(this._vm.contracts.ovmStateManager.address)) { + result = { + gasUsed: new BN(0), + execResult: { + gasUsed: new BN(0), + returnValue: await this._vm.ovmStateManager.handleCall(message) + }, + } as EVMResult + } else { + result = await this._executeCall(message) + } } else { result = await this._executeCreate(message) } @@ -128,6 +152,32 @@ export default class EVM { // instead of `ExecResult`. result.execResult.gasRefund = this._refund.clone() + if (isTargetMessage) { + this._targetMessageResult = result + } + + if (message.depth === 0) { + if (this._targetMessageResult) { + if (result.execResult.logs) { + result.execResult.logs = result.execResult.logs.filter(log => { + return !log[0].equals(this._vm.contracts.ovmExecutionManager.address) + }) + } + + result = { + ...result, + createdAddress: this._targetMessageResult.createdAddress, + execResult: { + ...result.execResult, + returnValue: this._targetMessageResult.execResult.returnValue, + exceptionError: this._targetMessageResult.execResult.exceptionError, + }, + } + } else { + result.execResult.exceptionError = new VmError(ERROR.OVM_ERROR) + } + } + const err = result.execResult.exceptionError if (err) { result.execResult.logs = [] @@ -307,6 +357,7 @@ export default class EVM { block: this._block || new Block(), contract: await this._state.getAccount(message.to || zeros(32)), codeAddress: message.codeAddress, + originalTargetAddress: message.originalTargetAddress } const eei = new EEI(env, this._state, this, this._vm._common, message.gasLimit.clone()) if (message.selfdestruct) { @@ -387,15 +438,14 @@ export default class EVM { } async _generateAddress(message: Message): Promise { - let addr - if (message.salt) { - addr = generateAddress2(message.caller, message.salt, message.code as Buffer) - } else { - const acc = await this._state.getAccount(message.caller) - const newNonce = new BN(acc.nonce).subn(1) - addr = generateAddress(message.caller, newNonce.toArrayLike(Buffer)) - } - return addr + return fromHexString( + toHexAddress( + await this._vm.pStateManager.getContractStorage( + this._vm.contracts.ovmExecutionManager.address, + Buffer.from('00'.repeat(31) + '06', 'hex'), + ), + ), + ) } async _reduceSenderBalance(account: Account, message: Message): Promise { diff --git a/packages/vm/lib/evm/message.ts b/packages/vm/lib/evm/message.ts index e267e45aee6..80e52dc236f 100644 --- a/packages/vm/lib/evm/message.ts +++ b/packages/vm/lib/evm/message.ts @@ -1,6 +1,12 @@ import BN = require('bn.js') import { PrecompileFunc } from './precompiles' +// OVM imports +import VM from '../index' +import { iExecutionManager } from '../ovm/contracts' +import { toHexString, fromHexString } from '../ovm/utils/buffer-utils' +import { NULL_ADDRESS } from '../ovm/utils/constants' + export default class Message { to: Buffer value: BN @@ -16,6 +22,9 @@ export default class Message { selfdestruct: any delegatecall: boolean + // Custom variables + originalTargetAddress: Buffer + constructor(opts: any) { this.to = opts.to this.value = opts.value ? new BN(opts.value) : new BN(0) @@ -30,9 +39,44 @@ export default class Message { this.salt = opts.salt // For CREATE2, TODO: Move from here this.selfdestruct = opts.selfdestruct // TODO: Move from here this.delegatecall = opts.delegatecall || false + + // Custom variables + this.originalTargetAddress = opts.originalTargetAddress } get codeAddress(): Buffer { return this._codeAddress ? this._codeAddress : this.to } + + isTargetMessage(): boolean { + return ( + (!this.to && !this.originalTargetAddress) || + (this.to && this.originalTargetAddress && this.to.equals(this.originalTargetAddress)) + ) + } + + toOvmMessage(vm: VM, block: any): Message { + if (!vm.contracts.ovmExecutionManager.address) { + throw new Error('Cannot create a message because the ExecutionManager does not exist.') + } + + const calldata = iExecutionManager.encodeFunctionData('executeTransaction', [ + toHexString(new BN(block.header.timestamp).toBuffer()), + 0, + this.to ? toHexString(this.to) : NULL_ADDRESS, + this.data, + toHexString(this.caller), + toHexString(this.caller), + true, + ]) + + return new Message({ + ...this, + ...{ + to: vm.contracts.ovmExecutionManager.address, + data: fromHexString(calldata), + originalTargetAddress: this.to, + }, + }) + } } diff --git a/packages/vm/lib/exceptions.ts b/packages/vm/lib/exceptions.ts index 60a97b04047..3a347a73d3f 100644 --- a/packages/vm/lib/exceptions.ts +++ b/packages/vm/lib/exceptions.ts @@ -12,6 +12,9 @@ export enum ERROR { STOP = 'stop', REFUND_EXHAUSTED = 'refund exhausted', VALUE_OVERFLOW = 'value overflow', + + // Custom variables + OVM_ERROR = 'target contract not reached' } export class VmError { diff --git a/packages/vm/lib/index.ts b/packages/vm/lib/index.ts index 4500104625d..949aa95f180 100644 --- a/packages/vm/lib/index.ts +++ b/packages/vm/lib/index.ts @@ -12,9 +12,37 @@ import { EVMResult, ExecResult } from './evm/evm' import { OpcodeList, getOpcodesForHF } from './evm/opcodes' import { precompiles } from './evm/precompiles' import runBlockchain from './runBlockchain' + +import PStateManager from './state/promisified' +import { OvmStateManager } from './ovm/ovm-state-manager' +const promisify = require('util.promisify') const AsyncEventEmitter = require('async-eventemitter') const promisify = require('util.promisify') +interface OVMContract { + address: Buffer + addressHex: string +} + +interface StorageDump { + [key: string]: string +} + +interface StateDump { + contracts: { + ovmExecutionManager: string + ovmStateManager: string + } + accounts: { + [address: string]: { + balance: number + nonce: number + code: string + storage: StorageDump + } + } +} + /** * Options for instantiating a [[VM]]. */ @@ -56,6 +84,16 @@ export interface VMOpts { */ allowUnlimitedContractSize?: boolean common?: Common + + ovmOpts?: { + initialized?: boolean + emGasLimit?: number + dump?: StateDump + contracts?: { + ovmExecutionManager: OVMContract + ovmStateManager: OVMContract + } + } } /** @@ -85,6 +123,16 @@ export default class VM extends AsyncEventEmitter { return vm } + // Custom variables + emGasLimit: number + initialized: boolean + dump: StateDump | undefined + contracts: { + ovmExecutionManager: OVMContract + ovmStateManager: OVMContract + } + ovmStateManager: OvmStateManager + /** * Instantiates a new [[VM]] Object. * @param opts - Default values for the options are: @@ -137,37 +185,82 @@ export default class VM extends AsyncEventEmitter { this.allowUnlimitedContractSize = opts.allowUnlimitedContractSize === undefined ? false : opts.allowUnlimitedContractSize + // OVM option setup. + const ovmOpts = opts.ovmOpts || {} + this.emGasLimit = ovmOpts.emGasLimit || 100_000_000 + this.dump = ovmOpts.dump + this.initialized = ovmOpts.initialized || false + this.contracts = ovmOpts.contracts || { + ovmExecutionManager: { + address: Buffer.from(''), + addressHex: '0x' + }, + ovmStateManager: { + address: Buffer.from(''), + addressHex: '0x' + }, + } + + // Always need an instance of this. + this.ovmStateManager = new OvmStateManager({ + vm: this + }) + // We cache this promisified function as it's called from the main execution loop, and // promisifying each time has a huge performance impact. this._emit = promisify(this.emit.bind(this)) } async init(): Promise { - if (this.isInitialized) { + if (this.initialized) { return } - const { opts } = this - - if (opts.activatePrecompiles && !opts.stateManager) { - this.stateManager.checkpoint() - // put 1 wei in each of the precompiles in order to make the accounts non-empty and thus not have them deduct `callNewAccount` gas. - await Promise.all( - Object.keys(precompiles) - .map((k: string): Buffer => Buffer.from(k, 'hex')) - .map((address: Buffer) => - this.stateManager.putAccount( - address, - new Account({ - balance: '0x01', - }), - ), - ), - ) - await this.stateManager.commit() + if (!this.dump) { + throw new Error('You must provide a state dump to initialize the OVM.') + } + + this.initialized = true + + let emAddress = this.dump.contracts.ovmExecutionManager + if (emAddress.startsWith('0x')) { + emAddress = emAddress.slice(2) + } + + let smAddress = this.dump.contracts.ovmStateManager + if (smAddress.startsWith('0x')) { + smAddress = smAddress.slice(2) + } + + this.contracts = { + ovmExecutionManager: { + address: Buffer.from(emAddress, 'hex'), + addressHex: '0x' + emAddress + }, + ovmStateManager: { + address: Buffer.from(smAddress, 'hex'), + addressHex: '0x' + smAddress + } } - this.isInitialized = true + for (const [address, account] of Object.entries(this.dump.accounts)) { + await this.pStateManager.putAccount( + Buffer.from(address, 'hex'), new Account() + ) + + await this.pStateManager.putContractCode( + Buffer.from(address, 'hex'), + Buffer.from(account.code, 'hex') + ) + + for (const [key, val] of Object.entries(account.storage)) { + await this.pStateManager.putContractStorage( + Buffer.from(address, 'hex'), + Buffer.from(key, 'hex'), + Buffer.from(val, 'hex') + ) + } + } } /** @@ -237,6 +330,7 @@ export default class VM extends AsyncEventEmitter { stateManager: this.stateManager.copy(), blockchain: this.blockchain, common: this._common, + ovmOpts: this.opts.ovmOpts }) } } From 09c373554eab9880a4dcfe84be713547717f7240 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Fri, 25 Sep 2020 12:01:21 -0400 Subject: [PATCH 04/31] Removed logger --- lib/ovm/ovm-state-manager.ts | 6 ---- lib/ovm/utils/logger.ts | 53 ------------------------------------ 2 files changed, 59 deletions(-) delete mode 100644 lib/ovm/utils/logger.ts diff --git a/lib/ovm/ovm-state-manager.ts b/lib/ovm/ovm-state-manager.ts index 486ce3ee769..70d76c91d26 100644 --- a/lib/ovm/ovm-state-manager.ts +++ b/lib/ovm/ovm-state-manager.ts @@ -6,12 +6,8 @@ import VM from '../index' import Message from '../evm/message' import { fromHexString, toHexString } from './utils/buffer-utils' import { NULL_BYTES32 } from './utils/constants' -import { Logger } from './utils/logger' import { iStateManager } from './contracts' -// TODO: Add comments here -const logger = new Logger('ethereumjs-ovm:ovm-state-manager') - export interface OvmStateManagerOpts { vm: VM } @@ -44,10 +40,8 @@ export class OvmStateManager { const fragment = this._iface.getFunction(methodId) const functionArgs = this._iface.decodeFunctionData(fragment, toHexString(message.data)) - //logger.log(`Calling function: ${fragment.name} with args ${functionArgs}`) const ret = await this._handlers[fragment.name](...functionArgs) const encodedRet = this._iface.encodeFunctionResult(fragment, ret) - //logger.log(`Got result: ${encodedRet}`) return fromHexString(encodedRet) } diff --git a/lib/ovm/utils/logger.ts b/lib/ovm/utils/logger.ts deleted file mode 100644 index e5f5b60efc8..00000000000 --- a/lib/ovm/utils/logger.ts +++ /dev/null @@ -1,53 +0,0 @@ -import debug, { Debugger } from 'debug' -import { v4 as uuidv4 } from 'uuid' - -export class Logger { - private _namespace: string - private _debugger: Debugger - - constructor(namespace: string) { - this._namespace = namespace - this._debugger = debug(namespace) - } - - log(message: string): void { - this._debugger(message) - } - - scope(namespace: string, section?: string, id?: string): ScopedLogger { - id = id || uuidv4() - return new ScopedLogger(`${this._namespace}:${namespace}:${id}`, section) - } - - getNamespace(): string { - return this._namespace - } -} - -export class ScopedLogger extends Logger { - private _section: string - - constructor(namespace: string, section?: string) { - super(namespace) - - this._section = section || namespace - } - - open(): void { - const sectionStartMessage = `BEGIN: ${this._section}` - - this._logSection(sectionStartMessage) - } - - close(): void { - const sectionEndMessage = `END: ${this._section}` - - this._logSection(sectionEndMessage) - } - - private _logSection(message: string): void { - this.log(`------${'-'.repeat(message.length)}------`) - this.log(`----- ${message} -----`) - this.log(`------${'-'.repeat(message.length)}------`) - } -} From b32868198040313b6df5b12eafdf6a8ac9804360 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Fri, 25 Sep 2020 12:01:41 -0400 Subject: [PATCH 05/31] Linted files --- packages/vm/lib/evm/evm.ts | 4 ++-- packages/vm/lib/exceptions.ts | 2 +- packages/vm/lib/index.ts | 22 ++++++++++------------ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index d05e060fa36..a2ae7e3d223 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -139,7 +139,7 @@ export default class EVM { gasUsed: new BN(0), execResult: { gasUsed: new BN(0), - returnValue: await this._vm.ovmStateManager.handleCall(message) + returnValue: await this._vm.ovmStateManager.handleCall(message), }, } as EVMResult } else { @@ -357,7 +357,7 @@ export default class EVM { block: this._block || new Block(), contract: await this._state.getAccount(message.to || zeros(32)), codeAddress: message.codeAddress, - originalTargetAddress: message.originalTargetAddress + originalTargetAddress: message.originalTargetAddress, } const eei = new EEI(env, this._state, this, this._vm._common, message.gasLimit.clone()) if (message.selfdestruct) { diff --git a/packages/vm/lib/exceptions.ts b/packages/vm/lib/exceptions.ts index 3a347a73d3f..efe52150a62 100644 --- a/packages/vm/lib/exceptions.ts +++ b/packages/vm/lib/exceptions.ts @@ -14,7 +14,7 @@ export enum ERROR { VALUE_OVERFLOW = 'value overflow', // Custom variables - OVM_ERROR = 'target contract not reached' + OVM_ERROR = 'target contract not reached', } export class VmError { diff --git a/packages/vm/lib/index.ts b/packages/vm/lib/index.ts index 949aa95f180..a8be78cf5ea 100644 --- a/packages/vm/lib/index.ts +++ b/packages/vm/lib/index.ts @@ -193,17 +193,17 @@ export default class VM extends AsyncEventEmitter { this.contracts = ovmOpts.contracts || { ovmExecutionManager: { address: Buffer.from(''), - addressHex: '0x' + addressHex: '0x', }, ovmStateManager: { address: Buffer.from(''), - addressHex: '0x' + addressHex: '0x', }, } // Always need an instance of this. this.ovmStateManager = new OvmStateManager({ - vm: this + vm: this, }) // We cache this promisified function as it's called from the main execution loop, and @@ -235,29 +235,27 @@ export default class VM extends AsyncEventEmitter { this.contracts = { ovmExecutionManager: { address: Buffer.from(emAddress, 'hex'), - addressHex: '0x' + emAddress + addressHex: '0x' + emAddress, }, ovmStateManager: { address: Buffer.from(smAddress, 'hex'), - addressHex: '0x' + smAddress - } + addressHex: '0x' + smAddress, + }, } for (const [address, account] of Object.entries(this.dump.accounts)) { - await this.pStateManager.putAccount( - Buffer.from(address, 'hex'), new Account() - ) + await this.pStateManager.putAccount(Buffer.from(address, 'hex'), new Account()) await this.pStateManager.putContractCode( Buffer.from(address, 'hex'), - Buffer.from(account.code, 'hex') + Buffer.from(account.code, 'hex'), ) for (const [key, val] of Object.entries(account.storage)) { await this.pStateManager.putContractStorage( Buffer.from(address, 'hex'), Buffer.from(key, 'hex'), - Buffer.from(val, 'hex') + Buffer.from(val, 'hex'), ) } } @@ -330,7 +328,7 @@ export default class VM extends AsyncEventEmitter { stateManager: this.stateManager.copy(), blockchain: this.blockchain, common: this._common, - ovmOpts: this.opts.ovmOpts + ovmOpts: this.opts.ovmOpts, }) } } From a6ce7e53effa64e9ff4b92036325a77883cf0222 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Fri, 25 Sep 2020 15:24:35 -0400 Subject: [PATCH 06/31] Added logging back into the interpreter --- README.md | 127 +++-------------------------- lib/ovm/utils/logger.ts | 48 +++++++++++ packages/vm/lib/evm/interpreter.ts | 106 ++++++++++++++++++++++++ packages/vm/lib/index.ts | 10 +++ 4 files changed, 174 insertions(+), 117 deletions(-) create mode 100644 lib/ovm/utils/logger.ts diff --git a/README.md b/README.md index a9ed2bb0636..27278d173b0 100644 --- a/README.md +++ b/README.md @@ -1,126 +1,19 @@ -

- -

+# ethereumjs-ovm -# EthereumJS Monorepo +Implements Optimism's OVM in Javascript. Forked with <3 from `ethereumjs-vm`! -[![Code Coverage][coverage-badge]][coverage-link] -[![Gitter][gitter-badge]][gitter-link] -[![StackExchange][stackexchange-badge]][stackexchange-link] +## Logging -[![JS Standard Style][js-standard-style-badge]][js-standard-style-link] +This fork provides some custom logging tools for introspecting the OVM via the `debug` package. Particularly, the environment variable `DEBUG='ethjs-ovm:interpreter` will allow you to log various degrees of internal EVM execution such as calls, stack, and memory. -This was originally the EthereumJS VM repository. On Q1 2020 we brought some of its building blocks together to simplify development. Below you can find the packages included in this repository. +Available namespaces are: -🚧 Please note that the `master` branch is updated on a daily basis, and to inspect code related to a specific package version, refer to the [tags](https://github.com/ethereumjs/ethereumjs-vm/tags). +- All OVM debug logging (warning, lots of logs): `DEBUG='ethjs-ovm:interpreter:*'` +- Call logging: `DEBUG='ethjs-ovm:interpreter:calls` +- Step logging: `DEBUG='ethjs-ovm:interpreter:calls:steps` +- Memory logging: `DEBUG='ethjs-ovm:interpreter:calls:memory` -| package | npm | issues | tests | coverage | -| ------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | -| [@ethereumjs/account][account-package] | [![NPM Package][account-npm-badge]][account-npm-link] | [![Account Issues][account-issues-badge]][account-issues-link] | [![Actions Status][account-actions-badge]][account-actions-link] | [![Code Coverage][account-coverage-badge]][account-coverage-link] | -| [@ethereumjs/block][block-package] | [![NPM Package][block-npm-badge]][block-npm-link] | [![Block Issues][block-issues-badge]][block-issues-link] | [![Actions Status][block-actions-badge]][block-actions-link] | [![Code Coverage][block-coverage-badge]][block-coverage-link] | -| [@ethereumjs/blockchain][blockchain-package] | [![NPM Package][blockchain-npm-badge]][blockchain-npm-link] | [![Blockchain Issues][blockchain-issues-badge]][blockchain-issues-link] | [![Actions Status][blockchain-actions-badge]][blockchain-actions-link] | [![Code Coverage][blockchain-coverage-badge]][blockchain-coverage-link] | -| [@ethereumjs/common][common-package] | [![NPM Package][common-npm-badge]][common-npm-link] | [![Common Issues][common-issues-badge]][common-issues-link] | [![Actions Status][common-actions-badge]][common-actions-link] | [![Code Coverage][common-coverage-badge]][common-coverage-link] | -| [@ethereumjs/ethash][ethash-package] | [![NPM Package][ethash-npm-badge]][ethash-npm-link] | [![Ethash Issues][ethash-issues-badge]][ethash-issues-link] | [![Actions Status][ethash-actions-badge]][ethash-actions-link] | [![Code Coverage][ethash-coverage-badge]][ethash-coverage-link] | -| [@ethereumjs/tx][tx-package] | [![NPM Package][tx-npm-badge]][tx-npm-link] | [![Tx Issues][tx-issues-badge]][tx-issues-link] | [![Actions Status][tx-actions-badge]][tx-actions-link] | [![Code Coverage][tx-coverage-badge]][tx-coverage-link] | -| [@ethereumjs/vm][vm-package] | [![NPM Package][vm-npm-badge]][vm-npm-link] | [![VM Issues][vm-issues-badge]][vm-issues-link] | [![Actions Status][vm-actions-badge]][vm-actions-link] | [![Code Coverage][vm-coverage-badge]][vm-coverage-link] | - -## Coverage report - -Detailed version can be seen on [Codecov.io][coverage-link] - -[![Code Coverage](https://codecov.io/gh/ethereumjs/ethereumjs-vm/branch/master/graphs/icicle.svg)][coverage-link] - -## Package dependency relationship - -

- diagram -

- - - -## Development quick start - -This monorepo uses [Lerna](https://lerna.js.org/). It links the local packages together, making development a lot easier. - -TLDR: Setup -```sh -npm install -npm build -``` - -TLDR: To update dependencies and (re-)link packages -```sh -npm run bootstrap -npm build -``` - -Above is the quickest way to set you up. Going down the road, there are two sets of commands: *project* and *package-specific* commands. You can find them at `./package.json` and `./packages/*/package.json`, respectively. Here's a breakdown: - -### Project scripts — run from repository root - -#### `npm install` -Adds dependencies listed in the root package. Also, it executes the `bootstrap` script described below, installing all sub-packages dependencies. - -#### `npm run bootstrap` - -Installs dependencies for all sub-packages, and links them to create an integrated development environment. - -#### `npm run build` - -Produces `dist` files for all sub-packages. This command can be scoped - -#### `npm run build:tree -- --scope @ethereumjs/blockchain` - -Builds all local packages that the provided package (eg: @ethereumjs/blockchain) depends on, and itself. This unusual syntax just means: pass whatever arguments are after `--` to the underlying script. - -If no scope is provided, `npm run build:tree`, will build all sub-packages. - -### Package scripts — run from `./packages/` - - **⚠️ Important: if you run `npm install` from the package directory, it will remove all links to the local packages, pulling all dependencies from npm. Run `npm install` from the root only.** - -There's a set of rather standardized commands you will find in each package of this repository. - -#### `npm run build` - -Uses TypeScript compiler to build files from `src` or `lib`. Files can be found at `packages//dist`. - -#### `npm run coverage` - -Runs whatever is on `npm run test` script, capturing coverage information. By the end, it displays a coverage table. Additional reports can be found at `packages//coverage`. - -#### `npm run docs:build` - -Generates package documentation and outputs it to `./packages//docs`. - -#### `npm run lint` - -Checks code style, according to the rules defined in [ethereumjs-config](https://github.com/ethereumjs/ethereumjs-config). - -#### `npm run lint:fix` - -Fixes code style, according to the rules - -#### `npm run test` - -Runs all package tests. Note that the VM have several test scopes. Refer to their package.json for more info. - -### Going further - -As this project is powered by Lerna, you can install it globally to enjoy lots more options. Refer to [Lerna docs](https://github.com/lerna/lerna/tree/master/commands/run) for additional commands. - -- `npm install -g lerna` -- `lerna run` -- `lerna exec` -- `lerna clean` - -# EthereumJS - -See our organizational [documentation](https://ethereumjs.readthedocs.io) for an introduction to `EthereumJS` as well as information on current standards and best practices. - -If you want to join for work or do improvements on the libraries have a look at our [contribution guidelines](https://ethereumjs.readthedocs.io/en/latest/contributing.html). +Or mix and match any of the above to get your desired logging level. # LICENSE diff --git a/lib/ovm/utils/logger.ts b/lib/ovm/utils/logger.ts new file mode 100644 index 00000000000..a3206acb5cb --- /dev/null +++ b/lib/ovm/utils/logger.ts @@ -0,0 +1,48 @@ +import debug, { Debugger } from 'debug' +import { v4 as uuidv4 } from 'uuid' + +export class Logger { + private _namespace: string + private _debugger: Debugger + private _section: string | undefined + + constructor(namespace: string) { + this._namespace = namespace + this._debugger = debug(namespace) + } + + log(message: string): void { + this._debugger(message) + } + + scope(namespace: string, id?: string): Logger { + return new Logger(`${this._namespace}:${namespace}:${id || uuidv4()}`) + } + + get enabled(): boolean { + return this._debugger.enabled + } + + get namespace(): string { + return this._namespace + } + + logSection(message: string): void { + this.log(`------${'-'.repeat(message.length)}------`) + this.log(`----- ${message} -----`) + this.log(`------${'-'.repeat(message.length)}------`) + } + + open(message: string): void { + this._section = message + this.logSection(`BEGIN: ${this._section}`) + } + + close(): void { + if (!this._section) { + return + } + + this.logSection(`END : ${this._section}`) + } +} diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index 2a8fa536563..46e6536318f 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -9,6 +9,13 @@ import EEI from './eei' import { Opcode } from './opcodes' import { handlers as opHandlers, OpHandler } from './opFns' +import { Logger } from '../ovm/utils/logger' +import { env } from 'process' +import { toHexAddress, toHexString } from '../ovm/utils/buffer-utils' +import { iExecutionManager } from '../ovm/contracts' + +const logger = new Logger('ethjs-ovm:interpreter') + export interface InterpreterOpts { pc?: number } @@ -58,6 +65,14 @@ export default class Interpreter { _state: StateManager _runState: RunState _eei: EEI + _printNextMemory: boolean = false + _loggers: { + [depth: number]: { + callLogger: Logger + stepLogger: Logger + memLogger: Logger + } + } constructor(vm: any, eei: EEI) { this._vm = vm // TODO: remove when not needed @@ -77,6 +92,8 @@ export default class Interpreter { stateManager: this._state, eei: this._eei, } + + this._loggers = {} } async run(code: Buffer, opts: InterpreterOpts = {}): Promise { @@ -175,6 +192,13 @@ export default class Interpreter { memoryWordCount: this._runState.memoryWordCount, codeAddress: this._eei._env.codeAddress, } + + try { + this._logStep(eventObj) + } catch (err) { + logger.log(`STEP LOGGING ERROR: ${err.toString()}`) + } + /** * The `step` event for trace output * @@ -213,4 +237,86 @@ export default class Interpreter { return jumps } + + _logStep(step: InterpreterStep): void { + if (!env.DEBUG?.includes(logger.namespace)) { + return + } + + if (!(step.depth in this._loggers)) { + const contractName = this._vm.getContractName(step.address) + const description = step.depth === 0 ? 'OVM TX starts with' : 'EVM STEPS for' + + const callLogger = new Logger(logger.namespace + ':calls') + const stepLogger = new Logger(callLogger.namespace + ':steps') + const memLogger = new Logger(callLogger.namespace + ':memory') + + callLogger.open(`${description} ${contractName} at depth ${step.depth}`) + + this._loggers[step.depth] = { + callLogger, + stepLogger, + memLogger, + } + } + + const loggers = this._loggers[step.depth] + const stack = new Array(...step.stack).reverse() + const memory = step.memory + const op = step.opcode.name + + if (op === 'RETURN' || op === 'REVERT') { + const offset = stack[0].toNumber() + const length = stack[1].toNumber() + + const data = Buffer.from(memory.slice(offset, offset + length)) + + loggers.callLogger.log(`${op} with data: ${toHexString(data)}`) + loggers.callLogger.close() + delete this._loggers[step.depth] + } else if (op === 'CALL') { + const target = stack[1].toBuffer() + const offset = stack[3].toNumber() + const length = stack[4].toNumber() + + const calldata = Buffer.from(memory.slice(offset, offset + length)) + + if (target.equals(this._vm.contracts.ovmExecutionManager.address)) { + const sighash = toHexString(calldata.slice(0, 4)) + const fragment = iExecutionManager.getFunction(sighash) + const functionName = fragment.name + const functionArgs = iExecutionManager.decodeFunctionData( + fragment, + toHexString(calldata), + ) as any[] + + loggers.callLogger.log( + `CALL to OVM_ExecutionManager.${functionName}\nDecoded calldata: ${functionArgs}\nEncoded calldata: ${toHexString( + calldata.slice(4), + )}`, + ) + } else { + loggers.callLogger.log( + `CALL to ${toHexAddress(target)} with data:\n${toHexString(calldata)}`, + ) + } + } else { + loggers.stepLogger.log( + `opcode: ${op.padEnd(20, ' ')}\npc: ${step.pc}\nstack: [${stack + .map((el, idx) => { + return `${idx}: ${toHexString(el)}` + }) + .join('')}]\n`, + ) + + if ( + this._printNextMemory || + ['CALL', 'CREATE', 'CREATE2', 'STATICCALL', 'DELEGATECALL'].includes(op) + ) { + loggers.memLogger.log(`memory: [${toHexString(Buffer.from(memory))}]`) + } + + this._printNextMemory = ['MSTORE', 'CALLDATACOPY', 'RETURNDATACOPY', 'CODECOPY'].includes(op) + } + } } diff --git a/packages/vm/lib/index.ts b/packages/vm/lib/index.ts index a8be78cf5ea..1394e0a5ee5 100644 --- a/packages/vm/lib/index.ts +++ b/packages/vm/lib/index.ts @@ -331,4 +331,14 @@ export default class VM extends AsyncEventEmitter { ovmOpts: this.opts.ovmOpts, }) } + + getContractName(address: Buffer) { + if (address.equals(this.contracts.ovmExecutionManager.address)) { + return 'OVM_ExecutionManager' + } else if (address.equals(this.contracts.ovmStateManager.address)) { + return 'OVM_StateManager' + } else { + return `UNKNOWN CONTRACT (${'0x' + address.toString('hex')})` + } + } } From 89223b3fcf74c949cf2c1170fb8e79df47548079 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Mon, 28 Sep 2020 13:12:27 -0400 Subject: [PATCH 07/31] Skip balance and nonce checks --- packages/vm/lib/runTx.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/vm/lib/runTx.ts b/packages/vm/lib/runTx.ts index 8b2822f2118..81da56ecf6a 100644 --- a/packages/vm/lib/runTx.ts +++ b/packages/vm/lib/runTx.ts @@ -85,6 +85,10 @@ export default async function runTx(this: VM, opts: RunTxOpts): Promise { + // Skip these checks because we don't have these concepts in the OVM. + opts.skipBalance = true + opts.skipNonce = true + const block = opts.block const tx = opts.tx const state = this.stateManager From bb5d95490e83b595b10457256273c435d061e428 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Mon, 28 Sep 2020 13:35:10 -0400 Subject: [PATCH 08/31] Updated package.json --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 474f7dbfd5d..b47b991749b 100644 --- a/package.json +++ b/package.json @@ -30,5 +30,4 @@ "lint:fix": "lerna run lint:fix --stream --parallel", "test": "lerna exec npm run test --parallel", "coverage": "lerna run coverage --stream" - } } From 9bfb4b9c83043b9bc14fc987375b192cfe674b76 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Mon, 5 Oct 2020 18:51:55 -0400 Subject: [PATCH 09/31] Added experimental logging fix --- packages/vm/lib/evm/interpreter.ts | 2 +- packages/vm/lib/index.ts | 17 ++++++++++++- packages/vm/lib/runTx.ts | 38 ++++++++++++++---------------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index 46e6536318f..3c2bb410d87 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -239,7 +239,7 @@ export default class Interpreter { } _logStep(step: InterpreterStep): void { - if (!env.DEBUG?.includes(logger.namespace)) { + if (!env.DEBUG?.includes(logger.namespace) && !logger.enabled) { return } diff --git a/packages/vm/lib/index.ts b/packages/vm/lib/index.ts index 1394e0a5ee5..a1bd0041856 100644 --- a/packages/vm/lib/index.ts +++ b/packages/vm/lib/index.ts @@ -208,7 +208,22 @@ export default class VM extends AsyncEventEmitter { // We cache this promisified function as it's called from the main execution loop, and // promisifying each time has a huge performance impact. - this._emit = promisify(this.emit.bind(this)) + const emit = promisify(this.emit.bind(this)) + this._emit = async (topic: string, data: any): Promise => { + if (data) { + const addresses = [data.address, data.to] + for (const address of addresses) { + if (address) { + const addr = address.toString('hex') + if (addr.startsWith('c0dec0dec0de') || addr.startsWith('deaddeaddead')) { + return + } + } + } + } + + emit(topic, data) + } } async init(): Promise { diff --git a/packages/vm/lib/runTx.ts b/packages/vm/lib/runTx.ts index 81da56ecf6a..8d5315c6ed6 100644 --- a/packages/vm/lib/runTx.ts +++ b/packages/vm/lib/runTx.ts @@ -127,11 +127,11 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { ) } // Update from account's nonce and balance - fromAccount.nonce = toBuffer(new BN(fromAccount.nonce).addn(1)) - fromAccount.balance = toBuffer( - new BN(fromAccount.balance).sub(new BN(tx.gasLimit).mul(new BN(tx.gasPrice))), - ) - await state.putAccount(tx.getSenderAddress(), fromAccount) + // fromAccount.nonce = toBuffer(new BN(fromAccount.nonce).addn(1)) + // fromAccount.balance = toBuffer( + // new BN(fromAccount.balance).sub(new BN(tx.gasLimit).mul(new BN(tx.gasPrice))), + // ) + // await state.putAccount(tx.getSenderAddress(), fromAccount) /* * Execute message @@ -139,7 +139,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { const txContext = new TxContext(tx.gasPrice, tx.getSenderAddress()) const message = new Message({ caller: tx.getSenderAddress(), - gasLimit: gasLimit, + gasLimit: gasLimit.mul(new BN(5)), // TODO: Find a cleaner way to do this, it works for now though. to: tx.to.toString('hex') !== '' ? tx.to : undefined, value: tx.value, data: tx.data, @@ -166,23 +166,21 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { results.amountSpent = results.gasUsed.mul(new BN(tx.gasPrice)) // Update sender's balance - fromAccount = await state.getAccount(tx.getSenderAddress()) - const finalFromBalance = new BN(tx.gasLimit) - .sub(results.gasUsed) - .mul(new BN(tx.gasPrice)) - .add(new BN(fromAccount.balance)) - fromAccount.balance = toBuffer(finalFromBalance) - await state.putAccount(toBuffer(tx.getSenderAddress()), fromAccount) + // fromAccount = await state.getAccount(tx.getSenderAddress()) + // const finalFromBalance = new BN(tx.gasLimit) + // .sub(results.gasUsed) + // .mul(new BN(tx.gasPrice)) + // .add(new BN(fromAccount.balance)) + // fromAccount.balance = toBuffer(finalFromBalance) + // await state.putAccount(toBuffer(tx.getSenderAddress()), fromAccount) // Update miner's balance - const minerAccount = await state.getAccount(block.header.coinbase) + // const minerAccount = await state.getAccount(block.header.coinbase) // add the amount spent on gas to the miner's account - minerAccount.balance = toBuffer(new BN(minerAccount.balance).add(results.amountSpent)) - - // Put the miner account into the state. If the balance of the miner account remains zero, note that - // the state.putAccount function puts this into the "touched" accounts. This will thus be removed when - // we clean the touched accounts below in case we are in a fork >= SpuriousDragon - await state.putAccount(block.header.coinbase, minerAccount) + // minerAccount.balance = toBuffer(new BN(minerAccount.balance).add(results.amountSpent)) + // if (!new BN(minerAccount.balance).isZero()) { + // await state.putAccount(block.header.coinbase, minerAccount) + // } /* * Cleanup accounts From b01eb136090fa9b82e901f6cd077a5a42529d1b4 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Wed, 7 Oct 2020 17:15:29 -0400 Subject: [PATCH 10/31] Started contracts v2 migration --- lib/ovm/contracts/defs/ExecutionManager.json | 445 ------------------- lib/ovm/contracts/defs/StateManager.json | 283 ------------ lib/ovm/contracts/index.ts | 8 - lib/ovm/ovm-state-manager.ts | 112 +++-- lib/ovm/utils/buffer-utils.ts | 6 +- packages/vm/lib/evm/evm.ts | 74 ++- packages/vm/lib/evm/interpreter.ts | 7 +- packages/vm/lib/evm/message.ts | 30 +- packages/vm/lib/index.ts | 104 ++--- packages/vm/lib/runTx.ts | 5 +- 10 files changed, 214 insertions(+), 860 deletions(-) delete mode 100644 lib/ovm/contracts/defs/ExecutionManager.json delete mode 100644 lib/ovm/contracts/defs/StateManager.json delete mode 100644 lib/ovm/contracts/index.ts diff --git a/lib/ovm/contracts/defs/ExecutionManager.json b/lib/ovm/contracts/defs/ExecutionManager.json deleted file mode 100644 index cf888ff9a64..00000000000 --- a/lib/ovm/contracts/defs/ExecutionManager.json +++ /dev/null @@ -1,445 +0,0 @@ -{ - "contractName": "ExecutionManager", - "abi": [ - { - "inputs": [ - { - "internalType": "address", - "name": "_addressResolver", - "type": "address" - }, - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "OvmTxBaseGasFee", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "OvmTxMaxGas", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "GasRateLimitEpochSeconds", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "MaxSequencedGasPerEpoch", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "MaxQueuedGasPerEpoch", - "type": "uint256" - } - ], - "internalType": "struct DataTypes.GasMeterConfig", - "name": "_gasMeterConfig", - "type": "tuple" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "uint256", - "name": "_timestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_queueOrigin", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_nonce", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_ovmEntrypoint", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_callBytes", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_v", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_s", - "type": "bytes32" - } - ], - "name": "executeEOACall", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "uint256", - "name": "_timestamp", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "_queueOrigin", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_ovmEntrypoint", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_callBytes", - "type": "bytes" - }, - { - "internalType": "address", - "name": "_fromAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "_l1MsgSenderAddress", - "type": "address" - }, - { - "internalType": "bool", - "name": "_allowRevert", - "type": "bool" - } - ], - "name": "executeTransaction", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "getL1MessageSender", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "getStateManagerAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "isStaticContext", - "outputs": [], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ovmADDRESS", - "outputs": [], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ovmBlockGasLimit", - "outputs": [], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "ovmCALL", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ovmCALLER", - "outputs": [], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ovmCHAINID", - "outputs": [], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "ovmCREATE", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "ovmCREATE2", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "ovmDELEGATECALL", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "ovmEXTCODECOPY", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "ovmEXTCODEHASH", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "ovmEXTCODESIZE", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ovmGASLIMIT", - "outputs": [], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ovmNUMBER", - "outputs": [], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ovmORIGIN", - "outputs": [], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ovmQueueOrigin", - "outputs": [], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "ovmSLOAD", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "ovmSSTORE", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [], - "name": "ovmSTATICCALL", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "ovmTIMESTAMP", - "outputs": [], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "internalType": "uint256", - "name": "_nonce", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "bytes", - "name": "_callData", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "_v", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "_r", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_s", - "type": "bytes32" - } - ], - "name": "recoverEOAAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "internalType": "string", - "name": "_name", - "type": "string" - } - ], - "name": "resolveContract", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_stateManagerAddress", - "type": "address" - } - ], - "name": "setStateManager", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x60806040523480156200001157600080fd5b506040516200343e3803806200343e83398101604081905262000034916200042d565b600080546001600160a01b0319166001600160a01b0385161781556200005962000275565b905060015b6014816001600160a01b03161015620000e257604051636b8b57e160e01b81526001600160a01b03831690636b8b57e190620000a19084908190600401620004ed565b600060405180830381600087803b158015620000bc57600080fd5b505af1158015620000d1573d6000803e3d6000fd5b5050600190920191506200005e9050565b50600030604051620000f4906200033e565b620001009190620004dd565b604051809103906000f0801580156200011d573d6000803e3d6000fd5b50604051636b8b57e160e01b81529091506001600160a01b03831690636b8b57e1906200015590602160991b90859060040162000513565b600060405180830381600087803b1580156200017057600080fd5b505af115801562000185573d6000803e3d6000fd5b505050506000306040516200019a906200034c565b620001a69190620004dd565b604051809103906000f080158015620001c3573d6000803e3d6000fd5b50604051636b8b57e160e01b81529091506001600160a01b03841690636b8b57e1906200020b9073420000000000000000000000000000000000000190859060040162000513565b600060405180830381600087803b1580156200022657600080fd5b505af11580156200023b573d6000803e3d6000fd5b50506101a460025550508351600b555050506020810151600c556040810151600d556060810151600e5560800151600f5550620006049050565b6000620002ac6040518060400160405280600c81526020016b29ba30ba32a6b0b730b3b2b960a11b815250620002b160201b60201c565b905090565b6000805460405163bf40fac160e01b81526001600160a01b039091169063bf40fac190620002e490859060040162000532565b60206040518083038186803b158015620002fd57600080fd5b505afa15801562000312573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525062000338919081019062000404565b92915050565b6102978062002f4a83390190565b61025d80620031e183390190565b80516200033881620005df565b600060a082840312156200037a57600080fd5b6200038660a062000545565b90506000620003968484620003f7565b8252506020620003a984848301620003f7565b6020830152506040620003bf84828501620003f7565b6040830152506060620003d584828501620003f7565b6060830152506080620003eb84828501620003f7565b60808301525092915050565b80516200033881620005f9565b6000602082840312156200041757600080fd5b60006200042584846200035a565b949350505050565b600080600060e084860312156200044357600080fd5b60006200045186866200035a565b935050602062000464868287016200035a565b9250506040620004778682870162000367565b9150509250925092565b6200048c816200058e565b82525050565b6200048c8162000579565b6000620004aa826200056c565b620004b6818562000570565b9350620004c8818560208601620005a2565b620004d381620005d5565b9093019392505050565b6020810162000338828462000492565b60408101620004fd828562000481565b6200050c602083018462000481565b9392505050565b6040810162000523828562000492565b6200050c602083018462000492565b602080825281016200050c81846200049d565b6040518181016001600160401b03811182821017156200056457600080fd5b604052919050565b5190565b90815260200190565b60006001600160a01b03821662000338565b90565b600062000338826000620003388262000579565b60005b83811015620005bf578181015183820152602001620005a5565b83811115620005cf576000848401525b50505050565b601f01601f191690565b620005ea8162000579565b8114620005f657600080fd5b50565b620005ea816200058b565b61293680620006146000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806373509064116100f9578063bdbf8c3611610097578063d203410611610071578063d2034106146102aa578063d8178e3d146102b2578063f55c5c72146102ba578063fbb0f79d146102cd576101a9565b8063bdbf8c3614610292578063c3382d0f1461029a578063c8645416146102a2576101a9565b80638e03b2d1116100d35780638e03b2d114610272578063905802561461027a578063996d79a514610282578063b0168ba31461028a576101a9565b8063735090641461024f57806377a5a62f146102575780637aec0a921461026a576101a9565b806345e97ddb116101665780634c6d7c84116101405780634c6d7c84146102195780635a98c361146102215780635c8e0129146102295780635cbccd461461023c576101a9565b806345e97ddb1461020157806349d65ff9146102095780634ba8746f14610211576101a9565b8063035a2005146101ae57806316902d57146101cc57806320160f3a146101d657806320966208146101de578063232cdee6146101e657806328dcb2a0146101f9575b600080fd5b6101b66102d5565b6040516101c39190612651565b60405180910390f35b6101d46102e6565b005b6101d4610331565b6101d461033f565b6101b66101f4366004611eb9565b6103e5565b6101d461046e565b6101d4610511565b6101d46105e1565b6101d4610796565b6101d46107a4565b6101d461089b565b6101d4610237366004611f8d565b6108a9565b6101d461024a366004612041565b610b52565b6101d4610c4e565b6101d4610265366004611e04565b610c90565b6101d4610cf5565b6101d4610dbd565b6101d4610e6b565b6101d4610e7a565b6101d4610ebc565b6101d4610eca565b6101d4610ed8565b6101d4610f7e565b6101b6610fa5565b6101d461103a565b6101b66102c8366004611eee565b6110ab565b6101d46112ed565b6000806102e06113fe565b91505090565b6008546001600160a01b03166103175760405162461bcd60e51b815260040161030e9061270c565b60405180910390fd5b6008546040516001600160a01b0390911680825290602081f35b600a54604051818152602081f35b60006103496113fe565b6006546040516362c510a360e01b815291925060048035926000926001600160a01b03808716936362c510a393610386939092169187910161267a565b602060405180830381600087803b1580156103a057600080fd5b505af11580156103b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103d89190810190611e66565b9050604051818152602081f35b6000805460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906104169085906004016126fb565b60206040518083038186803b15801561042e57600080fd5b505afa158015610442573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104669190810190611e2a565b90505b919050565b60006104786113fe565b60015490915060ff161561049e5760405162461bcd60e51b815260040161030e906127cb565b6006546040516339e503ab60e01b81526004803592602435926001600160a01b03808716936339e503ab936104da939216918791879101612695565b600060405180830381600087803b1580156104f457600080fd5b505af1158015610508573d6000803e3d6000fd5b50505050505050565b600061051b6113fe565b604080516023193680830182019093529293509101906010358260248337604051633dec5d8560e01b8152606082901c906000906001600160a01b03871690633dec5d859061056e908590600401612651565b602060405180830381600087803b15801561058857600080fd5b505af115801561059c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105c09190810190611e2a565b905060008086866000855af16040513d6000823e816105dd573d81fd5b3d81f35b60006105eb6113fe565b60015490915060ff16156106055760405160008152602081f35b604051600319360180825280600460208401378101602081016040819052600654630e7d0fff60e01b9091526001600160a01b0390811691600091851690630e7d0fff90610657908590602401612651565b602060405180830381600087803b15801561067157600080fd5b505af1158015610685573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106a99190810190611e66565b905060006106b78383611432565b90506106c381856114ce565b6040516333dda11760e11b81526001600160a01b038616906367bb422e906106ef908490600401612651565b600060405180830381600087803b15801561070957600080fd5b505af115801561071d573d6000803e3d6000fd5b505060405163d909aa5360e01b81526001600160a01b038816925063d909aa53915061074d908690600401612651565b600060405180830381600087803b15801561076757600080fd5b505af115801561077b573d6000803e3d6000fd5b50506040516001600160a01b03841680825292509050602081f35b600c54604051818152602081f35b60006107ae6113fe565b604080516023193680830182019093529293509101906010358260248337606081901c6000806107dd8361172f565b915091506000876001600160a01b0316633dec5d85856040518263ffffffff1660e01b815260040161080f9190612651565b602060405180830381600087803b15801561082957600080fd5b505af115801561083d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108619190810190611e2a565b9050606060008060008a8a6000875af160405192503d6000843e80610884573d83fd5b50503d8181016040526108978585611763565b8082f35b600454604051818152602081f35b60006108b36113fe565b90506108c58860008987876000611794565b6108ce8461172f565b5060009050806001600160a01b038816158015610a36576108ed6117e2565b6001600160a01b031663b1540a01886040518263ffffffff1660e01b81526004016109189190612651565b60206040518083038186803b15801561093057600080fd5b505afa158015610944573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109689190810190611e48565b6109845760405162461bcd60e51b815260040161030e9061272c565b60e06040516109929061263b565b6040518091039020901c9250875160040191506000610a2e88866001600160a01b0316630e7d0fff8b6040518263ffffffff1660e01b81526004016109d79190612651565b602060405180830381600087803b1580156109f157600080fd5b505af1158015610a05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a299190810190611e66565b611432565b905050610ab6565b60e0604051610a4490612646565b6040519081900381208a5163d909aa5360e01b8352921c9450602490910192506001600160a01b0385169063d909aa5390610a83908a90600401612651565b600060405180830381600087803b158015610a9d57600080fd5b505af1158015610ab1573d6000803e3d6000fd5b505050505b80610ac657888852600319909701965b6001811415610ad657601c880197505b8260181c88538260101c60018901538260081c600289015382600389015360006060818080868d82305af192503d9050604051915060208201816000823e8183528101604052602082016001841415610b2d578181f35b6001891415610b3a578181fd5b5082610b4257005b5050505050505050505050505050565b6000610b5c6113fe565b90506000610b6e8888888888886110ab565b90506001600160a01b038116610b965760405162461bcd60e51b815260040161030e9061274c565b604051630e7d0fff60e01b81526001600160a01b03831690630e7d0fff90610bc2908490600401612651565b602060405180830381600087803b158015610bdc57600080fd5b505af1158015610bf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c149190810190611e66565b8814610c325760405162461bcd60e51b815260040161030e9061273c565b610c428a8a8989856000806108a9565b50505050505050505050565b6007546001600160a01b0316610c765760405162461bcd60e51b815260040161030e9061271c565b6007546040516001600160a01b0390911680825290602081f35b600054604051639b2ea4bd60e01b81526001600160a01b0390911690639b2ea4bd90610cc09084906004016127ac565b600060405180830381600087803b158015610cda57600080fd5b505af1158015610cee573d6000803e3d6000fd5b5050505050565b6000610cff6113fe565b604051633dec5d8560e01b815290915060103590606082901c906000906001600160a01b03851690633dec5d8590610d3b908590600401612651565b602060405180830381600087803b158015610d5557600080fd5b505af1158015610d69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d8d9190810190611e2a565b90506000846001600160a01b031663dfcac77d836040518263ffffffff1660e01b81526004016103869190612651565b6000610dc76113fe565b604051633dec5d8560e01b8152909150601035906024359060443590606084901c906000906001600160a01b03871690633dec5d8590610e0b908590600401612651565b602060405180830381600087803b158015610e2557600080fd5b505af1158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e5d9190810190611e2a565b9050604051838582843c8381f35b6040516101a480825290602081f35b6006546001600160a01b0316610ea25760405162461bcd60e51b815260040161030e9061279c565b6006546040516001600160a01b0390911680825290602081f35b600554604051818152602081f35b600354604051818152602081f35b6000610ee26113fe565b604051633dec5d8560e01b815290915060103590606082901c906000906001600160a01b03851690633dec5d8590610f1e908590600401612651565b602060405180830381600087803b158015610f3857600080fd5b505af1158015610f4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f709190810190611e2a565b9050604051813b8152602081f35b60015460009060ff16610f92576000610f95565b60015b60ff169050604051818152602081f35b6006546000906001600160a01b03166001602160991b0114610fd95760405162461bcd60e51b815260040161030e906127db565b6009546001600160a01b03166110015760405162461bcd60e51b815260040161030e9061275c565b6007546001600160a01b03161561102a5760405162461bcd60e51b815260040161030e9061278c565b506009546001600160a01b031690565b60015460ff16156110515760405160008152602081f35b604051602319360180825260043590806024602085013782016020016040526006546001600160a01b03166000611089828486611816565b905061109581856114ce565b6040516001600160a01b03821680825290602081f35b604080516009808252610140820190925260009160609190816020015b60608152602001906001900390816110c85790505090506110e888611867565b816000815181106110f557fe5b602002602001018190525061110a6000611867565b8160018151811061111757fe5b6020026020010181905250611130600b60010154611867565b8160028151811061113d57fe5b60209081029190910101526001600160a01b03871661117d576111606000611867565b8160038151811061116d57fe5b602002602001018190525061119f565b6111868761187a565b8160038151811061119357fe5b60200260200101819052505b6111a96000611867565b816004815181106111b657fe5b60200260200101819052506111ca86611899565b816005815181106111d757fe5b60200260200101819052506111ef6001800154611867565b816006815181106111fc57fe5b60200260200101819052506112116000611867565b8160078151811061121e57fe5b60200260200101819052506112336000611867565b8160088151811061124057fe5b60200260200101819052506060611256826118e2565b905060008160405160200161126b919061262f565b604051602081830303815290604052805190602001209050600181600860018001546002028a03038888604051600081526020016040526040516112b294939291906126bd565b6020604051602081039080840390855afa1580156112d4573d6000803e3d6000fd5b5050604051601f1901519b9a5050505050505050505050565b60006112f76113fe565b6040805160231936808301820190935292935091019060103582602483376001805460ff198116821790915560ff16606082901c6000806113378361172f565b915091506000886001600160a01b0316633dec5d85856040518263ffffffff1660e01b81526004016113699190612651565b602060405180830381600087803b15801561138357600080fd5b505af1158015611397573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113bb9190810190611e2a565b9050606060008060008b8b6000875af160405192503d6000843e3d9150806113e1573d83fd5b506113ec8585611763565b6001805460ff19168815151790558082f35b600061142d6040518060400160405280600c81526020016b29ba30ba32a6b0b730b3b2b960a11b8152506103e5565b905090565b60408051600280825260608281019093526000929190816020015b606081526020019060019003908161144d57905050905061146d8461187a565b8160008151811061147a57fe5b602002602001018190525061148e83611867565b8160018151811061149b57fe5b602002602001018190525060606114b1826118e2565b90506114c38180519060200120611905565b925050505b92915050565b60006114d86113fe565b905060006114e4611911565b6040516352275acd60e11b81529091506001600160a01b0382169063a44eb59a906115139086906004016126fb565b60206040518083038186803b15801561152b57600080fd5b505afa15801561153f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115639190810190611e48565b61157f5760405162461bcd60e51b815260040161030e9061277c565b60008061158b8661172f565b91509150600061159a86611941565b90506060856001600160a01b031663d7b5555e836040518263ffffffff1660e01b81526004016115ca9190612651565b600060405180830381600087803b1580156115e457600080fd5b505af11580156115f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116209190810190611e84565b6040516352275acd60e11b81529091506001600160a01b0386169063a44eb59a9061164f9084906004016126fb565b60206040518083038186803b15801561166757600080fd5b505afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061169f9190810190611e48565b6116bb5760405162461bcd60e51b815260040161030e9061276c565b604051636b8b57e160e01b81526001600160a01b03871690636b8b57e1906116e9908b90869060040161265f565b600060405180830381600087803b15801561170357600080fd5b505af1158015611717573d6000803e3d6000fd5b505050506117258484611763565b5050505050505050565b60068054600780546001600160a01b03198084166001600160a01b0396871617909455918416928216831790559190911691565b600680546001600160a01b039283166001600160a01b03199182161790915560078054939092169216919091179055565b61179f600080611763565b600395909555600493909355600591909155600880546001600160a01b039283166001600160a01b03199182161790915560098054929093169116179055600a55565b600061142d6040518060400160405280601181526020017011195c1b1bde595c95da1a5d195b1a5cdd607a1b8152506103e5565b60008060ff60f81b8585858051906020012060405160200161183b94939291906125e7565b60405160208183030381529060405280519060200120905061185c81611905565b9150505b9392505050565b606061046661187583611952565b611899565b60408051600560a21b8318601482015260348101909152606090611860815b606080825160011480156118c157506080836000815181106118b757fe5b016020015160f81c105b156118cd575081610466565b6118606118dc84516080611a44565b84611b7d565b6060806118ee83611bfa565b90506118606118ff825160c0611a44565b82611b7d565b6001600160a01b031690565b600061142d6040518060400160405280600d81526020016c29b0b332ba3ca1b432b1b5b2b960991b8152506103e5565b60008151602083016000f092915050565b60408051602080825281830190925260609182919060208201818038833950505060208101849052905060005b60208110156119b55781818151811061199457fe5b01602001516001600160f81b031916156119ad576119b5565b60010161197f565b6060816020036040519080825280601f01601f1916602001820160405280156119e5576020820181803883390190505b50905060005b8151811015611a3b578351600184019385918110611a0557fe5b602001015160f81c60f81b828281518110611a1c57fe5b60200101906001600160f81b031916908160001a9053506001016119eb565b50949350505050565b6060806038841015611a9e576040805160018082528183019092529060208201818038833901905050905082840160f81b81600081518110611a8257fe5b60200101906001600160f81b031916908160001a905350611860565b600060015b808681611aac57fe5b0415611ac15760019091019061010002611aa3565b816001016040519080825280601f01601f191660200182016040528015611aef576020820181803883390190505b50925084820160370160f81b83600081518110611b0857fe5b60200101906001600160f81b031916908160001a905350600190505b818111611b74576101008183036101000a8781611b3d57fe5b0481611b4557fe5b0660f81b838281518110611b5557fe5b60200101906001600160f81b031916908160001a905350600101611b24565b50509392505050565b6060806040519050835180825260208201818101602087015b81831015611bae578051835260209283019201611b96565b50855184518101855292509050808201602086015b81831015611bdb578051835260209283019201611bc3565b508651929092011591909101601f01601f191660405250905092915050565b6060815160001415611c1b5750604080516000815260208101909152610469565b6000805b8351811015611c4e57838181518110611c3457fe5b602002602001015151820191508080600101915050611c1f565b6060826040519080825280601f01601f191660200182016040528015611c7b576020820181803883390190505b50600092509050602081015b8551831015611a3b576060868481518110611c9e57fe5b602002602001015190506000602082019050611cbc83828451611ce4565b878581518110611cc857fe5b6020026020010151518301925050508280600101935050611c87565b8282825b60208110611d07578151835260209283019290910190601f1901611ce8565b905182516020929092036101000a6000190180199091169116179052505050565b80356114c8816128ca565b80516114c8816128ca565b80356114c8816128e1565b80516114c8816128e1565b80356114c8816128ea565b80516114c8816128ea565b600082601f830112611d7b57600080fd5b8135611d8e611d8982612812565b6127eb565b91508082526020830160208301858383011115611daa57600080fd5b611db583828461286d565b50505092915050565b600082601f830112611dcf57600080fd5b8151611ddd611d8982612812565b91508082526020830160208301858383011115611df957600080fd5b611db5838284612879565b600060208284031215611e1657600080fd5b6000611e228484611d28565b949350505050565b600060208284031215611e3c57600080fd5b6000611e228484611d33565b600060208284031215611e5a57600080fd5b6000611e228484611d49565b600060208284031215611e7857600080fd5b6000611e228484611d5f565b600060208284031215611e9657600080fd5b815167ffffffffffffffff811115611ead57600080fd5b611e2284828501611dbe565b600060208284031215611ecb57600080fd5b813567ffffffffffffffff811115611ee257600080fd5b611e2284828501611d6a565b60008060008060008060c08789031215611f0757600080fd5b6000611f138989611d54565b9650506020611f2489828a01611d28565b955050604087013567ffffffffffffffff811115611f4157600080fd5b611f4d89828a01611d6a565b9450506060611f5e89828a01611d54565b9350506080611f6f89828a01611d54565b92505060a0611f8089828a01611d54565b9150509295509295509295565b600080600080600080600060e0888a031215611fa857600080fd5b6000611fb48a8a611d54565b9750506020611fc58a828b01611d54565b9650506040611fd68a828b01611d28565b955050606088013567ffffffffffffffff811115611ff357600080fd5b611fff8a828b01611d6a565b94505060806120108a828b01611d28565b93505060a06120218a828b01611d28565b92505060c06120328a828b01611d3e565b91505092959891949750929550565b600080600080600080600080610100898b03121561205e57600080fd5b600061206a8b8b611d54565b985050602061207b8b828c01611d54565b975050604061208c8b828c01611d54565b965050606061209d8b828c01611d28565b955050608089013567ffffffffffffffff8111156120ba57600080fd5b6120c68b828c01611d6a565b94505060a06120d78b828c01611d54565b93505060c06120e88b828c01611d54565b92505060e06120f98b828c01611d54565b9150509295985092959890939650565b61211281612847565b82525050565b61211261212482612847565b6128a9565b61211261213582612857565b612864565b61211281612864565b61211261213582612864565b600061215a8261283a565b612164818561283e565b9350612174818560208601612879565b61217d816128ba565b9093019392505050565b60006121928261283a565b61219c8185610469565b93506121ac818560208601612879565b9290920192915050565b60006121c360328361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527132bc34b9ba32b73a103a3c27b934b3b4b71760711b602082015260400192915050565b600061221760338361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527232bc34b9ba32b73a1036b9b3a9b2b73232b91760691b602082015260400192915050565b600061226c602b8361283e565b7f53656e646572206e6f7420616c6c6f77656420746f206465706c6f79206e657781526a20636f6e7472616374732160a81b602082015260400192915050565b60006122b960108361283e565b6f496e636f7272656374206e6f6e63652160801b815260200192915050565b60006122e5600b83610469565b6a6f766d435245415445282960a81b8152600b0192915050565b600061230c601b8361283e565b7f4661696c656420746f207265636f766572207369676e61747572650000000000815260200192915050565b6000612345600983610469565b686f766d43414c4c282960b81b815260090192915050565b600061236a60188361283e565b7f4c314d65737361676553656e646572206e6f7420736574210000000000000000815260200192915050565b60006123a360308361283e565b7f436f6e74726163742072756e74696d6520286465706c6f79656429206279746581526f636f6465206973206e6f74207361666560801b602082015260400192915050565b60006123f560298361283e565b7f436f6e747261637420696e697420286372656174696f6e2920636f6465206973815268206e6f74207361666560b81b602082015260400192915050565b600061244060378361283e565b7f4c314d65737361676553656e646572206f6e6c792061636365737369626c652081527f696e20656e747279706f696e7420636f6e747261637421000000000000000000602082015260400192915050565b600061249f603b8361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527f6578697374656e74206f766d416374697665436f6e74726163742e0000000000602082015260400192915050565b60006124fe600c8361283e565b6b29ba30ba32a6b0b730b3b2b960a11b815260200192915050565b6000612526602c8361283e565b7f43616e6e6f742063616c6c205353544f52452066726f6d2077697468696e206181526b1029aa20aa24a1a1a0a6261760a11b602082015260400192915050565b6000612574604f8361283e565b7f4f6e6c7920746865204c314d65737361676553656e64657220707265636f6d7081527f696c6520697320616c6c6f77656420746f2063616c6c206765744c314d65737360208201526e61676553656e646572282e2e2e292160881b604082015260600192915050565b61211281612867565b60006125f38287612129565b6001820191506126038286612118565b6014820191506126138285612143565b6020820191506126238284612143565b50602001949350505050565b60006118608284612187565b60006114c8826122d8565b60006114c882612338565b602081016114c88284612109565b6040810161266d8285612109565b6118606020830184612109565b604081016126888285612109565b611860602083018461213a565b606081016126a38286612109565b6126b0602083018561213a565b611e22604083018461213a565b608081016126cb828761213a565b6126d860208301866125de565b6126e5604083018561213a565b6126f2606083018461213a565b95945050505050565b60208082528101611860818461214f565b60208082528101610466816121b6565b602080825281016104668161220a565b602080825281016104668161225f565b60208082528101610466816122ac565b60208082528101610466816122ff565b602080825281016104668161235d565b6020808252810161046681612396565b60208082528101610466816123e8565b6020808252810161046681612433565b6020808252810161046681612492565b604080825281016127bc816124f1565b90506114c86020830184612109565b6020808252810161046681612519565b6020808252810161046681612567565b60405181810167ffffffffffffffff8111828210171561280a57600080fd5b604052919050565b600067ffffffffffffffff82111561282957600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b600061046682611905565b151590565b6001600160f81b03191690565b90565b60ff1690565b82818337506000910152565b60005b8381101561289457818101518382015260200161287c565b838111156128a3576000848401525b50505050565b6000610466826000610466826128c4565b601f01601f191690565b60601b90565b6128d381612847565b81146128de57600080fd5b50565b6128d381612852565b6128d38161286456fea365627a7a72315820628c4900b986bf0fde8d4e9f7d6dc9c4d2ef2b8c923c1a6f6ded2288ba095dc66c6578706572696d656e74616cf564736f6c634300050f0040608060405234801561001057600080fd5b506040516102973803806102978339818101604052602081101561003357600080fd5b5051600180546001600160a01b0319166001600160a01b03909216919091179055610234806100636000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063cafa81dc14610030575b600080fd5b6100d66004803603602081101561004657600080fd5b81019060208101813564010000000081111561006157600080fd5b82018360208201111561007357600080fd5b8035906020019184600183028401116401000000008311171561009557600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506100d8945050505050565b005b60008054600181019091557f47b65c6c9adf9c9a1f4d661cea00e3a0be49b77b90d9b5a02347d55cbfb7c3f59061010d6101a8565b8360405180848152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610169578181015183820152602001610151565b50505050905090810190601f1680156101965780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a150565b604080516a6f766d43414c4c4552282960a81b8152905190819003600b0181206001548183526000926001600160a01b03909116908390806207a12081368186885af1806101f4573d82fd5b50519450505050509056fea265627a7a72315820343803a12ea2d9c56741a67958dea5bb2201f31f4037ba697412498df5f96e6764736f6c634300050f0032608060405234801561001057600080fd5b5060405161025d38038061025d83398101604081905261002f91610065565b600080546001600160a01b0319166001600160a01b03929092169190911790556100b3565b805161005f8161009c565b92915050565b60006020828403121561007757600080fd5b60006100838484610054565b949350505050565b60006001600160a01b03821661005f565b6100a58161008b565b81146100b057600080fd5b50565b61019b806100c26000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d203410614610030575b600080fd5b61003861004e565b6040516100459190610122565b60405180910390f35b60008060009054906101000a90046001600160a01b03166001600160a01b031663d20341066040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561009f57600080fd5b505af11580156100b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506100d791908101906100ed565b905090565b80516100e781610141565b92915050565b6000602082840312156100ff57600080fd5b600061010b84846100dc565b949350505050565b61011c81610130565b82525050565b602081016100e78284610113565b60006001600160a01b0382166100e7565b61014a81610130565b811461015557600080fd5b5056fea365627a7a723158203fee4ffc5bf216e9ed2244978d45a942231af338f679eb4dd6c6e15b664459196c6578706572696d656e74616cf564736f6c634300050f0040", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c806373509064116100f9578063bdbf8c3611610097578063d203410611610071578063d2034106146102aa578063d8178e3d146102b2578063f55c5c72146102ba578063fbb0f79d146102cd576101a9565b8063bdbf8c3614610292578063c3382d0f1461029a578063c8645416146102a2576101a9565b80638e03b2d1116100d35780638e03b2d114610272578063905802561461027a578063996d79a514610282578063b0168ba31461028a576101a9565b8063735090641461024f57806377a5a62f146102575780637aec0a921461026a576101a9565b806345e97ddb116101665780634c6d7c84116101405780634c6d7c84146102195780635a98c361146102215780635c8e0129146102295780635cbccd461461023c576101a9565b806345e97ddb1461020157806349d65ff9146102095780634ba8746f14610211576101a9565b8063035a2005146101ae57806316902d57146101cc57806320160f3a146101d657806320966208146101de578063232cdee6146101e657806328dcb2a0146101f9575b600080fd5b6101b66102d5565b6040516101c39190612651565b60405180910390f35b6101d46102e6565b005b6101d4610331565b6101d461033f565b6101b66101f4366004611eb9565b6103e5565b6101d461046e565b6101d4610511565b6101d46105e1565b6101d4610796565b6101d46107a4565b6101d461089b565b6101d4610237366004611f8d565b6108a9565b6101d461024a366004612041565b610b52565b6101d4610c4e565b6101d4610265366004611e04565b610c90565b6101d4610cf5565b6101d4610dbd565b6101d4610e6b565b6101d4610e7a565b6101d4610ebc565b6101d4610eca565b6101d4610ed8565b6101d4610f7e565b6101b6610fa5565b6101d461103a565b6101b66102c8366004611eee565b6110ab565b6101d46112ed565b6000806102e06113fe565b91505090565b6008546001600160a01b03166103175760405162461bcd60e51b815260040161030e9061270c565b60405180910390fd5b6008546040516001600160a01b0390911680825290602081f35b600a54604051818152602081f35b60006103496113fe565b6006546040516362c510a360e01b815291925060048035926000926001600160a01b03808716936362c510a393610386939092169187910161267a565b602060405180830381600087803b1580156103a057600080fd5b505af11580156103b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103d89190810190611e66565b9050604051818152602081f35b6000805460405163bf40fac160e01b81526001600160a01b039091169063bf40fac1906104169085906004016126fb565b60206040518083038186803b15801561042e57600080fd5b505afa158015610442573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506104669190810190611e2a565b90505b919050565b60006104786113fe565b60015490915060ff161561049e5760405162461bcd60e51b815260040161030e906127cb565b6006546040516339e503ab60e01b81526004803592602435926001600160a01b03808716936339e503ab936104da939216918791879101612695565b600060405180830381600087803b1580156104f457600080fd5b505af1158015610508573d6000803e3d6000fd5b50505050505050565b600061051b6113fe565b604080516023193680830182019093529293509101906010358260248337604051633dec5d8560e01b8152606082901c906000906001600160a01b03871690633dec5d859061056e908590600401612651565b602060405180830381600087803b15801561058857600080fd5b505af115801561059c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105c09190810190611e2a565b905060008086866000855af16040513d6000823e816105dd573d81fd5b3d81f35b60006105eb6113fe565b60015490915060ff16156106055760405160008152602081f35b604051600319360180825280600460208401378101602081016040819052600654630e7d0fff60e01b9091526001600160a01b0390811691600091851690630e7d0fff90610657908590602401612651565b602060405180830381600087803b15801561067157600080fd5b505af1158015610685573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106a99190810190611e66565b905060006106b78383611432565b90506106c381856114ce565b6040516333dda11760e11b81526001600160a01b038616906367bb422e906106ef908490600401612651565b600060405180830381600087803b15801561070957600080fd5b505af115801561071d573d6000803e3d6000fd5b505060405163d909aa5360e01b81526001600160a01b038816925063d909aa53915061074d908690600401612651565b600060405180830381600087803b15801561076757600080fd5b505af115801561077b573d6000803e3d6000fd5b50506040516001600160a01b03841680825292509050602081f35b600c54604051818152602081f35b60006107ae6113fe565b604080516023193680830182019093529293509101906010358260248337606081901c6000806107dd8361172f565b915091506000876001600160a01b0316633dec5d85856040518263ffffffff1660e01b815260040161080f9190612651565b602060405180830381600087803b15801561082957600080fd5b505af115801561083d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506108619190810190611e2a565b9050606060008060008a8a6000875af160405192503d6000843e80610884573d83fd5b50503d8181016040526108978585611763565b8082f35b600454604051818152602081f35b60006108b36113fe565b90506108c58860008987876000611794565b6108ce8461172f565b5060009050806001600160a01b038816158015610a36576108ed6117e2565b6001600160a01b031663b1540a01886040518263ffffffff1660e01b81526004016109189190612651565b60206040518083038186803b15801561093057600080fd5b505afa158015610944573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109689190810190611e48565b6109845760405162461bcd60e51b815260040161030e9061272c565b60e06040516109929061263b565b6040518091039020901c9250875160040191506000610a2e88866001600160a01b0316630e7d0fff8b6040518263ffffffff1660e01b81526004016109d79190612651565b602060405180830381600087803b1580156109f157600080fd5b505af1158015610a05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a299190810190611e66565b611432565b905050610ab6565b60e0604051610a4490612646565b6040519081900381208a5163d909aa5360e01b8352921c9450602490910192506001600160a01b0385169063d909aa5390610a83908a90600401612651565b600060405180830381600087803b158015610a9d57600080fd5b505af1158015610ab1573d6000803e3d6000fd5b505050505b80610ac657888852600319909701965b6001811415610ad657601c880197505b8260181c88538260101c60018901538260081c600289015382600389015360006060818080868d82305af192503d9050604051915060208201816000823e8183528101604052602082016001841415610b2d578181f35b6001891415610b3a578181fd5b5082610b4257005b5050505050505050505050505050565b6000610b5c6113fe565b90506000610b6e8888888888886110ab565b90506001600160a01b038116610b965760405162461bcd60e51b815260040161030e9061274c565b604051630e7d0fff60e01b81526001600160a01b03831690630e7d0fff90610bc2908490600401612651565b602060405180830381600087803b158015610bdc57600080fd5b505af1158015610bf0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c149190810190611e66565b8814610c325760405162461bcd60e51b815260040161030e9061273c565b610c428a8a8989856000806108a9565b50505050505050505050565b6007546001600160a01b0316610c765760405162461bcd60e51b815260040161030e9061271c565b6007546040516001600160a01b0390911680825290602081f35b600054604051639b2ea4bd60e01b81526001600160a01b0390911690639b2ea4bd90610cc09084906004016127ac565b600060405180830381600087803b158015610cda57600080fd5b505af1158015610cee573d6000803e3d6000fd5b5050505050565b6000610cff6113fe565b604051633dec5d8560e01b815290915060103590606082901c906000906001600160a01b03851690633dec5d8590610d3b908590600401612651565b602060405180830381600087803b158015610d5557600080fd5b505af1158015610d69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d8d9190810190611e2a565b90506000846001600160a01b031663dfcac77d836040518263ffffffff1660e01b81526004016103869190612651565b6000610dc76113fe565b604051633dec5d8560e01b8152909150601035906024359060443590606084901c906000906001600160a01b03871690633dec5d8590610e0b908590600401612651565b602060405180830381600087803b158015610e2557600080fd5b505af1158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610e5d9190810190611e2a565b9050604051838582843c8381f35b6040516101a480825290602081f35b6006546001600160a01b0316610ea25760405162461bcd60e51b815260040161030e9061279c565b6006546040516001600160a01b0390911680825290602081f35b600554604051818152602081f35b600354604051818152602081f35b6000610ee26113fe565b604051633dec5d8560e01b815290915060103590606082901c906000906001600160a01b03851690633dec5d8590610f1e908590600401612651565b602060405180830381600087803b158015610f3857600080fd5b505af1158015610f4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610f709190810190611e2a565b9050604051813b8152602081f35b60015460009060ff16610f92576000610f95565b60015b60ff169050604051818152602081f35b6006546000906001600160a01b03166001602160991b0114610fd95760405162461bcd60e51b815260040161030e906127db565b6009546001600160a01b03166110015760405162461bcd60e51b815260040161030e9061275c565b6007546001600160a01b03161561102a5760405162461bcd60e51b815260040161030e9061278c565b506009546001600160a01b031690565b60015460ff16156110515760405160008152602081f35b604051602319360180825260043590806024602085013782016020016040526006546001600160a01b03166000611089828486611816565b905061109581856114ce565b6040516001600160a01b03821680825290602081f35b604080516009808252610140820190925260009160609190816020015b60608152602001906001900390816110c85790505090506110e888611867565b816000815181106110f557fe5b602002602001018190525061110a6000611867565b8160018151811061111757fe5b6020026020010181905250611130600b60010154611867565b8160028151811061113d57fe5b60209081029190910101526001600160a01b03871661117d576111606000611867565b8160038151811061116d57fe5b602002602001018190525061119f565b6111868761187a565b8160038151811061119357fe5b60200260200101819052505b6111a96000611867565b816004815181106111b657fe5b60200260200101819052506111ca86611899565b816005815181106111d757fe5b60200260200101819052506111ef6001800154611867565b816006815181106111fc57fe5b60200260200101819052506112116000611867565b8160078151811061121e57fe5b60200260200101819052506112336000611867565b8160088151811061124057fe5b60200260200101819052506060611256826118e2565b905060008160405160200161126b919061262f565b604051602081830303815290604052805190602001209050600181600860018001546002028a03038888604051600081526020016040526040516112b294939291906126bd565b6020604051602081039080840390855afa1580156112d4573d6000803e3d6000fd5b5050604051601f1901519b9a5050505050505050505050565b60006112f76113fe565b6040805160231936808301820190935292935091019060103582602483376001805460ff198116821790915560ff16606082901c6000806113378361172f565b915091506000886001600160a01b0316633dec5d85856040518263ffffffff1660e01b81526004016113699190612651565b602060405180830381600087803b15801561138357600080fd5b505af1158015611397573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506113bb9190810190611e2a565b9050606060008060008b8b6000875af160405192503d6000843e3d9150806113e1573d83fd5b506113ec8585611763565b6001805460ff19168815151790558082f35b600061142d6040518060400160405280600c81526020016b29ba30ba32a6b0b730b3b2b960a11b8152506103e5565b905090565b60408051600280825260608281019093526000929190816020015b606081526020019060019003908161144d57905050905061146d8461187a565b8160008151811061147a57fe5b602002602001018190525061148e83611867565b8160018151811061149b57fe5b602002602001018190525060606114b1826118e2565b90506114c38180519060200120611905565b925050505b92915050565b60006114d86113fe565b905060006114e4611911565b6040516352275acd60e11b81529091506001600160a01b0382169063a44eb59a906115139086906004016126fb565b60206040518083038186803b15801561152b57600080fd5b505afa15801561153f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506115639190810190611e48565b61157f5760405162461bcd60e51b815260040161030e9061277c565b60008061158b8661172f565b91509150600061159a86611941565b90506060856001600160a01b031663d7b5555e836040518263ffffffff1660e01b81526004016115ca9190612651565b600060405180830381600087803b1580156115e457600080fd5b505af11580156115f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116209190810190611e84565b6040516352275acd60e11b81529091506001600160a01b0386169063a44eb59a9061164f9084906004016126fb565b60206040518083038186803b15801561166757600080fd5b505afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061169f9190810190611e48565b6116bb5760405162461bcd60e51b815260040161030e9061276c565b604051636b8b57e160e01b81526001600160a01b03871690636b8b57e1906116e9908b90869060040161265f565b600060405180830381600087803b15801561170357600080fd5b505af1158015611717573d6000803e3d6000fd5b505050506117258484611763565b5050505050505050565b60068054600780546001600160a01b03198084166001600160a01b0396871617909455918416928216831790559190911691565b600680546001600160a01b039283166001600160a01b03199182161790915560078054939092169216919091179055565b61179f600080611763565b600395909555600493909355600591909155600880546001600160a01b039283166001600160a01b03199182161790915560098054929093169116179055600a55565b600061142d6040518060400160405280601181526020017011195c1b1bde595c95da1a5d195b1a5cdd607a1b8152506103e5565b60008060ff60f81b8585858051906020012060405160200161183b94939291906125e7565b60405160208183030381529060405280519060200120905061185c81611905565b9150505b9392505050565b606061046661187583611952565b611899565b60408051600560a21b8318601482015260348101909152606090611860815b606080825160011480156118c157506080836000815181106118b757fe5b016020015160f81c105b156118cd575081610466565b6118606118dc84516080611a44565b84611b7d565b6060806118ee83611bfa565b90506118606118ff825160c0611a44565b82611b7d565b6001600160a01b031690565b600061142d6040518060400160405280600d81526020016c29b0b332ba3ca1b432b1b5b2b960991b8152506103e5565b60008151602083016000f092915050565b60408051602080825281830190925260609182919060208201818038833950505060208101849052905060005b60208110156119b55781818151811061199457fe5b01602001516001600160f81b031916156119ad576119b5565b60010161197f565b6060816020036040519080825280601f01601f1916602001820160405280156119e5576020820181803883390190505b50905060005b8151811015611a3b578351600184019385918110611a0557fe5b602001015160f81c60f81b828281518110611a1c57fe5b60200101906001600160f81b031916908160001a9053506001016119eb565b50949350505050565b6060806038841015611a9e576040805160018082528183019092529060208201818038833901905050905082840160f81b81600081518110611a8257fe5b60200101906001600160f81b031916908160001a905350611860565b600060015b808681611aac57fe5b0415611ac15760019091019061010002611aa3565b816001016040519080825280601f01601f191660200182016040528015611aef576020820181803883390190505b50925084820160370160f81b83600081518110611b0857fe5b60200101906001600160f81b031916908160001a905350600190505b818111611b74576101008183036101000a8781611b3d57fe5b0481611b4557fe5b0660f81b838281518110611b5557fe5b60200101906001600160f81b031916908160001a905350600101611b24565b50509392505050565b6060806040519050835180825260208201818101602087015b81831015611bae578051835260209283019201611b96565b50855184518101855292509050808201602086015b81831015611bdb578051835260209283019201611bc3565b508651929092011591909101601f01601f191660405250905092915050565b6060815160001415611c1b5750604080516000815260208101909152610469565b6000805b8351811015611c4e57838181518110611c3457fe5b602002602001015151820191508080600101915050611c1f565b6060826040519080825280601f01601f191660200182016040528015611c7b576020820181803883390190505b50600092509050602081015b8551831015611a3b576060868481518110611c9e57fe5b602002602001015190506000602082019050611cbc83828451611ce4565b878581518110611cc857fe5b6020026020010151518301925050508280600101935050611c87565b8282825b60208110611d07578151835260209283019290910190601f1901611ce8565b905182516020929092036101000a6000190180199091169116179052505050565b80356114c8816128ca565b80516114c8816128ca565b80356114c8816128e1565b80516114c8816128e1565b80356114c8816128ea565b80516114c8816128ea565b600082601f830112611d7b57600080fd5b8135611d8e611d8982612812565b6127eb565b91508082526020830160208301858383011115611daa57600080fd5b611db583828461286d565b50505092915050565b600082601f830112611dcf57600080fd5b8151611ddd611d8982612812565b91508082526020830160208301858383011115611df957600080fd5b611db5838284612879565b600060208284031215611e1657600080fd5b6000611e228484611d28565b949350505050565b600060208284031215611e3c57600080fd5b6000611e228484611d33565b600060208284031215611e5a57600080fd5b6000611e228484611d49565b600060208284031215611e7857600080fd5b6000611e228484611d5f565b600060208284031215611e9657600080fd5b815167ffffffffffffffff811115611ead57600080fd5b611e2284828501611dbe565b600060208284031215611ecb57600080fd5b813567ffffffffffffffff811115611ee257600080fd5b611e2284828501611d6a565b60008060008060008060c08789031215611f0757600080fd5b6000611f138989611d54565b9650506020611f2489828a01611d28565b955050604087013567ffffffffffffffff811115611f4157600080fd5b611f4d89828a01611d6a565b9450506060611f5e89828a01611d54565b9350506080611f6f89828a01611d54565b92505060a0611f8089828a01611d54565b9150509295509295509295565b600080600080600080600060e0888a031215611fa857600080fd5b6000611fb48a8a611d54565b9750506020611fc58a828b01611d54565b9650506040611fd68a828b01611d28565b955050606088013567ffffffffffffffff811115611ff357600080fd5b611fff8a828b01611d6a565b94505060806120108a828b01611d28565b93505060a06120218a828b01611d28565b92505060c06120328a828b01611d3e565b91505092959891949750929550565b600080600080600080600080610100898b03121561205e57600080fd5b600061206a8b8b611d54565b985050602061207b8b828c01611d54565b975050604061208c8b828c01611d54565b965050606061209d8b828c01611d28565b955050608089013567ffffffffffffffff8111156120ba57600080fd5b6120c68b828c01611d6a565b94505060a06120d78b828c01611d54565b93505060c06120e88b828c01611d54565b92505060e06120f98b828c01611d54565b9150509295985092959890939650565b61211281612847565b82525050565b61211261212482612847565b6128a9565b61211261213582612857565b612864565b61211281612864565b61211261213582612864565b600061215a8261283a565b612164818561283e565b9350612174818560208601612879565b61217d816128ba565b9093019392505050565b60006121928261283a565b61219c8185610469565b93506121ac818560208601612879565b9290920192915050565b60006121c360328361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527132bc34b9ba32b73a103a3c27b934b3b4b71760711b602082015260400192915050565b600061221760338361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527232bc34b9ba32b73a1036b9b3a9b2b73232b91760691b602082015260400192915050565b600061226c602b8361283e565b7f53656e646572206e6f7420616c6c6f77656420746f206465706c6f79206e657781526a20636f6e7472616374732160a81b602082015260400192915050565b60006122b960108361283e565b6f496e636f7272656374206e6f6e63652160801b815260200192915050565b60006122e5600b83610469565b6a6f766d435245415445282960a81b8152600b0192915050565b600061230c601b8361283e565b7f4661696c656420746f207265636f766572207369676e61747572650000000000815260200192915050565b6000612345600983610469565b686f766d43414c4c282960b81b815260090192915050565b600061236a60188361283e565b7f4c314d65737361676553656e646572206e6f7420736574210000000000000000815260200192915050565b60006123a360308361283e565b7f436f6e74726163742072756e74696d6520286465706c6f79656429206279746581526f636f6465206973206e6f74207361666560801b602082015260400192915050565b60006123f560298361283e565b7f436f6e747261637420696e697420286372656174696f6e2920636f6465206973815268206e6f74207361666560b81b602082015260400192915050565b600061244060378361283e565b7f4c314d65737361676553656e646572206f6e6c792061636365737369626c652081527f696e20656e747279706f696e7420636f6e747261637421000000000000000000602082015260400192915050565b600061249f603b8361283e565b7f4572726f723a20617474656d7074696e6720746f20616363657373206e6f6e2d81527f6578697374656e74206f766d416374697665436f6e74726163742e0000000000602082015260400192915050565b60006124fe600c8361283e565b6b29ba30ba32a6b0b730b3b2b960a11b815260200192915050565b6000612526602c8361283e565b7f43616e6e6f742063616c6c205353544f52452066726f6d2077697468696e206181526b1029aa20aa24a1a1a0a6261760a11b602082015260400192915050565b6000612574604f8361283e565b7f4f6e6c7920746865204c314d65737361676553656e64657220707265636f6d7081527f696c6520697320616c6c6f77656420746f2063616c6c206765744c314d65737360208201526e61676553656e646572282e2e2e292160881b604082015260600192915050565b61211281612867565b60006125f38287612129565b6001820191506126038286612118565b6014820191506126138285612143565b6020820191506126238284612143565b50602001949350505050565b60006118608284612187565b60006114c8826122d8565b60006114c882612338565b602081016114c88284612109565b6040810161266d8285612109565b6118606020830184612109565b604081016126888285612109565b611860602083018461213a565b606081016126a38286612109565b6126b0602083018561213a565b611e22604083018461213a565b608081016126cb828761213a565b6126d860208301866125de565b6126e5604083018561213a565b6126f2606083018461213a565b95945050505050565b60208082528101611860818461214f565b60208082528101610466816121b6565b602080825281016104668161220a565b602080825281016104668161225f565b60208082528101610466816122ac565b60208082528101610466816122ff565b602080825281016104668161235d565b6020808252810161046681612396565b60208082528101610466816123e8565b6020808252810161046681612433565b6020808252810161046681612492565b604080825281016127bc816124f1565b90506114c86020830184612109565b6020808252810161046681612519565b6020808252810161046681612567565b60405181810167ffffffffffffffff8111828210171561280a57600080fd5b604052919050565b600067ffffffffffffffff82111561282957600080fd5b506020601f91909101601f19160190565b5190565b90815260200190565b600061046682611905565b151590565b6001600160f81b03191690565b90565b60ff1690565b82818337506000910152565b60005b8381101561289457818101518382015260200161287c565b838111156128a3576000848401525b50505050565b6000610466826000610466826128c4565b601f01601f191690565b60601b90565b6128d381612847565b81146128de57600080fd5b50565b6128d381612852565b6128d38161286456fea365627a7a72315820628c4900b986bf0fde8d4e9f7d6dc9c4d2ef2b8c923c1a6f6ded2288ba095dc66c6578706572696d656e74616cf564736f6c634300050f0040", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/lib/ovm/contracts/defs/StateManager.json b/lib/ovm/contracts/defs/StateManager.json deleted file mode 100644 index 54648e511ac..00000000000 --- a/lib/ovm/contracts/defs/StateManager.json +++ /dev/null @@ -1,283 +0,0 @@ -{ - "contractName": "FullStateManager", - "abi": [ - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - }, - { - "internalType": "address", - "name": "_codeContractAddress", - "type": "address" - } - ], - "name": "associateCodeContract", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - } - ], - "name": "getCodeContractAddressFromOvmAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_codeContractAddress", - "type": "address" - } - ], - "name": "getCodeContractBytecode", - "outputs": [ - { - "internalType": "bytes", - "name": "codeContractBytecode", - "type": "bytes" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_codeContractAddress", - "type": "address" - } - ], - "name": "getCodeContractHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "_codeContractHash", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_codeContractAddress", - "type": "address" - } - ], - "name": "getOvmAddressFromCodeContractAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - } - ], - "name": "getOvmContractNonce", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - } - ], - "name": "getOvmContractNonceView", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_slot", - "type": "bytes32" - } - ], - "name": "getStorage", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_slot", - "type": "bytes32" - } - ], - "name": "getStorageView", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - } - ], - "name": "incrementOvmContractNonce", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - } - ], - "name": "registerCreatedContract", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "setOvmContractNonce", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "internalType": "address", - "name": "_ovmContractAddress", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "_slot", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "_value", - "type": "bytes32" - } - ], - "name": "setStorage", - "outputs": [], - "payable": false, - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50610580806100206000396000f3fe608060405234801561001057600080fd5b50600436106100cf5760003560e01c806367bb422e1161008c578063ac6c266611610066578063ac6c26661461017e578063d7b5555e14610191578063d909aa53146101b1578063dfcac77d146101c4576100cf565b806367bb422e146101455780636b8b57e114610158578063807de2351461016b576100cf565b80630e7d0fff146100d457806339e503ab146100fd5780633dec5d851461011257806349677085146101325780635f78dd86146100d457806362c510a314610132575b600080fd5b6100e76100e236600461035e565b6101d7565b6040516100f49190610499565b60405180910390f35b61011061010b3660046103ee565b6101f2565b005b61012561012036600461035e565b610216565b6040516100f4919061048b565b6100e76101403660046103be565b610234565b61011061015336600461035e565b61025d565b610110610166366004610384565b610260565b61012561017936600461035e565b6102a8565b61011061018c3660046103be565b6102c6565b6101a461019f36600461035e565b6102e2565b6040516100f491906104a7565b6101106101bf36600461035e565b610309565b6100e76101d236600461035e565b61032c565b6001600160a01b031660009081526001602052604090205490565b6001600160a01b039092166000908152602081815260408083209383529290522055565b6001600160a01b039081166000908152600260205260409020541690565b6001600160a01b0382166000908152602081815260408083208484529091529020545b92915050565b50565b6001600160a01b0391821660008181526002602090815260408083208054969095166001600160a01b0319968716811790955593825260039052919091208054909216179055565b6001600160a01b039081166000908152600360205260409020541690565b6001600160a01b03909116600090815260016020526040902055565b60408051603f833b908101601f191682019092528181529080600060208401853c50919050565b6001600160a01b0316600090815260016020819052604090912080549091019055565b60006060610339836102e2565b80516020909101209392505050565b803561025781610520565b803561025781610534565b60006020828403121561037057600080fd5b600061037c8484610348565b949350505050565b6000806040838503121561039757600080fd5b60006103a38585610348565b92505060206103b485828601610348565b9150509250929050565b600080604083850312156103d157600080fd5b60006103dd8585610348565b92505060206103b485828601610353565b60008060006060848603121561040357600080fd5b600061040f8686610348565b935050602061042086828701610353565b925050604061043186828701610353565b9150509250925092565b610444816104cc565b82525050565b610444816104d7565b600061045e826104bf565b61046881856104c3565b93506104788185602086016104e6565b61048181610516565b9093019392505050565b60208101610257828461043b565b60208101610257828461044a565b602080825281016104b88184610453565b9392505050565b5190565b90815260200190565b6000610257826104da565b90565b6001600160a01b031690565b60005b838110156105015781810151838201526020016104e9565b83811115610510576000848401525b50505050565b601f01601f191690565b610529816104cc565b811461025d57600080fd5b610529816104d756fea365627a7a7231582078d85385ce2d2bcfae3c4055bedfb19da2b7eacfdb01fa1e853b31dc6b773c556c6578706572696d656e74616cf564736f6c634300050f0040", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c806367bb422e1161008c578063ac6c266611610066578063ac6c26661461017e578063d7b5555e14610191578063d909aa53146101b1578063dfcac77d146101c4576100cf565b806367bb422e146101455780636b8b57e114610158578063807de2351461016b576100cf565b80630e7d0fff146100d457806339e503ab146100fd5780633dec5d851461011257806349677085146101325780635f78dd86146100d457806362c510a314610132575b600080fd5b6100e76100e236600461035e565b6101d7565b6040516100f49190610499565b60405180910390f35b61011061010b3660046103ee565b6101f2565b005b61012561012036600461035e565b610216565b6040516100f4919061048b565b6100e76101403660046103be565b610234565b61011061015336600461035e565b61025d565b610110610166366004610384565b610260565b61012561017936600461035e565b6102a8565b61011061018c3660046103be565b6102c6565b6101a461019f36600461035e565b6102e2565b6040516100f491906104a7565b6101106101bf36600461035e565b610309565b6100e76101d236600461035e565b61032c565b6001600160a01b031660009081526001602052604090205490565b6001600160a01b039092166000908152602081815260408083209383529290522055565b6001600160a01b039081166000908152600260205260409020541690565b6001600160a01b0382166000908152602081815260408083208484529091529020545b92915050565b50565b6001600160a01b0391821660008181526002602090815260408083208054969095166001600160a01b0319968716811790955593825260039052919091208054909216179055565b6001600160a01b039081166000908152600360205260409020541690565b6001600160a01b03909116600090815260016020526040902055565b60408051603f833b908101601f191682019092528181529080600060208401853c50919050565b6001600160a01b0316600090815260016020819052604090912080549091019055565b60006060610339836102e2565b80516020909101209392505050565b803561025781610520565b803561025781610534565b60006020828403121561037057600080fd5b600061037c8484610348565b949350505050565b6000806040838503121561039757600080fd5b60006103a38585610348565b92505060206103b485828601610348565b9150509250929050565b600080604083850312156103d157600080fd5b60006103dd8585610348565b92505060206103b485828601610353565b60008060006060848603121561040357600080fd5b600061040f8686610348565b935050602061042086828701610353565b925050604061043186828701610353565b9150509250925092565b610444816104cc565b82525050565b610444816104d7565b600061045e826104bf565b61046881856104c3565b93506104788185602086016104e6565b61048181610516565b9093019392505050565b60208101610257828461043b565b60208101610257828461044a565b602080825281016104b88184610453565b9392505050565b5190565b90815260200190565b6000610257826104da565b90565b6001600160a01b031690565b60005b838110156105015781810151838201526020016104e9565b83811115610510576000848401525b50505050565b601f01601f191690565b610529816104cc565b811461025d57600080fd5b610529816104d756fea365627a7a7231582078d85385ce2d2bcfae3c4055bedfb19da2b7eacfdb01fa1e853b31dc6b773c556c6578706572696d656e74616cf564736f6c634300050f0040", - "linkReferences": {}, - "deployedLinkReferences": {} - } - \ No newline at end of file diff --git a/lib/ovm/contracts/index.ts b/lib/ovm/contracts/index.ts deleted file mode 100644 index 50241ea2c42..00000000000 --- a/lib/ovm/contracts/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* External Imports */ -import { Interface } from '@ethersproject/abi' - -import * as ExecutionManagerJSON from './defs/ExecutionManager.json' -import * as StateManagerJSON from './defs/StateManager.json' - -export const iExecutionManager = new Interface(ExecutionManagerJSON.abi) -export const iStateManager = new Interface(StateManagerJSON.abi) diff --git a/lib/ovm/ovm-state-manager.ts b/lib/ovm/ovm-state-manager.ts index 70d76c91d26..58ebc5b613e 100644 --- a/lib/ovm/ovm-state-manager.ts +++ b/lib/ovm/ovm-state-manager.ts @@ -1,12 +1,12 @@ /* External Imports */ import BN = require('bn.js') +import { BigNumber } from 'ethers' /* Internal Imports */ import VM from '../index' import Message from '../evm/message' import { fromHexString, toHexString } from './utils/buffer-utils' import { NULL_BYTES32 } from './utils/constants' -import { iStateManager } from './contracts' export interface OvmStateManagerOpts { vm: VM @@ -14,24 +14,28 @@ export interface OvmStateManagerOpts { export class OvmStateManager { public vm: VM - private _iface = iStateManager + private _iface: any private _handlers: { [name: string]: any } constructor(opts: OvmStateManagerOpts) { this.vm = opts.vm + this._iface = this.vm.contracts.OVM_StateManager.iface this._handlers = { - associateCodeContract: this.associateCodeContract.bind(this), - setStorage: this.setStorage.bind(this), - getStorage: this.getStorage.bind(this), - getStorageView: this.getStorageView.bind(this), - getOvmContractNonce: this.getOvmContractNonce.bind(this), - getCodeContractBytecode: this.getCodeContractBytecode.bind(this), - registerCreatedContract: this.registerCreatedContract.bind(this), - incrementOvmContractNonce: this.incrementOvmContractNonce.bind(this), - getCodeContractAddressFromOvmAddress: this.getCodeContractAddressFromOvmAddress.bind(this), + hasAccount: this.hasAccount.bind(this), + hasEmptyAccount: this.hasEmptyAccount.bind(this), + setAccountNonce: this.setAccountNonce.bind(this), + getAccountNonce: this.getAccountNonce.bind(this), + getAccountEthAddress: this.getAccountEthAddress.bind(this), + getContractStorage: this.getContractStorage.bind(this), + hasContractStorage: this.hasContractStorage.bind(this), + putContractStorage: this.putContractStorage.bind(this), + testAndSetAccountLoaded: this.testAndSetAccountLoaded.bind(this), + testAndSetAccountChanged: this.testAndSetAccountChanged.bind(this), + testAndSetContractStorageLoaded: this.testAndSetContractStorageLoaded.bind(this), + testAndSetContractStorageChanged: this.testAndSetContractStorageChanged.bind(this), } } @@ -40,61 +44,79 @@ export class OvmStateManager { const fragment = this._iface.getFunction(methodId) const functionArgs = this._iface.decodeFunctionData(fragment, toHexString(message.data)) - const ret = await this._handlers[fragment.name](...functionArgs) - const encodedRet = this._iface.encodeFunctionResult(fragment, ret) + let ret: any + if (fragment.name in this._handlers) { + ret = await this._handlers[fragment.name](...functionArgs) + ret = (ret === null || ret === undefined) ? ret : [ret] + } - return fromHexString(encodedRet) + try { + console.log(` ← Responding with: ${ret}`) + const encodedRet = this._iface.encodeFunctionResult(fragment, ret) + return fromHexString(encodedRet) + } catch (err) { + console.log(`Caught encoding error in ovmStateManager: ${err}`) + throw err + } } - async associateCodeContract( - ovmContractAddress: string, - codeContractAddress: string, - ): Promise { - return + async hasAccount(address: string): Promise { + return true } - async setStorage(ovmContractAddress: string, slot: string, value: string): Promise { - return this.vm.pStateManager.putContractStorage( - fromHexString(ovmContractAddress), - fromHexString(slot), - fromHexString(value), - ) + async hasEmptyAccount(address: string): Promise { + return true + } + + async setAccountNonce(address: string, nonce: BigNumber): Promise { + const account = await this.vm.pStateManager.getAccount(fromHexString(address)) + account.nonce = (new BN(nonce.toNumber())).toArrayLike(Buffer) + return this.vm.pStateManager.putAccount(fromHexString(address), account) } - async getStorage(ovmContractAddress: string, slot: string): Promise<[string]> { - return this.getStorageView(ovmContractAddress, slot) + async getAccountNonce(address: string): Promise { + const account = await this.vm.pStateManager.getAccount(fromHexString(address)) + return (new BN(account.nonce)).toNumber() } - async getStorageView(ovmContractAddress: string, slot: string): Promise<[string]> { + async getAccountEthAddress(address: string): Promise { + return address + } + + async getContractStorage(address: string, key: string): Promise { const ret = await this.vm.pStateManager.getContractStorage( - fromHexString(ovmContractAddress), - fromHexString(slot), + fromHexString(address), + fromHexString(key), ) - return [ret.length ? toHexString(ret) : NULL_BYTES32] + return ret.length ? toHexString(ret) : NULL_BYTES32 + } + + async hasContractStorage(address: string, key: string): Promise { + return true } - async getOvmContractNonce(ovmContractAddress: string): Promise<[string]> { - const account = await this.vm.pStateManager.getAccount(fromHexString(ovmContractAddress)) - return [account.nonce.length ? toHexString(account.nonce) : '0x00'] + async putContractStorage(address: string, key: string, value: string): Promise { + return this.vm.pStateManager.putContractStorage( + fromHexString(address), + fromHexString(key), + fromHexString(value), + ) } - async getCodeContractBytecode(ovmContractAddress: string): Promise<[string]> { - const code = await this.vm.pStateManager.getContractCode(fromHexString(ovmContractAddress)) - return [toHexString(code)] + async testAndSetAccountLoaded(address: string): Promise { + return true } - async registerCreatedContract(ovmContractAddress: string): Promise { - return + async testAndSetAccountChanged(address: string): Promise { + return true } - async incrementOvmContractNonce(ovmContractAddress: string): Promise { - const account = await this.vm.pStateManager.getAccount(fromHexString(ovmContractAddress)) - account.nonce = new BN(account.nonce).addn(1).toArrayLike(Buffer) - return this.vm.pStateManager.putAccount(fromHexString(ovmContractAddress), account) + async testAndSetContractStorageLoaded(address: string, key: string): Promise { + return true } - async getCodeContractAddressFromOvmAddress(ovmContractAddress: string): Promise<[string]> { - return [ovmContractAddress] + async testAndSetContractStorageChanged(address: string, key: string): Promise { + return true } } diff --git a/lib/ovm/utils/buffer-utils.ts b/lib/ovm/utils/buffer-utils.ts index 3f8732f8d34..7b8fbe56884 100644 --- a/lib/ovm/utils/buffer-utils.ts +++ b/lib/ovm/utils/buffer-utils.ts @@ -1,5 +1,9 @@ export const toHexAddress = (buf: any): string => { - return '0x' + buf.toString('hex').padStart(40, '0') + if (buf.length < 20) { + throw new Error('Buffer must be at least 20 bytes to be an address.') + } + + return '0x' + buf.slice(buf.length - 20).toString('hex').padStart(40, '0') } export const toHexString = (buf: any): string => { diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index a2ae7e3d223..eaf1a24c636 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -16,7 +16,9 @@ import TxContext from './txContext' import Message from './message' import EEI from './eei' import { default as Interpreter, InterpreterOpts, RunState } from './interpreter' -import { fromHexString, toHexAddress } from '../ovm/utils/buffer-utils' +import { fromHexString, toHexAddress, toHexString } from '../ovm/utils/buffer-utils' +import { Interface } from 'ethers/lib/utils' +import { ethers } from 'ethers' /** * Result of executing a message via the [[EVM]]. @@ -124,6 +126,14 @@ export default class EVM { await this._state.checkpoint() if (message.depth === 0) { + const code = await this._state.getContractCode(message.caller) + if (code.length === 0) { + await this._state.putContractCode( + message.caller, + fromHexString(this._vm.contracts.mockOVM_ECDSAContractAccount.code) + ) + } + message = message.toOvmMessage(this._vm, this._block || new Block()) } @@ -134,7 +144,57 @@ export default class EVM { let result if (message.to) { - if (message.to.equals(this._vm.contracts.ovmStateManager.address)) { + const code = await this._state.getContractCode(message.to) + const isECDSAContractAccount = toHexString(code) === this._vm.contracts.mockOVM_ECDSAContractAccount.code + const target = isECDSAContractAccount ? this._vm.getContractByName('mockOVM_ECDSAContractAccount') : this._vm.getContract(message.to) + + if (target) { + let methodId = '0x' + message.data.slice(0, 4).toString('hex') + + let fragment: any + try { + fragment = target.iface.getFunction(methodId) + } catch (err) { + console.error(`\nCaught decoding error for ${target.name} with data: ${toHexString(message.data)}, ${err}`) + console.error(`Attempting to try again with function parameters removed in sighash calculation.`) + + let correctedMethodId: string | undefined + for (const functionName of Object.keys(target.iface.functions)) { + const possibleMethodId = ethers.utils.id(functionName.split('(')[0] + '()').slice(0, 10) + if (possibleMethodId === methodId) { + correctedMethodId = ethers.utils.id(functionName).slice(0, 10) + break + } + } + + if (!correctedMethodId) { + console.error(`Cannot find a suitable function match, throwing.`) + throw err + } + + try { + fragment = target.iface.getFunction(correctedMethodId) + methodId = correctedMethodId + console.log(`Found a suitable function match: ${target.name}.${fragment.name}, continuing.`) + } catch (err) { + console.error(`Second decoding attempt failed for ${target.name} with data: ${toHexString(message.data)}, ${err}`) + throw err + } + } + + message.data = Buffer.concat([ + fromHexString(methodId), + message.data.slice(4) + ]) + + const functionArgs = target.iface.decodeFunctionData(fragment, toHexString(message.data)) + + console.log(`\nCalling ${target.name}.${fragment.name} with args: ${functionArgs}`) + } else { + console.log(`Calling unknown contract (${toHexString(message.to)}) with data: ${toHexString(message.data)}`) + } + + if (target && target.name === 'OVM_StateManager') { result = { gasUsed: new BN(0), execResult: { @@ -148,6 +208,7 @@ export default class EVM { } else { result = await this._executeCreate(message) } + // TODO: Move `gasRefund` to a tx-level result object // instead of `ExecResult`. result.execResult.gasRefund = this._refund.clone() @@ -160,7 +221,7 @@ export default class EVM { if (this._targetMessageResult) { if (result.execResult.logs) { result.execResult.logs = result.execResult.logs.filter(log => { - return !log[0].equals(this._vm.contracts.ovmExecutionManager.address) + return !log[0].equals(this._vm.contracts.OVM_ExecutionManager.address) }) } @@ -285,7 +346,8 @@ export default class EVM { } // Exit early if there's no contract code or value transfer overflowed - if (!message.code || message.code.length === 0 || errorMessage) { + if (!message.code || message.code.length === 0) { + console.error(`Could not load code for: ${toHexString(message.to)}`) return { gasUsed: new BN(0), createdAddress: message.to, @@ -441,8 +503,8 @@ export default class EVM { return fromHexString( toHexAddress( await this._vm.pStateManager.getContractStorage( - this._vm.contracts.ovmExecutionManager.address, - Buffer.from('00'.repeat(31) + '06', 'hex'), + this._vm.contracts.OVM_ExecutionManager.address, + Buffer.from('00'.repeat(31) + '0f', 'hex'), ), ), ) diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index 3c2bb410d87..082aa3d5085 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -12,7 +12,6 @@ import { handlers as opHandlers, OpHandler } from './opFns' import { Logger } from '../ovm/utils/logger' import { env } from 'process' import { toHexAddress, toHexString } from '../ovm/utils/buffer-utils' -import { iExecutionManager } from '../ovm/contracts' const logger = new Logger('ethjs-ovm:interpreter') @@ -281,11 +280,11 @@ export default class Interpreter { const calldata = Buffer.from(memory.slice(offset, offset + length)) - if (target.equals(this._vm.contracts.ovmExecutionManager.address)) { + if (target.equals(this._vm.contracts.OVM_ExecutionManager.address)) { const sighash = toHexString(calldata.slice(0, 4)) - const fragment = iExecutionManager.getFunction(sighash) + const fragment = this._vm.contracts.OVM_ExecutionManager.iface.getFunction(sighash) const functionName = fragment.name - const functionArgs = iExecutionManager.decodeFunctionData( + const functionArgs = this._vm.contracts.OVM_ExecutionManager.iface.decodeFunctionData( fragment, toHexString(calldata), ) as any[] diff --git a/packages/vm/lib/evm/message.ts b/packages/vm/lib/evm/message.ts index 80e52dc236f..442bb365c36 100644 --- a/packages/vm/lib/evm/message.ts +++ b/packages/vm/lib/evm/message.ts @@ -3,7 +3,6 @@ import { PrecompileFunc } from './precompiles' // OVM imports import VM from '../index' -import { iExecutionManager } from '../ovm/contracts' import { toHexString, fromHexString } from '../ovm/utils/buffer-utils' import { NULL_ADDRESS } from '../ovm/utils/constants' @@ -56,24 +55,33 @@ export default class Message { } toOvmMessage(vm: VM, block: any): Message { - if (!vm.contracts.ovmExecutionManager.address) { + if (!vm.contracts.OVM_ExecutionManager.address) { throw new Error('Cannot create a message because the ExecutionManager does not exist.') } - const calldata = iExecutionManager.encodeFunctionData('executeTransaction', [ - toHexString(new BN(block.header.timestamp).toBuffer()), - 0, - this.to ? toHexString(this.to) : NULL_ADDRESS, - this.data, - toHexString(this.caller), - toHexString(this.caller), - true, + const calldata = vm.contracts.OVM_ExecutionManager.iface.encodeFunctionData('run', [ + { + timestamp: (new BN(block.header.timestamp)).toNumber(), + number: (new BN(block.header.number)).toNumber(), + l1QueueOrigin: 0, + l1Txorigin: toHexString(this.caller), + entrypoint: toHexString(this.caller), + gasLimit: this.gasLimit.toNumber(), + data: vm.contracts.mockOVM_ECDSAContractAccount.iface.encodeFunctionData('execute', [ + toHexString(this.data), + 0, + 0, + '0x' + '00'.repeat(32), + '0x' + '00'.repeat(32) + ]), + }, + vm.contracts.OVM_StateManager.addressHex ]) return new Message({ ...this, ...{ - to: vm.contracts.ovmExecutionManager.address, + to: vm.contracts.OVM_ExecutionManager.address, data: fromHexString(calldata), originalTargetAddress: this.to, }, diff --git a/packages/vm/lib/index.ts b/packages/vm/lib/index.ts index a1bd0041856..53f0784b0fd 100644 --- a/packages/vm/lib/index.ts +++ b/packages/vm/lib/index.ts @@ -19,9 +19,16 @@ const promisify = require('util.promisify') const AsyncEventEmitter = require('async-eventemitter') const promisify = require('util.promisify') +// Custom imports +import { Interface } from '@ethersproject/abi' +import { fromHexString } from './ovm/utils/buffer-utils' + interface OVMContract { + name: string address: Buffer addressHex: string + code: string + iface: any } interface StorageDump { @@ -29,16 +36,13 @@ interface StorageDump { } interface StateDump { - contracts: { - ovmExecutionManager: string - ovmStateManager: string - } accounts: { - [address: string]: { - balance: number - nonce: number + [name: string]: { + address: string code: string + codeHash: string storage: StorageDump + abi: any } } } @@ -90,8 +94,7 @@ export interface VMOpts { emGasLimit?: number dump?: StateDump contracts?: { - ovmExecutionManager: OVMContract - ovmStateManager: OVMContract + [name: string]: OVMContract } } } @@ -127,11 +130,10 @@ export default class VM extends AsyncEventEmitter { emGasLimit: number initialized: boolean dump: StateDump | undefined + ovmStateManager: OvmStateManager contracts: { - ovmExecutionManager: OVMContract - ovmStateManager: OVMContract + [name: string]: OVMContract } - ovmStateManager: OvmStateManager /** * Instantiates a new [[VM]] Object. @@ -190,15 +192,24 @@ export default class VM extends AsyncEventEmitter { this.emGasLimit = ovmOpts.emGasLimit || 100_000_000 this.dump = ovmOpts.dump this.initialized = ovmOpts.initialized || false - this.contracts = ovmOpts.contracts || { - ovmExecutionManager: { - address: Buffer.from(''), - addressHex: '0x', - }, - ovmStateManager: { - address: Buffer.from(''), - addressHex: '0x', - }, + + if (ovmOpts.contracts) { + this.contracts = ovmOpts.contracts + } else { + if (!this.dump) { + throw new Error('You must provide a state dump to initialize the OVM.') + } + + this.contracts = {} + for (const [name, account] of Object.entries(this.dump.accounts)) { + this.contracts[name] = { + name, + address: fromHexString(account.address), + addressHex: account.address, + code: account.code, + iface: new Interface(account.abi) + } + } } // Always need an instance of this. @@ -215,7 +226,7 @@ export default class VM extends AsyncEventEmitter { for (const address of addresses) { if (address) { const addr = address.toString('hex') - if (addr.startsWith('c0dec0dec0de') || addr.startsWith('deaddeaddead')) { + if (addr.startsWith('deaddeaddead')) { return } } @@ -237,38 +248,17 @@ export default class VM extends AsyncEventEmitter { this.initialized = true - let emAddress = this.dump.contracts.ovmExecutionManager - if (emAddress.startsWith('0x')) { - emAddress = emAddress.slice(2) - } - - let smAddress = this.dump.contracts.ovmStateManager - if (smAddress.startsWith('0x')) { - smAddress = smAddress.slice(2) - } - - this.contracts = { - ovmExecutionManager: { - address: Buffer.from(emAddress, 'hex'), - addressHex: '0x' + emAddress, - }, - ovmStateManager: { - address: Buffer.from(smAddress, 'hex'), - addressHex: '0x' + smAddress, - }, - } - - for (const [address, account] of Object.entries(this.dump.accounts)) { - await this.pStateManager.putAccount(Buffer.from(address, 'hex'), new Account()) + for (const account of Object.values(this.dump.accounts)) { + await this.pStateManager.putAccount(fromHexString(account.address), new Account()) await this.pStateManager.putContractCode( - Buffer.from(address, 'hex'), - Buffer.from(account.code, 'hex'), + fromHexString(account.address), + fromHexString(account.code), ) for (const [key, val] of Object.entries(account.storage)) { await this.pStateManager.putContractStorage( - Buffer.from(address, 'hex'), + fromHexString(account.address), Buffer.from(key, 'hex'), Buffer.from(val, 'hex'), ) @@ -347,13 +337,15 @@ export default class VM extends AsyncEventEmitter { }) } - getContractName(address: Buffer) { - if (address.equals(this.contracts.ovmExecutionManager.address)) { - return 'OVM_ExecutionManager' - } else if (address.equals(this.contracts.ovmStateManager.address)) { - return 'OVM_StateManager' - } else { - return `UNKNOWN CONTRACT (${'0x' + address.toString('hex')})` - } + getContract(address: Buffer): OVMContract | undefined { + return Object.values(this.contracts).find((contract) => { + return contract.address.equals(address) + }) + } + + getContractByName(name: string): OVMContract | undefined { + return Object.values(this.contracts).find((contract) => { + return contract.name === name + }) } } diff --git a/packages/vm/lib/runTx.ts b/packages/vm/lib/runTx.ts index 8d5315c6ed6..5c49e2a870a 100644 --- a/packages/vm/lib/runTx.ts +++ b/packages/vm/lib/runTx.ts @@ -142,10 +142,13 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { gasLimit: gasLimit.mul(new BN(5)), // TODO: Find a cleaner way to do this, it works for now though. to: tx.to.toString('hex') !== '' ? tx.to : undefined, value: tx.value, - data: tx.data, + data: tx.serialize(), }) const evm = new EVM(this, txContext, block) + + console.log('---------- BEGIN TRANSACTION TRACE ----------') const results = (await evm.executeMessage(message)) as RunTxResult + console.log('---------- END TRANSACTION TRACE ----------') /* * Parse results From bb4525561e8190fc713e48b216cb7a9bce247efc Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Wed, 7 Oct 2020 17:15:53 -0400 Subject: [PATCH 11/31] Linted files --- lib/ovm/ovm-state-manager.ts | 6 ++--- lib/ovm/utils/buffer-utils.ts | 8 ++++++- packages/vm/lib/evm/evm.ts | 40 ++++++++++++++++++++++++---------- packages/vm/lib/evm/message.ts | 8 +++---- packages/vm/lib/index.ts | 6 ++--- 5 files changed, 45 insertions(+), 23 deletions(-) diff --git a/lib/ovm/ovm-state-manager.ts b/lib/ovm/ovm-state-manager.ts index 58ebc5b613e..119469fcb65 100644 --- a/lib/ovm/ovm-state-manager.ts +++ b/lib/ovm/ovm-state-manager.ts @@ -47,7 +47,7 @@ export class OvmStateManager { let ret: any if (fragment.name in this._handlers) { ret = await this._handlers[fragment.name](...functionArgs) - ret = (ret === null || ret === undefined) ? ret : [ret] + ret = ret === null || ret === undefined ? ret : [ret] } try { @@ -70,13 +70,13 @@ export class OvmStateManager { async setAccountNonce(address: string, nonce: BigNumber): Promise { const account = await this.vm.pStateManager.getAccount(fromHexString(address)) - account.nonce = (new BN(nonce.toNumber())).toArrayLike(Buffer) + account.nonce = new BN(nonce.toNumber()).toArrayLike(Buffer) return this.vm.pStateManager.putAccount(fromHexString(address), account) } async getAccountNonce(address: string): Promise { const account = await this.vm.pStateManager.getAccount(fromHexString(address)) - return (new BN(account.nonce)).toNumber() + return new BN(account.nonce).toNumber() } async getAccountEthAddress(address: string): Promise { diff --git a/lib/ovm/utils/buffer-utils.ts b/lib/ovm/utils/buffer-utils.ts index 7b8fbe56884..2669c789a08 100644 --- a/lib/ovm/utils/buffer-utils.ts +++ b/lib/ovm/utils/buffer-utils.ts @@ -3,7 +3,13 @@ export const toHexAddress = (buf: any): string => { throw new Error('Buffer must be at least 20 bytes to be an address.') } - return '0x' + buf.slice(buf.length - 20).toString('hex').padStart(40, '0') + return ( + '0x' + + buf + .slice(buf.length - 20) + .toString('hex') + .padStart(40, '0') + ) } export const toHexString = (buf: any): string => { diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index eaf1a24c636..694bf0d8e99 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -130,7 +130,7 @@ export default class EVM { if (code.length === 0) { await this._state.putContractCode( message.caller, - fromHexString(this._vm.contracts.mockOVM_ECDSAContractAccount.code) + fromHexString(this._vm.contracts.mockOVM_ECDSAContractAccount.code), ) } @@ -145,8 +145,11 @@ export default class EVM { let result if (message.to) { const code = await this._state.getContractCode(message.to) - const isECDSAContractAccount = toHexString(code) === this._vm.contracts.mockOVM_ECDSAContractAccount.code - const target = isECDSAContractAccount ? this._vm.getContractByName('mockOVM_ECDSAContractAccount') : this._vm.getContract(message.to) + const isECDSAContractAccount = + toHexString(code) === this._vm.contracts.mockOVM_ECDSAContractAccount.code + const target = isECDSAContractAccount + ? this._vm.getContractByName('mockOVM_ECDSAContractAccount') + : this._vm.getContract(message.to) if (target) { let methodId = '0x' + message.data.slice(0, 4).toString('hex') @@ -155,8 +158,14 @@ export default class EVM { try { fragment = target.iface.getFunction(methodId) } catch (err) { - console.error(`\nCaught decoding error for ${target.name} with data: ${toHexString(message.data)}, ${err}`) - console.error(`Attempting to try again with function parameters removed in sighash calculation.`) + console.error( + `\nCaught decoding error for ${target.name} with data: ${toHexString( + message.data, + )}, ${err}`, + ) + console.error( + `Attempting to try again with function parameters removed in sighash calculation.`, + ) let correctedMethodId: string | undefined for (const functionName of Object.keys(target.iface.functions)) { @@ -175,23 +184,30 @@ export default class EVM { try { fragment = target.iface.getFunction(correctedMethodId) methodId = correctedMethodId - console.log(`Found a suitable function match: ${target.name}.${fragment.name}, continuing.`) + console.log( + `Found a suitable function match: ${target.name}.${fragment.name}, continuing.`, + ) } catch (err) { - console.error(`Second decoding attempt failed for ${target.name} with data: ${toHexString(message.data)}, ${err}`) + console.error( + `Second decoding attempt failed for ${target.name} with data: ${toHexString( + message.data, + )}, ${err}`, + ) throw err } } - message.data = Buffer.concat([ - fromHexString(methodId), - message.data.slice(4) - ]) + message.data = Buffer.concat([fromHexString(methodId), message.data.slice(4)]) const functionArgs = target.iface.decodeFunctionData(fragment, toHexString(message.data)) console.log(`\nCalling ${target.name}.${fragment.name} with args: ${functionArgs}`) } else { - console.log(`Calling unknown contract (${toHexString(message.to)}) with data: ${toHexString(message.data)}`) + console.log( + `Calling unknown contract (${toHexString(message.to)}) with data: ${toHexString( + message.data, + )}`, + ) } if (target && target.name === 'OVM_StateManager') { diff --git a/packages/vm/lib/evm/message.ts b/packages/vm/lib/evm/message.ts index 442bb365c36..47b3ae67bd5 100644 --- a/packages/vm/lib/evm/message.ts +++ b/packages/vm/lib/evm/message.ts @@ -61,8 +61,8 @@ export default class Message { const calldata = vm.contracts.OVM_ExecutionManager.iface.encodeFunctionData('run', [ { - timestamp: (new BN(block.header.timestamp)).toNumber(), - number: (new BN(block.header.number)).toNumber(), + timestamp: new BN(block.header.timestamp).toNumber(), + number: new BN(block.header.number).toNumber(), l1QueueOrigin: 0, l1Txorigin: toHexString(this.caller), entrypoint: toHexString(this.caller), @@ -72,10 +72,10 @@ export default class Message { 0, 0, '0x' + '00'.repeat(32), - '0x' + '00'.repeat(32) + '0x' + '00'.repeat(32), ]), }, - vm.contracts.OVM_StateManager.addressHex + vm.contracts.OVM_StateManager.addressHex, ]) return new Message({ diff --git a/packages/vm/lib/index.ts b/packages/vm/lib/index.ts index 53f0784b0fd..b34fdc4fb9d 100644 --- a/packages/vm/lib/index.ts +++ b/packages/vm/lib/index.ts @@ -207,7 +207,7 @@ export default class VM extends AsyncEventEmitter { address: fromHexString(account.address), addressHex: account.address, code: account.code, - iface: new Interface(account.abi) + iface: new Interface(account.abi), } } } @@ -338,13 +338,13 @@ export default class VM extends AsyncEventEmitter { } getContract(address: Buffer): OVMContract | undefined { - return Object.values(this.contracts).find((contract) => { + return Object.values(this.contracts).find(contract => { return contract.address.equals(address) }) } getContractByName(name: string): OVMContract | undefined { - return Object.values(this.contracts).find((contract) => { + return Object.values(this.contracts).find(contract => { return contract.name === name }) } From 2a48aeb70fd672dc6684821c04bd1db0938f9370 Mon Sep 17 00:00:00 2001 From: ben-chain Date: Wed, 7 Oct 2020 22:46:44 -0400 Subject: [PATCH 12/31] kelvin changes --- package.json | 4 +- packages/vm/lib/evm/evm.ts | 88 +++++++++++++++++++------------------- 2 files changed, 47 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index b47b991749b..2d5c9df9792 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "ethereumjs-ovm", - "version": "4.2.0", + "name": "@eth-optimism/ethereumjs-vm", + "version": "4.2.0-alpha.0", "description": "An Ethereum VM implementation", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index 694bf0d8e99..23796b76531 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -154,52 +154,54 @@ export default class EVM { if (target) { let methodId = '0x' + message.data.slice(0, 4).toString('hex') - let fragment: any - try { - fragment = target.iface.getFunction(methodId) - } catch (err) { - console.error( - `\nCaught decoding error for ${target.name} with data: ${toHexString( - message.data, - )}, ${err}`, - ) - console.error( - `Attempting to try again with function parameters removed in sighash calculation.`, - ) - - let correctedMethodId: string | undefined - for (const functionName of Object.keys(target.iface.functions)) { - const possibleMethodId = ethers.utils.id(functionName.split('(')[0] + '()').slice(0, 10) - if (possibleMethodId === methodId) { - correctedMethodId = ethers.utils.id(functionName).slice(0, 10) - break - } - } - - if (!correctedMethodId) { - console.error(`Cannot find a suitable function match, throwing.`) - throw err - } - - try { - fragment = target.iface.getFunction(correctedMethodId) - methodId = correctedMethodId - console.log( - `Found a suitable function match: ${target.name}.${fragment.name}, continuing.`, - ) - } catch (err) { - console.error( - `Second decoding attempt failed for ${target.name} with data: ${toHexString( - message.data, - )}, ${err}`, - ) - throw err - } - } + let fragment = target.iface.getFunction(methodId) + + // try { + // fragment = target.iface.getFunction(methodId) + // } catch (err) { + // console.error( + // `\nCaught decoding error for ${target.name} with data: ${toHexString( + // message.data, + // )}, ${err}`, + // ) + // console.error( + // `Attempting to try again with function parameters removed in sighash calculation.`, + // ) + + // let correctedMethodId: string | undefined + // for (const functionName of Object.keys(target.iface.functions)) { + // const possibleMethodId = ethers.utils.id(functionName.split('(')[0] + '()').slice(0, 10) + // if (possibleMethodId === methodId) { + // correctedMethodId = ethers.utils.id(functionName).slice(0, 10) + // break + // } + // } + + // if (!correctedMethodId) { + // console.error(`Cannot find a suitable function match, throwing.`) + // throw err + // } + + // try { + // fragment = target.iface.getFunction(correctedMethodId) + // methodId = correctedMethodId + // console.log( + // `Found a suitable function match: ${target.name}.${fragment.name}, continuing.`, + // ) + // } catch (err) { + // console.error( + // `Second decoding attempt failed for ${target.name} with data: ${toHexString( + // message.data, + // )}, ${err}`, + // ) + // throw err + // } + // } message.data = Buffer.concat([fromHexString(methodId), message.data.slice(4)]) - + console.log(`BEGIN: POTAYTOES, data is: ${toHexString(message.data)}, target is: ${toHexAddress(message.to)}`) const functionArgs = target.iface.decodeFunctionData(fragment, toHexString(message.data)) + console.log('END: POTAYTOES') console.log(`\nCalling ${target.name}.${fragment.name} with args: ${functionArgs}`) } else { From 3147553d47f64a0d52772b1c87edeb22c52876b3 Mon Sep 17 00:00:00 2001 From: ben-chain Date: Mon, 12 Oct 2020 11:19:24 -0400 Subject: [PATCH 13/31] update logging --- packages/vm/lib/evm/interpreter.ts | 53 +++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index 082aa3d5085..ee993c428b6 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -12,8 +12,9 @@ import { handlers as opHandlers, OpHandler } from './opFns' import { Logger } from '../ovm/utils/logger' import { env } from 'process' import { toHexAddress, toHexString } from '../ovm/utils/buffer-utils' +import { info } from 'console' -const logger = new Logger('ethjs-ovm:interpreter') +const logger = new Logger('js-ovm:intrp') export interface InterpreterOpts { pc?: number @@ -70,8 +71,12 @@ export default class Interpreter { callLogger: Logger stepLogger: Logger memLogger: Logger + memSizeLogger: Logger + gasLogger: Logger } } + _firstStep: boolean + _initialGas: number constructor(vm: any, eei: EEI) { this._vm = vm // TODO: remove when not needed @@ -93,6 +98,8 @@ export default class Interpreter { } this._loggers = {} + this._firstStep = true + this._initialGas = 0 } async run(code: Buffer, opts: InterpreterOpts = {}): Promise { @@ -238,17 +245,26 @@ export default class Interpreter { } _logStep(step: InterpreterStep): void { - if (!env.DEBUG?.includes(logger.namespace) && !logger.enabled) { + if (env.DEBUG_OVM != 'true') { return } + if (this._firstStep && step.depth == 0) { + this._initialGas = step.gasLeft.toNumber() + this._firstStep = false + } + if (!(step.depth in this._loggers)) { - const contractName = this._vm.getContractName(step.address) + const contractName = this._vm.getContract(step.address) const description = step.depth === 0 ? 'OVM TX starts with' : 'EVM STEPS for' - const callLogger = new Logger(logger.namespace + ':calls') + const addressStart = step.address.slice(0, 2).toString('hex') + const addressEnd = step.address.slice(step.address.length - 4).toString('hex') + const callLogger = new Logger(logger.namespace + ':0x' + addressStart + addressEnd + '..' + ':calls') const stepLogger = new Logger(callLogger.namespace + ':steps') const memLogger = new Logger(callLogger.namespace + ':memory') + const memSizeLogger = new Logger(callLogger.namespace + ':memorysize') + const gasLogger = new Logger(callLogger.namespace + ':steps') callLogger.open(`${description} ${contractName} at depth ${step.depth}`) @@ -256,6 +272,8 @@ export default class Interpreter { callLogger, stepLogger, memLogger, + gasLogger, + memSizeLogger } } @@ -265,9 +283,12 @@ export default class Interpreter { const op = step.opcode.name if (op === 'RETURN' || op === 'REVERT') { + if (step.depth === 0) { + loggers.gasLogger.log(`OVM tx completed having used ${this._initialGas - step.gasLeft.toNumber()} gas.`) + } + const offset = stack[0].toNumber() const length = stack[1].toNumber() - const data = Buffer.from(memory.slice(offset, offset + length)) loggers.callLogger.log(`${op} with data: ${toHexString(data)}`) @@ -284,10 +305,22 @@ export default class Interpreter { const sighash = toHexString(calldata.slice(0, 4)) const fragment = this._vm.contracts.OVM_ExecutionManager.iface.getFunction(sighash) const functionName = fragment.name + loggers.callLogger.log(`trying the decodeFunctionData for ${functionName}, raw it is: 0x${calldata.toString('hex')}`) + loggers.callLogger.log(`the ideal encoding would be:${ + this._vm.contracts.OVM_ExecutionManager.iface.encodeFunctionData( + fragment, + [ + 1234, + '0x1234123412341234123412341234123412341234', + '0x6789678967896789' + ], + ) + }`) const functionArgs = this._vm.contracts.OVM_ExecutionManager.iface.decodeFunctionData( fragment, toHexString(calldata), ) as any[] + loggers.callLogger.log(`decoded it WUT`) loggers.callLogger.log( `CALL to OVM_ExecutionManager.${functionName}\nDecoded calldata: ${functionArgs}\nEncoded calldata: ${toHexString( @@ -301,9 +334,9 @@ export default class Interpreter { } } else { loggers.stepLogger.log( - `opcode: ${op.padEnd(20, ' ')}\npc: ${step.pc}\nstack: [${stack + `opcode: ${op.padEnd(10, ' ')} pc: ${step.pc}\nstack: [${stack .map((el, idx) => { - return `${idx}: ${toHexString(el)}` + return ` ${idx}: ${toHexString(el)}` }) .join('')}]\n`, ) @@ -312,7 +345,11 @@ export default class Interpreter { this._printNextMemory || ['CALL', 'CREATE', 'CREATE2', 'STATICCALL', 'DELEGATECALL'].includes(op) ) { - loggers.memLogger.log(`memory: [${toHexString(Buffer.from(memory))}]`) + const memsize = memory.length + if (memsize > 20000) { + loggers.memSizeLogger.log(`MSIZE of ${memsize} in memory modifying step.`) + } + loggers.memLogger.log(`$[${toHexString(Buffer.from(memory))}]`) } this._printNextMemory = ['MSTORE', 'CALLDATACOPY', 'RETURNDATACOPY', 'CODECOPY'].includes(op) From 35e0fd0602cc35244892730198f0d8c39b0b785c Mon Sep 17 00:00:00 2001 From: B T Date: Tue, 20 Oct 2020 19:14:32 -0400 Subject: [PATCH 14/31] random fixes --- lib/ovm/ovm-state-manager.ts | 6 +++++- packages/vm/lib/evm/evm.ts | 23 +++++++++++++++----- packages/vm/lib/evm/interpreter.ts | 34 +++++++++++++++--------------- packages/vm/lib/evm/message.ts | 9 +++++++- packages/vm/lib/runTx.ts | 1 + 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/lib/ovm/ovm-state-manager.ts b/lib/ovm/ovm-state-manager.ts index 119469fcb65..0e39505f03b 100644 --- a/lib/ovm/ovm-state-manager.ts +++ b/lib/ovm/ovm-state-manager.ts @@ -39,7 +39,7 @@ export class OvmStateManager { } } - async handleCall(message: Message): Promise { + async handleCall(message: Message, context: any): Promise { const methodId = '0x' + message.data.slice(0, 4).toString('hex') const fragment = this._iface.getFunction(methodId) const functionArgs = this._iface.decodeFunctionData(fragment, toHexString(message.data)) @@ -50,6 +50,10 @@ export class OvmStateManager { ret = ret === null || ret === undefined ? ret : [ret] } + if (fragment.name == 'owner') { + ret = ['0x' + context.origin.toString('hex')] + } + try { console.log(` ← Responding with: ${ret}`) const encodedRet = this._iface.encodeFunctionResult(fragment, ret) diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index 23796b76531..4502ee82b80 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -151,6 +151,8 @@ export default class EVM { ? this._vm.getContractByName('mockOVM_ECDSAContractAccount') : this._vm.getContract(message.to) + if (isECDSAContractAccount) { console.log(`account code is: ${toHexString(code)}`) } + if (target) { let methodId = '0x' + message.data.slice(0, 4).toString('hex') @@ -198,12 +200,11 @@ export default class EVM { // } // } - message.data = Buffer.concat([fromHexString(methodId), message.data.slice(4)]) - console.log(`BEGIN: POTAYTOES, data is: ${toHexString(message.data)}, target is: ${toHexAddress(message.to)}`) + // message.data = Buffer.concat([fromHexString(methodId), message.data.slice(4)]) const functionArgs = target.iface.decodeFunctionData(fragment, toHexString(message.data)) - console.log('END: POTAYTOES') console.log(`\nCalling ${target.name}.${fragment.name} with args: ${functionArgs}`) + console.log(`as raw data this is: ${toHexString(message.data)}`) } else { console.log( `Calling unknown contract (${toHexString(message.to)}) with data: ${toHexString( @@ -217,7 +218,7 @@ export default class EVM { gasUsed: new BN(0), execResult: { gasUsed: new BN(0), - returnValue: await this._vm.ovmStateManager.handleCall(message), + returnValue: await this._vm.ovmStateManager.handleCall(message, this._tx), }, } as EVMResult } else { @@ -227,6 +228,8 @@ export default class EVM { result = await this._executeCreate(message) } + console.log(`call result was: ${JSON.stringify(result.execResult.returnValue)}`) + // TODO: Move `gasRefund` to a tx-level result object // instead of `ExecResult`. result.execResult.gasRefund = this._refund.clone() @@ -243,16 +246,26 @@ export default class EVM { }) } + // OVM reverts have some flag-related metadata before the revert data--strip this out for providers etc. + let returnData: Buffer = this._targetMessageResult.execResult.returnValue + if ( + !!this._targetMessageResult.execResult.exceptionError + && returnData.byteLength >= 160 + ) { + returnData = returnData.slice(160) + } + result = { ...result, createdAddress: this._targetMessageResult.createdAddress, execResult: { ...result.execResult, - returnValue: this._targetMessageResult.execResult.returnValue, + returnValue: returnData, exceptionError: this._targetMessageResult.execResult.exceptionError, }, } } else { + // todo: break out error cases and surface here result.execResult.exceptionError = new VmError(ERROR.OVM_ERROR) } } diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index ee993c428b6..66b85c8067c 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -76,7 +76,7 @@ export default class Interpreter { } } _firstStep: boolean - _initialGas: number + _initialGas: BN constructor(vm: any, eei: EEI) { this._vm = vm // TODO: remove when not needed @@ -99,7 +99,7 @@ export default class Interpreter { this._loggers = {} this._firstStep = true - this._initialGas = 0 + this._initialGas = new BN(0) } async run(code: Buffer, opts: InterpreterOpts = {}): Promise { @@ -250,7 +250,7 @@ export default class Interpreter { } if (this._firstStep && step.depth == 0) { - this._initialGas = step.gasLeft.toNumber() + this._initialGas = step.gasLeft this._firstStep = false } @@ -260,7 +260,7 @@ export default class Interpreter { const addressStart = step.address.slice(0, 2).toString('hex') const addressEnd = step.address.slice(step.address.length - 4).toString('hex') - const callLogger = new Logger(logger.namespace + ':0x' + addressStart + addressEnd + '..' + ':calls') + const callLogger = new Logger(logger.namespace + ':0x' + addressStart + '..' + addressEnd + ':calls') const stepLogger = new Logger(callLogger.namespace + ':steps') const memLogger = new Logger(callLogger.namespace + ':memory') const memSizeLogger = new Logger(callLogger.namespace + ':memorysize') @@ -284,7 +284,7 @@ export default class Interpreter { if (op === 'RETURN' || op === 'REVERT') { if (step.depth === 0) { - loggers.gasLogger.log(`OVM tx completed having used ${this._initialGas - step.gasLeft.toNumber()} gas.`) + loggers.gasLogger.log(`OVM tx completed having used ${this._initialGas.sub(step.gasLeft).toString()} gas.`) } const offset = stack[0].toNumber() @@ -305,17 +305,17 @@ export default class Interpreter { const sighash = toHexString(calldata.slice(0, 4)) const fragment = this._vm.contracts.OVM_ExecutionManager.iface.getFunction(sighash) const functionName = fragment.name - loggers.callLogger.log(`trying the decodeFunctionData for ${functionName}, raw it is: 0x${calldata.toString('hex')}`) - loggers.callLogger.log(`the ideal encoding would be:${ - this._vm.contracts.OVM_ExecutionManager.iface.encodeFunctionData( - fragment, - [ - 1234, - '0x1234123412341234123412341234123412341234', - '0x6789678967896789' - ], - ) - }`) + // loggers.callLogger.log(`trying the decodeFunctionData for ${functionName}, raw it is: 0x${calldata.toString('hex')}`) + // loggers.callLogger.log(`the ideal encoding would be:${ + // this._vm.contracts.OVM_ExecutionManager.iface.encodeFunctionData( + // fragment, + // [ + // 1234, + // '0x1234123412341234123412341234123412341234', + // '0x6789678967896789' + // ], + // ) + // }`) const functionArgs = this._vm.contracts.OVM_ExecutionManager.iface.decodeFunctionData( fragment, toHexString(calldata), @@ -334,7 +334,7 @@ export default class Interpreter { } } else { loggers.stepLogger.log( - `opcode: ${op.padEnd(10, ' ')} pc: ${step.pc}\nstack: [${stack + `opcode: ${op.padEnd(10, ' ')} pc: ${step.pc.toString().padEnd(10, ' ')} gasLeft: ${step.gasLeft.toString()}\nstack: [${stack .map((el, idx) => { return ` ${idx}: ${toHexString(el)}` }) diff --git a/packages/vm/lib/evm/message.ts b/packages/vm/lib/evm/message.ts index 47b3ae67bd5..bc32be7a3b1 100644 --- a/packages/vm/lib/evm/message.ts +++ b/packages/vm/lib/evm/message.ts @@ -59,6 +59,13 @@ export default class Message { throw new Error('Cannot create a message because the ExecutionManager does not exist.') } + console.log(`gaslimit is ${this.gasLimit.toString('hex')}`) + console.log(`ovm gaslimit is ${vm.emGasLimit}`) + + const notTooBigGasLimit = BN.min(this.gasLimit, new BN(vm.emGasLimit)) + + console.log(`using gasLimit ${toHexString(notTooBigGasLimit.toBuffer())}`) + const calldata = vm.contracts.OVM_ExecutionManager.iface.encodeFunctionData('run', [ { timestamp: new BN(block.header.timestamp).toNumber(), @@ -66,7 +73,7 @@ export default class Message { l1QueueOrigin: 0, l1Txorigin: toHexString(this.caller), entrypoint: toHexString(this.caller), - gasLimit: this.gasLimit.toNumber(), + gasLimit: toHexString(notTooBigGasLimit.toBuffer()), data: vm.contracts.mockOVM_ECDSAContractAccount.iface.encodeFunctionData('execute', [ toHexString(this.data), 0, diff --git a/packages/vm/lib/runTx.ts b/packages/vm/lib/runTx.ts index 5c49e2a870a..37ef8b6938b 100644 --- a/packages/vm/lib/runTx.ts +++ b/packages/vm/lib/runTx.ts @@ -85,6 +85,7 @@ export default async function runTx(this: VM, opts: RunTxOpts): Promise { + console.log('in custom') // Skip these checks because we don't have these concepts in the OVM. opts.skipBalance = true opts.skipNonce = true From 7c7e236ef54085aa81d9115e74a3f9ab8150a53a Mon Sep 17 00:00:00 2001 From: B T Date: Wed, 21 Oct 2020 13:25:25 -0400 Subject: [PATCH 15/31] clean up logging --- lib/ovm/ovm-state-manager.ts | 1 - packages/vm/lib/evm/evm.ts | 122 ++++++++++++++--------------- packages/vm/lib/evm/interpreter.ts | 79 ++++++++++++------- packages/vm/lib/runTx.ts | 2 +- 4 files changed, 110 insertions(+), 94 deletions(-) diff --git a/lib/ovm/ovm-state-manager.ts b/lib/ovm/ovm-state-manager.ts index 0e39505f03b..a33559cc180 100644 --- a/lib/ovm/ovm-state-manager.ts +++ b/lib/ovm/ovm-state-manager.ts @@ -55,7 +55,6 @@ export class OvmStateManager { } try { - console.log(` ← Responding with: ${ret}`) const encodedRet = this._iface.encodeFunctionResult(fragment, ret) return fromHexString(encodedRet) } catch (err) { diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index 4502ee82b80..f14aa2dce47 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -151,67 +151,65 @@ export default class EVM { ? this._vm.getContractByName('mockOVM_ECDSAContractAccount') : this._vm.getContract(message.to) - if (isECDSAContractAccount) { console.log(`account code is: ${toHexString(code)}`) } - - if (target) { - let methodId = '0x' + message.data.slice(0, 4).toString('hex') - - let fragment = target.iface.getFunction(methodId) - - // try { - // fragment = target.iface.getFunction(methodId) - // } catch (err) { - // console.error( - // `\nCaught decoding error for ${target.name} with data: ${toHexString( - // message.data, - // )}, ${err}`, - // ) - // console.error( - // `Attempting to try again with function parameters removed in sighash calculation.`, - // ) - - // let correctedMethodId: string | undefined - // for (const functionName of Object.keys(target.iface.functions)) { - // const possibleMethodId = ethers.utils.id(functionName.split('(')[0] + '()').slice(0, 10) - // if (possibleMethodId === methodId) { - // correctedMethodId = ethers.utils.id(functionName).slice(0, 10) - // break - // } - // } - - // if (!correctedMethodId) { - // console.error(`Cannot find a suitable function match, throwing.`) - // throw err - // } - - // try { - // fragment = target.iface.getFunction(correctedMethodId) - // methodId = correctedMethodId - // console.log( - // `Found a suitable function match: ${target.name}.${fragment.name}, continuing.`, - // ) - // } catch (err) { - // console.error( - // `Second decoding attempt failed for ${target.name} with data: ${toHexString( - // message.data, - // )}, ${err}`, - // ) - // throw err - // } - // } - - // message.data = Buffer.concat([fromHexString(methodId), message.data.slice(4)]) - const functionArgs = target.iface.decodeFunctionData(fragment, toHexString(message.data)) - - console.log(`\nCalling ${target.name}.${fragment.name} with args: ${functionArgs}`) - console.log(`as raw data this is: ${toHexString(message.data)}`) - } else { - console.log( - `Calling unknown contract (${toHexString(message.to)}) with data: ${toHexString( - message.data, - )}`, - ) - } + // if (target) { + // let methodId = '0x' + message.data.slice(0, 4).toString('hex') + + // let fragment = target.iface.getFunction(methodId) + + // // try { + // // fragment = target.iface.getFunction(methodId) + // // } catch (err) { + // // console.error( + // // `\nCaught decoding error for ${target.name} with data: ${toHexString( + // // message.data, + // // )}, ${err}`, + // // ) + // // console.error( + // // `Attempting to try again with function parameters removed in sighash calculation.`, + // // ) + + // // let correctedMethodId: string | undefined + // // for (const functionName of Object.keys(target.iface.functions)) { + // // const possibleMethodId = ethers.utils.id(functionName.split('(')[0] + '()').slice(0, 10) + // // if (possibleMethodId === methodId) { + // // correctedMethodId = ethers.utils.id(functionName).slice(0, 10) + // // break + // // } + // // } + + // // if (!correctedMethodId) { + // // console.error(`Cannot find a suitable function match, throwing.`) + // // throw err + // // } + + // // try { + // // fragment = target.iface.getFunction(correctedMethodId) + // // methodId = correctedMethodId + // // console.log( + // // `Found a suitable function match: ${target.name}.${fragment.name}, continuing.`, + // // ) + // // } catch (err) { + // // console.error( + // // `Second decoding attempt failed for ${target.name} with data: ${toHexString( + // // message.data, + // // )}, ${err}`, + // // ) + // // throw err + // // } + // // } + + // // message.data = Buffer.concat([fromHexString(methodId), message.data.slice(4)]) + // const functionArgs = target.iface.decodeFunctionData(fragment, toHexString(message.data)) + + // console.log(`\nCalling ${target.name}.${fragment.name} with args: ${functionArgs}`) + // console.log(`as raw data this is: ${toHexString(message.data)}`) + // } else { + // console.log( + // `Calling unknown contract (${toHexString(message.to)}) with data: ${toHexString( + // message.data, + // )}`, + // ) + // } if (target && target.name === 'OVM_StateManager') { result = { @@ -228,8 +226,6 @@ export default class EVM { result = await this._executeCreate(message) } - console.log(`call result was: ${JSON.stringify(result.execResult.returnValue)}`) - // TODO: Move `gasRefund` to a tx-level result object // instead of `ExecResult`. result.execResult.gasRefund = this._refund.clone() diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index 66b85c8067c..95de80f2e8a 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -200,7 +200,7 @@ export default class Interpreter { } try { - this._logStep(eventObj) + await this._logStep(eventObj) } catch (err) { logger.log(`STEP LOGGING ERROR: ${err.toString()}`) } @@ -244,9 +244,9 @@ export default class Interpreter { return jumps } - _logStep(step: InterpreterStep): void { + async _logStep(step: InterpreterStep): Promise { if (env.DEBUG_OVM != 'true') { - return + return } if (this._firstStep && step.depth == 0) { @@ -301,37 +301,58 @@ export default class Interpreter { const calldata = Buffer.from(memory.slice(offset, offset + length)) - if (target.equals(this._vm.contracts.OVM_ExecutionManager.address)) { - const sighash = toHexString(calldata.slice(0, 4)) - const fragment = this._vm.contracts.OVM_ExecutionManager.iface.getFunction(sighash) - const functionName = fragment.name - // loggers.callLogger.log(`trying the decodeFunctionData for ${functionName}, raw it is: 0x${calldata.toString('hex')}`) - // loggers.callLogger.log(`the ideal encoding would be:${ - // this._vm.contracts.OVM_ExecutionManager.iface.encodeFunctionData( - // fragment, - // [ - // 1234, - // '0x1234123412341234123412341234123412341234', - // '0x6789678967896789' - // ], - // ) - // }`) - const functionArgs = this._vm.contracts.OVM_ExecutionManager.iface.decodeFunctionData( - fragment, - toHexString(calldata), - ) as any[] - loggers.callLogger.log(`decoded it WUT`) - loggers.callLogger.log( - `CALL to OVM_ExecutionManager.${functionName}\nDecoded calldata: ${functionArgs}\nEncoded calldata: ${toHexString( - calldata.slice(4), - )}`, - ) + + const code = await this._state.getContractCode(target) + const isECDSAContractAccount = + toHexString(code) === this._vm.contracts.mockOVM_ECDSAContractAccount.code + const targetContract = isECDSAContractAccount + ? this._vm.getContractByName('mockOVM_ECDSAContractAccount') + : this._vm.getContract(target) + + if (targetContract) { + let methodId = '0x' + calldata.slice(0, 4).toString('hex') + let fragment = targetContract.iface.getFunction(methodId) + + let logString + try { + const decodedArgs = targetContract.iface.decodeFunctionData(fragment, toHexString(calldata)) + logString = `CALL to ${targetContract.name}.${fragment.name} with args: ${decodedArgs}` + } catch { + logString = `CALL to ${targetContract.name}.${fragment.name} with raw data (failed to decode): 0x${calldata.toString('hex')}` + } + + loggers.callLogger.log(logString) } else { loggers.callLogger.log( - `CALL to ${toHexAddress(target)} with data:\n${toHexString(calldata)}`, + `CALL to unknown contract (${toHexString(target)}) with data: ${toHexString( + calldata + )}`, ) } + + + + + // if (target.equals(this._vm.contracts.OVM_ExecutionManager.address)) { + // const sighash = toHexString(calldata.slice(0, 4)) + // const fragment = this._vm.contracts.OVM_ExecutionManager.iface.getFunction(sighash) + // const functionName = fragment.name + // const functionArgs = this._vm.contracts.OVM_ExecutionManager.iface.decodeFunctionData( + // fragment, + // toHexString(calldata), + // ) as any[] + + // loggers.callLogger.log( + // `CALL to OVM_ExecutionManager.${functionName}\nDecoded calldata: ${functionArgs}\nEncoded calldata: ${toHexString( + // calldata.slice(4), + // )}`, + // ) + // } else { + // loggers.callLogger.log( + // `CALL to ${toHexAddress(target)} with data:\n${toHexString(calldata)}`, + // ) + // } } else { loggers.stepLogger.log( `opcode: ${op.padEnd(10, ' ')} pc: ${step.pc.toString().padEnd(10, ' ')} gasLeft: ${step.gasLeft.toString()}\nstack: [${stack diff --git a/packages/vm/lib/runTx.ts b/packages/vm/lib/runTx.ts index 37ef8b6938b..b616e328107 100644 --- a/packages/vm/lib/runTx.ts +++ b/packages/vm/lib/runTx.ts @@ -106,7 +106,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { // Validate gas limit against base fee const basefee = tx.getBaseFee() const gasLimit = new BN(tx.gasLimit) - if (gasLimit.lt(basefee)) { + if (gasLimit.lt(basefee)) { throw new Error('base fee exceeds gas limit') } gasLimit.isub(basefee) From bc1dcb652ac38dedcfa507363ccd4ae9f52ebd69 Mon Sep 17 00:00:00 2001 From: B T Date: Wed, 21 Oct 2020 13:52:35 -0400 Subject: [PATCH 16/31] remove more console.logs --- packages/vm/lib/evm/message.ts | 5 ----- packages/vm/lib/runTx.ts | 3 --- 2 files changed, 8 deletions(-) diff --git a/packages/vm/lib/evm/message.ts b/packages/vm/lib/evm/message.ts index bc32be7a3b1..a0a2dea7e20 100644 --- a/packages/vm/lib/evm/message.ts +++ b/packages/vm/lib/evm/message.ts @@ -59,13 +59,8 @@ export default class Message { throw new Error('Cannot create a message because the ExecutionManager does not exist.') } - console.log(`gaslimit is ${this.gasLimit.toString('hex')}`) - console.log(`ovm gaslimit is ${vm.emGasLimit}`) - const notTooBigGasLimit = BN.min(this.gasLimit, new BN(vm.emGasLimit)) - console.log(`using gasLimit ${toHexString(notTooBigGasLimit.toBuffer())}`) - const calldata = vm.contracts.OVM_ExecutionManager.iface.encodeFunctionData('run', [ { timestamp: new BN(block.header.timestamp).toNumber(), diff --git a/packages/vm/lib/runTx.ts b/packages/vm/lib/runTx.ts index b616e328107..70095cd0e56 100644 --- a/packages/vm/lib/runTx.ts +++ b/packages/vm/lib/runTx.ts @@ -85,7 +85,6 @@ export default async function runTx(this: VM, opts: RunTxOpts): Promise { - console.log('in custom') // Skip these checks because we don't have these concepts in the OVM. opts.skipBalance = true opts.skipNonce = true @@ -147,9 +146,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { }) const evm = new EVM(this, txContext, block) - console.log('---------- BEGIN TRANSACTION TRACE ----------') const results = (await evm.executeMessage(message)) as RunTxResult - console.log('---------- END TRANSACTION TRACE ----------') /* * Parse results From 9ea2835864c5a5479dca17526e72afb32b3e1e1a Mon Sep 17 00:00:00 2001 From: B T Date: Sat, 24 Oct 2020 19:34:13 -0400 Subject: [PATCH 17/31] fix address begins with 0 bug --- lib/ovm/utils/buffer-utils.ts | 4 +++- packages/vm/lib/evm/evm.ts | 2 +- packages/vm/lib/evm/interpreter.ts | 9 +++------ 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/ovm/utils/buffer-utils.ts b/lib/ovm/utils/buffer-utils.ts index 2669c789a08..c193a568e2f 100644 --- a/lib/ovm/utils/buffer-utils.ts +++ b/lib/ovm/utils/buffer-utils.ts @@ -1,6 +1,8 @@ export const toHexAddress = (buf: any): string => { + // pad shorter values out if (buf.length < 20) { - throw new Error('Buffer must be at least 20 bytes to be an address.') + buf = Buffer.concat([Buffer.alloc(31), buf]) + // throw new Error('Buffer must be at least 20 bytes to be an address.') } return ( diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index f14aa2dce47..376421dfbe5 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -529,7 +529,7 @@ export default class EVM { async _generateAddress(message: Message): Promise { return fromHexString( toHexAddress( - await this._vm.pStateManager.getContractStorage( + await this._state.getContractStorage( this._vm.contracts.OVM_ExecutionManager.address, Buffer.from('00'.repeat(31) + '0f', 'hex'), ), diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index 95de80f2e8a..073988aac48 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -266,7 +266,7 @@ export default class Interpreter { const memSizeLogger = new Logger(callLogger.namespace + ':memorysize') const gasLogger = new Logger(callLogger.namespace + ':steps') - callLogger.open(`${description} ${contractName} at depth ${step.depth}`) + stepLogger.open(`${description} ${contractName} at depth ${step.depth}`) this._loggers[step.depth] = { callLogger, @@ -291,18 +291,15 @@ export default class Interpreter { const length = stack[1].toNumber() const data = Buffer.from(memory.slice(offset, offset + length)) + loggers.stepLogger.close() loggers.callLogger.log(`${op} with data: ${toHexString(data)}`) - loggers.callLogger.close() delete this._loggers[step.depth] } else if (op === 'CALL') { const target = stack[1].toBuffer() const offset = stack[3].toNumber() const length = stack[4].toNumber() - const calldata = Buffer.from(memory.slice(offset, offset + length)) - - const code = await this._state.getContractCode(target) const isECDSAContractAccount = toHexString(code) === this._vm.contracts.mockOVM_ECDSAContractAccount.code @@ -359,7 +356,7 @@ export default class Interpreter { .map((el, idx) => { return ` ${idx}: ${toHexString(el)}` }) - .join('')}]\n`, + .join('')}]`, ) if ( From 5e9c2b89c04202fd33c8ffda5534d62b8453d406 Mon Sep 17 00:00:00 2001 From: B T Date: Tue, 27 Oct 2020 12:27:42 -0400 Subject: [PATCH 18/31] no-message create revert fix --- packages/vm/lib/evm/evm.ts | 28 ++++++++++++++++++++++++++-- packages/vm/lib/evm/interpreter.ts | 6 +++--- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index 376421dfbe5..e57d1a7b9bc 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -106,6 +106,7 @@ export default class EVM { // Custom variables _targetMessage: Message | undefined _targetMessageResult: EVMResult | undefined + _accountMessageResult: EVMResult | undefined constructor(vm: any, txContext: TxContext, block: any) { this._vm = vm @@ -234,6 +235,11 @@ export default class EVM { this._targetMessageResult = result } + // if (message.depth === 1 && (await this._state.getContractCode(message.to)).toString('hex') == this._vm.contracts.OVM_ECDSAContractAccount.code.toString('hex')) { + // console.log(`found and set EOA acct message`) + // this._entryPointResult = result + // } + let wasDeployException = false if (message.depth === 0) { if (this._targetMessageResult) { if (result.execResult.logs) { @@ -251,13 +257,24 @@ export default class EVM { returnData = returnData.slice(160) } + result.execResult.exceptionError + + const EOAReturnedFalse = this._accountMessageResult?.execResult.returnValue.slice(0,32).toString('hex') == '00'.repeat(32) + wasDeployException = EOAReturnedFalse && !this._targetMessageResult.execResult.exceptionError + console.log(`detected deploy exception?: ${wasDeployException}`) + const exceptionError = wasDeployException + ? new VmError(ERROR.REVERT) + : this._targetMessageResult.execResult.exceptionError + + console.log(`exception error is: ${JSON.stringify(exceptionError)}`) + result = { ...result, createdAddress: this._targetMessageResult.createdAddress, execResult: { ...result.execResult, returnValue: returnData, - exceptionError: this._targetMessageResult.execResult.exceptionError, + exceptionError }, } } else { @@ -267,13 +284,20 @@ export default class EVM { } const err = result.execResult.exceptionError - if (err) { + if (err && !wasDeployException) { result.execResult.logs = [] await this._state.revert() } else { await this._state.commit() } + if ( + message.depth == 1 + && message.to.toString() != this._vm.contracts.OVM_StateManager.address.toString() + ) { + this._accountMessageResult = result + } + await this._vm._emit('afterMessage', result) return result diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index 073988aac48..d4d6ba8f736 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -258,9 +258,9 @@ export default class Interpreter { const contractName = this._vm.getContract(step.address) const description = step.depth === 0 ? 'OVM TX starts with' : 'EVM STEPS for' - const addressStart = step.address.slice(0, 2).toString('hex') - const addressEnd = step.address.slice(step.address.length - 4).toString('hex') - const callLogger = new Logger(logger.namespace + ':0x' + addressStart + '..' + addressEnd + ':calls') + const addressStart = step.address.slice(0, 3).toString('hex') + const addressEnd = step.address.slice(step.address.length - 3).toString('hex') + const callLogger = new Logger(logger.namespace + ':0x' + addressStart + '..' + addressEnd + ':d' + step.depth + ':calls') const stepLogger = new Logger(callLogger.namespace + ':steps') const memLogger = new Logger(callLogger.namespace + ':memory') const memSizeLogger = new Logger(callLogger.namespace + ':memorysize') From 957801c47eda23edf7274ab112c94cce62dc4c23 Mon Sep 17 00:00:00 2001 From: Ben Jones Date: Thu, 5 Nov 2020 15:49:29 -0500 Subject: [PATCH 19/31] improve logging --- packages/vm/lib/evm/evm.ts | 19 ++++++++---------- packages/vm/lib/evm/interpreter.ts | 32 ++++++++++++++++++++++-------- packages/vm/lib/evm/message.ts | 4 ++-- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index e57d1a7b9bc..cdf5c48443b 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -231,6 +231,14 @@ export default class EVM { // instead of `ExecResult`. result.execResult.gasRefund = this._refund.clone() + const err = result.execResult.exceptionError + if (err) { + result.execResult.logs = [] + await this._state.revert() + } else { + await this._state.commit() + } + if (isTargetMessage) { this._targetMessageResult = result } @@ -261,13 +269,10 @@ export default class EVM { const EOAReturnedFalse = this._accountMessageResult?.execResult.returnValue.slice(0,32).toString('hex') == '00'.repeat(32) wasDeployException = EOAReturnedFalse && !this._targetMessageResult.execResult.exceptionError - console.log(`detected deploy exception?: ${wasDeployException}`) const exceptionError = wasDeployException ? new VmError(ERROR.REVERT) : this._targetMessageResult.execResult.exceptionError - console.log(`exception error is: ${JSON.stringify(exceptionError)}`) - result = { ...result, createdAddress: this._targetMessageResult.createdAddress, @@ -283,14 +288,6 @@ export default class EVM { } } - const err = result.execResult.exceptionError - if (err && !wasDeployException) { - result.execResult.logs = [] - await this._state.revert() - } else { - await this._state.commit() - } - if ( message.depth == 1 && message.to.toString() != this._vm.contracts.OVM_StateManager.address.toString() diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index d4d6ba8f736..8bd69e2a825 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -254,9 +254,11 @@ export default class Interpreter { this._firstStep = false } + const isEntryPoint = step.depth === 0 + if (!(step.depth in this._loggers)) { const contractName = this._vm.getContract(step.address) - const description = step.depth === 0 ? 'OVM TX starts with' : 'EVM STEPS for' + const description = isEntryPoint ? 'OVM TX starts with' : 'EVM STEPS for' const addressStart = step.address.slice(0, 3).toString('hex') const addressEnd = step.address.slice(step.address.length - 3).toString('hex') @@ -266,7 +268,11 @@ export default class Interpreter { const memSizeLogger = new Logger(callLogger.namespace + ':memorysize') const gasLogger = new Logger(callLogger.namespace + ':steps') - stepLogger.open(`${description} ${contractName} at depth ${step.depth}`) + if(isEntryPoint) { + callLogger.open(`${description} ${contractName} at depth ${step.depth}`) + } else { + stepLogger.open(`${description} ${contractName} at depth ${step.depth}`) + } this._loggers[step.depth] = { callLogger, @@ -282,17 +288,27 @@ export default class Interpreter { const memory = step.memory const op = step.opcode.name - if (op === 'RETURN' || op === 'REVERT') { + if (['RETURN','REVERT','STOP','INVALID'].includes(op)) { if (step.depth === 0) { loggers.gasLogger.log(`OVM tx completed having used ${this._initialGas.sub(step.gasLeft).toString()} gas.`) } - const offset = stack[0].toNumber() - const length = stack[1].toNumber() - const data = Buffer.from(memory.slice(offset, offset + length)) + if (['RETURN','REVERT'].includes(op)) { + const offset = stack[0].toNumber() + const length = stack[1].toNumber() + const data = Buffer.from(memory.slice(offset, offset + length)) + loggers.callLogger.log(`${op} with data: ${toHexString(data)}`) + } else { + loggers.callLogger.log(op) + } + + + if(isEntryPoint) { + loggers.callLogger.close() + } else { + loggers.stepLogger.close() + } - loggers.stepLogger.close() - loggers.callLogger.log(`${op} with data: ${toHexString(data)}`) delete this._loggers[step.depth] } else if (op === 'CALL') { const target = stack[1].toBuffer() diff --git a/packages/vm/lib/evm/message.ts b/packages/vm/lib/evm/message.ts index a0a2dea7e20..dbf6a62a291 100644 --- a/packages/vm/lib/evm/message.ts +++ b/packages/vm/lib/evm/message.ts @@ -64,9 +64,9 @@ export default class Message { const calldata = vm.contracts.OVM_ExecutionManager.iface.encodeFunctionData('run', [ { timestamp: new BN(block.header.timestamp).toNumber(), - number: new BN(block.header.number).toNumber(), + blockNumber: new BN(block.header.number).toNumber(), l1QueueOrigin: 0, - l1Txorigin: toHexString(this.caller), + l1TxOrigin: toHexString(this.caller), entrypoint: toHexString(this.caller), gasLimit: toHexString(notTooBigGasLimit.toBuffer()), data: vm.contracts.mockOVM_ECDSAContractAccount.iface.encodeFunctionData('execute', [ From d35c0e72821596fb559316bc1830a9f4e6fbd980 Mon Sep 17 00:00:00 2001 From: Ben Jones Date: Thu, 5 Nov 2020 16:21:51 -0500 Subject: [PATCH 20/31] remove unused code --- packages/vm/lib/evm/evm.ts | 60 -------------------------------------- 1 file changed, 60 deletions(-) diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index cdf5c48443b..2aa86cb9a56 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -152,66 +152,6 @@ export default class EVM { ? this._vm.getContractByName('mockOVM_ECDSAContractAccount') : this._vm.getContract(message.to) - // if (target) { - // let methodId = '0x' + message.data.slice(0, 4).toString('hex') - - // let fragment = target.iface.getFunction(methodId) - - // // try { - // // fragment = target.iface.getFunction(methodId) - // // } catch (err) { - // // console.error( - // // `\nCaught decoding error for ${target.name} with data: ${toHexString( - // // message.data, - // // )}, ${err}`, - // // ) - // // console.error( - // // `Attempting to try again with function parameters removed in sighash calculation.`, - // // ) - - // // let correctedMethodId: string | undefined - // // for (const functionName of Object.keys(target.iface.functions)) { - // // const possibleMethodId = ethers.utils.id(functionName.split('(')[0] + '()').slice(0, 10) - // // if (possibleMethodId === methodId) { - // // correctedMethodId = ethers.utils.id(functionName).slice(0, 10) - // // break - // // } - // // } - - // // if (!correctedMethodId) { - // // console.error(`Cannot find a suitable function match, throwing.`) - // // throw err - // // } - - // // try { - // // fragment = target.iface.getFunction(correctedMethodId) - // // methodId = correctedMethodId - // // console.log( - // // `Found a suitable function match: ${target.name}.${fragment.name}, continuing.`, - // // ) - // // } catch (err) { - // // console.error( - // // `Second decoding attempt failed for ${target.name} with data: ${toHexString( - // // message.data, - // // )}, ${err}`, - // // ) - // // throw err - // // } - // // } - - // // message.data = Buffer.concat([fromHexString(methodId), message.data.slice(4)]) - // const functionArgs = target.iface.decodeFunctionData(fragment, toHexString(message.data)) - - // console.log(`\nCalling ${target.name}.${fragment.name} with args: ${functionArgs}`) - // console.log(`as raw data this is: ${toHexString(message.data)}`) - // } else { - // console.log( - // `Calling unknown contract (${toHexString(message.to)}) with data: ${toHexString( - // message.data, - // )}`, - // ) - // } - if (target && target.name === 'OVM_StateManager') { result = { gasUsed: new BN(0), From 238b6be52c95d65f3c3c9592623a2c1c5ca69498 Mon Sep 17 00:00:00 2001 From: Ben Jones Date: Thu, 5 Nov 2020 16:22:29 -0500 Subject: [PATCH 21/31] remove unused code --- packages/vm/lib/evm/evm.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index 2aa86cb9a56..1a0c5475863 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -183,10 +183,6 @@ export default class EVM { this._targetMessageResult = result } - // if (message.depth === 1 && (await this._state.getContractCode(message.to)).toString('hex') == this._vm.contracts.OVM_ECDSAContractAccount.code.toString('hex')) { - // console.log(`found and set EOA acct message`) - // this._entryPointResult = result - // } let wasDeployException = false if (message.depth === 0) { if (this._targetMessageResult) { From 0c1b35aab16aa8c12545052d49f06ce37488cac5 Mon Sep 17 00:00:00 2001 From: Ben Jones Date: Thu, 5 Nov 2020 17:43:19 -0500 Subject: [PATCH 22/31] more cleanup --- packages/vm/lib/evm/evm.ts | 2 +- packages/vm/lib/evm/interpreter.ts | 23 ----------------------- 2 files changed, 1 insertion(+), 24 deletions(-) diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index 1a0c5475863..b33d5549ed9 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -219,7 +219,7 @@ export default class EVM { }, } } else { - // todo: break out error cases and surface here + // todo: detect OVM-specific error cases and surface here result.execResult.exceptionError = new VmError(ERROR.OVM_ERROR) } } diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index 8bd69e2a825..f84071faae3 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -343,29 +343,6 @@ export default class Interpreter { )}`, ) } - - - - - // if (target.equals(this._vm.contracts.OVM_ExecutionManager.address)) { - // const sighash = toHexString(calldata.slice(0, 4)) - // const fragment = this._vm.contracts.OVM_ExecutionManager.iface.getFunction(sighash) - // const functionName = fragment.name - // const functionArgs = this._vm.contracts.OVM_ExecutionManager.iface.decodeFunctionData( - // fragment, - // toHexString(calldata), - // ) as any[] - - // loggers.callLogger.log( - // `CALL to OVM_ExecutionManager.${functionName}\nDecoded calldata: ${functionArgs}\nEncoded calldata: ${toHexString( - // calldata.slice(4), - // )}`, - // ) - // } else { - // loggers.callLogger.log( - // `CALL to ${toHexAddress(target)} with data:\n${toHexString(calldata)}`, - // ) - // } } else { loggers.stepLogger.log( `opcode: ${op.padEnd(10, ' ')} pc: ${step.pc.toString().padEnd(10, ' ')} gasLeft: ${step.gasLeft.toString()}\nstack: [${stack From 1088789ec70cd5c4c36af0da6537c49660bbbd14 Mon Sep 17 00:00:00 2001 From: Ben Jones Date: Thu, 5 Nov 2020 17:49:39 -0500 Subject: [PATCH 23/31] whitespace removal --- packages/vm/lib/runTx.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vm/lib/runTx.ts b/packages/vm/lib/runTx.ts index 70095cd0e56..3ed103cd26b 100644 --- a/packages/vm/lib/runTx.ts +++ b/packages/vm/lib/runTx.ts @@ -105,7 +105,7 @@ async function _runTx(this: VM, opts: RunTxOpts): Promise { // Validate gas limit against base fee const basefee = tx.getBaseFee() const gasLimit = new BN(tx.gasLimit) - if (gasLimit.lt(basefee)) { + if (gasLimit.lt(basefee)) { throw new Error('base fee exceeds gas limit') } gasLimit.isub(basefee) From 9b24d4169c22317f3bd2bc20a2e0158c9f891da4 Mon Sep 17 00:00:00 2001 From: Ben Jones Date: Mon, 9 Nov 2020 21:22:57 -0500 Subject: [PATCH 24/31] remove unused commented line --- lib/ovm/utils/buffer-utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/ovm/utils/buffer-utils.ts b/lib/ovm/utils/buffer-utils.ts index c193a568e2f..6d47beacfe9 100644 --- a/lib/ovm/utils/buffer-utils.ts +++ b/lib/ovm/utils/buffer-utils.ts @@ -2,7 +2,6 @@ export const toHexAddress = (buf: any): string => { // pad shorter values out if (buf.length < 20) { buf = Buffer.concat([Buffer.alloc(31), buf]) - // throw new Error('Buffer must be at least 20 bytes to be an address.') } return ( From 7cf29dd6020aa36b50e43ec7d94fba5774b115c5 Mon Sep 17 00:00:00 2001 From: Ben Jones Date: Mon, 14 Dec 2020 10:52:09 -0800 Subject: [PATCH 25/31] fix decoding and update isAuthenticated interface --- lib/ovm/ovm-state-manager.ts | 11 ++++++----- packages/vm/lib/index.ts | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/ovm/ovm-state-manager.ts b/lib/ovm/ovm-state-manager.ts index a33559cc180..ef3cecf09f3 100644 --- a/lib/ovm/ovm-state-manager.ts +++ b/lib/ovm/ovm-state-manager.ts @@ -1,6 +1,6 @@ /* External Imports */ import BN = require('bn.js') -import { BigNumber } from 'ethers' +import { BigNumber, ethers } from 'ethers' /* Internal Imports */ import VM from '../index' @@ -36,9 +36,14 @@ export class OvmStateManager { testAndSetAccountChanged: this.testAndSetAccountChanged.bind(this), testAndSetContractStorageLoaded: this.testAndSetContractStorageLoaded.bind(this), testAndSetContractStorageChanged: this.testAndSetContractStorageChanged.bind(this), + isAuthenticated: this.isAuthenticated.bind(this) } } + async isAuthenticated(message: Message, context: any): Promise { + return true + } + async handleCall(message: Message, context: any): Promise { const methodId = '0x' + message.data.slice(0, 4).toString('hex') const fragment = this._iface.getFunction(methodId) @@ -50,10 +55,6 @@ export class OvmStateManager { ret = ret === null || ret === undefined ? ret : [ret] } - if (fragment.name == 'owner') { - ret = ['0x' + context.origin.toString('hex')] - } - try { const encodedRet = this._iface.encodeFunctionResult(fragment, ret) return fromHexString(encodedRet) diff --git a/packages/vm/lib/index.ts b/packages/vm/lib/index.ts index b34fdc4fb9d..581808e0bb7 100644 --- a/packages/vm/lib/index.ts +++ b/packages/vm/lib/index.ts @@ -259,8 +259,8 @@ export default class VM extends AsyncEventEmitter { for (const [key, val] of Object.entries(account.storage)) { await this.pStateManager.putContractStorage( fromHexString(account.address), - Buffer.from(key, 'hex'), - Buffer.from(val, 'hex'), + fromHexString(key), + fromHexString(val), ) } } From d51fba823a6563e69099e44ee9e8feea89babd1d Mon Sep 17 00:00:00 2001 From: Kevin Ho Date: Mon, 9 Nov 2020 21:30:51 -0500 Subject: [PATCH 26/31] publish new version, lint --- package.json | 2 +- packages/vm/lib/evm/evm.ts | 22 ++++++++-------- packages/vm/lib/evm/interpreter.ts | 40 ++++++++++++++++++------------ 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/package.json b/package.json index 2d5c9df9792..bdfda9af181 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eth-optimism/ethereumjs-vm", - "version": "4.2.0-alpha.0", + "version": "4.2.0-alpha.1", "description": "An Ethereum VM implementation", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/vm/lib/evm/evm.ts b/packages/vm/lib/evm/evm.ts index b33d5549ed9..affeaf222e3 100644 --- a/packages/vm/lib/evm/evm.ts +++ b/packages/vm/lib/evm/evm.ts @@ -194,19 +194,19 @@ export default class EVM { // OVM reverts have some flag-related metadata before the revert data--strip this out for providers etc. let returnData: Buffer = this._targetMessageResult.execResult.returnValue - if ( - !!this._targetMessageResult.execResult.exceptionError - && returnData.byteLength >= 160 - ) { + if (!!this._targetMessageResult.execResult.exceptionError && returnData.byteLength >= 160) { returnData = returnData.slice(160) } result.execResult.exceptionError - const EOAReturnedFalse = this._accountMessageResult?.execResult.returnValue.slice(0,32).toString('hex') == '00'.repeat(32) - wasDeployException = EOAReturnedFalse && !this._targetMessageResult.execResult.exceptionError + const EOAReturnedFalse = + this._accountMessageResult?.execResult.returnValue.slice(0, 32).toString('hex') == + '00'.repeat(32) + wasDeployException = + EOAReturnedFalse && !this._targetMessageResult.execResult.exceptionError const exceptionError = wasDeployException - ? new VmError(ERROR.REVERT) + ? new VmError(ERROR.REVERT) : this._targetMessageResult.execResult.exceptionError result = { @@ -215,7 +215,7 @@ export default class EVM { execResult: { ...result.execResult, returnValue: returnData, - exceptionError + exceptionError, }, } } else { @@ -225,9 +225,9 @@ export default class EVM { } if ( - message.depth == 1 - && message.to.toString() != this._vm.contracts.OVM_StateManager.address.toString() - ) { + message.depth == 1 && + message.to.toString() != this._vm.contracts.OVM_StateManager.address.toString() + ) { this._accountMessageResult = result } diff --git a/packages/vm/lib/evm/interpreter.ts b/packages/vm/lib/evm/interpreter.ts index f84071faae3..60b571bda27 100644 --- a/packages/vm/lib/evm/interpreter.ts +++ b/packages/vm/lib/evm/interpreter.ts @@ -246,7 +246,7 @@ export default class Interpreter { async _logStep(step: InterpreterStep): Promise { if (env.DEBUG_OVM != 'true') { - return + return } if (this._firstStep && step.depth == 0) { @@ -262,13 +262,15 @@ export default class Interpreter { const addressStart = step.address.slice(0, 3).toString('hex') const addressEnd = step.address.slice(step.address.length - 3).toString('hex') - const callLogger = new Logger(logger.namespace + ':0x' + addressStart + '..' + addressEnd + ':d' + step.depth + ':calls') + const callLogger = new Logger( + logger.namespace + ':0x' + addressStart + '..' + addressEnd + ':d' + step.depth + ':calls', + ) const stepLogger = new Logger(callLogger.namespace + ':steps') const memLogger = new Logger(callLogger.namespace + ':memory') const memSizeLogger = new Logger(callLogger.namespace + ':memorysize') const gasLogger = new Logger(callLogger.namespace + ':steps') - if(isEntryPoint) { + if (isEntryPoint) { callLogger.open(`${description} ${contractName} at depth ${step.depth}`) } else { stepLogger.open(`${description} ${contractName} at depth ${step.depth}`) @@ -279,7 +281,7 @@ export default class Interpreter { stepLogger, memLogger, gasLogger, - memSizeLogger + memSizeLogger, } } @@ -288,12 +290,14 @@ export default class Interpreter { const memory = step.memory const op = step.opcode.name - if (['RETURN','REVERT','STOP','INVALID'].includes(op)) { + if (['RETURN', 'REVERT', 'STOP', 'INVALID'].includes(op)) { if (step.depth === 0) { - loggers.gasLogger.log(`OVM tx completed having used ${this._initialGas.sub(step.gasLeft).toString()} gas.`) + loggers.gasLogger.log( + `OVM tx completed having used ${this._initialGas.sub(step.gasLeft).toString()} gas.`, + ) } - if (['RETURN','REVERT'].includes(op)) { + if (['RETURN', 'REVERT'].includes(op)) { const offset = stack[0].toNumber() const length = stack[1].toNumber() const data = Buffer.from(memory.slice(offset, offset + length)) @@ -302,8 +306,7 @@ export default class Interpreter { loggers.callLogger.log(op) } - - if(isEntryPoint) { + if (isEntryPoint) { loggers.callLogger.close() } else { loggers.stepLogger.close() @@ -326,26 +329,31 @@ export default class Interpreter { if (targetContract) { let methodId = '0x' + calldata.slice(0, 4).toString('hex') let fragment = targetContract.iface.getFunction(methodId) - + let logString try { - const decodedArgs = targetContract.iface.decodeFunctionData(fragment, toHexString(calldata)) + const decodedArgs = targetContract.iface.decodeFunctionData( + fragment, + toHexString(calldata), + ) logString = `CALL to ${targetContract.name}.${fragment.name} with args: ${decodedArgs}` } catch { - logString = `CALL to ${targetContract.name}.${fragment.name} with raw data (failed to decode): 0x${calldata.toString('hex')}` + logString = `CALL to ${targetContract.name}.${ + fragment.name + } with raw data (failed to decode): 0x${calldata.toString('hex')}` } loggers.callLogger.log(logString) } else { loggers.callLogger.log( - `CALL to unknown contract (${toHexString(target)}) with data: ${toHexString( - calldata - )}`, + `CALL to unknown contract (${toHexString(target)}) with data: ${toHexString(calldata)}`, ) } } else { loggers.stepLogger.log( - `opcode: ${op.padEnd(10, ' ')} pc: ${step.pc.toString().padEnd(10, ' ')} gasLeft: ${step.gasLeft.toString()}\nstack: [${stack + `opcode: ${op.padEnd(10, ' ')} pc: ${step.pc + .toString() + .padEnd(10, ' ')} gasLeft: ${step.gasLeft.toString()}\nstack: [${stack .map((el, idx) => { return ` ${idx}: ${toHexString(el)}` }) From b919f87cb2c5ca73fc5be498d2433e50e7b37ebe Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Mon, 14 Dec 2020 11:39:45 -0800 Subject: [PATCH 27/31] Bumped version and linted --- lib/ovm/ovm-state-manager.ts | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ovm/ovm-state-manager.ts b/lib/ovm/ovm-state-manager.ts index ef3cecf09f3..ba7f83fd073 100644 --- a/lib/ovm/ovm-state-manager.ts +++ b/lib/ovm/ovm-state-manager.ts @@ -36,7 +36,7 @@ export class OvmStateManager { testAndSetAccountChanged: this.testAndSetAccountChanged.bind(this), testAndSetContractStorageLoaded: this.testAndSetContractStorageLoaded.bind(this), testAndSetContractStorageChanged: this.testAndSetContractStorageChanged.bind(this), - isAuthenticated: this.isAuthenticated.bind(this) + isAuthenticated: this.isAuthenticated.bind(this), } } diff --git a/package.json b/package.json index bdfda9af181..d4800746056 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eth-optimism/ethereumjs-vm", - "version": "4.2.0-alpha.1", + "version": "4.2.0-alpha.2", "description": "An Ethereum VM implementation", "main": "dist/index.js", "types": "dist/index.d.ts", From 7573f22e3c38deb1cfb687f2c0399d482441cc34 Mon Sep 17 00:00:00 2001 From: Kevin Ho Date: Fri, 19 Feb 2021 01:34:59 -0500 Subject: [PATCH 28/31] Update README.md --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 27278d173b0..d6b10784b79 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,15 @@ Implements Optimism's OVM in Javascript. Forked with <3 from `ethereumjs-vm`! ## Logging This fork provides some custom logging tools for introspecting the OVM via the `debug` package. Particularly, the environment variable `DEBUG='ethjs-ovm:interpreter` will allow you to log various degrees of internal EVM execution such as calls, stack, and memory. +You must also add `DEBUG_OVM=true` to enable debugging. +The logging namespace includes the start and ending bytes of the address and the call depth (e.g. `js-ovm:intrp:0xdeadde..ad0005:d5`) Available namespaces are: -- All OVM debug logging (warning, lots of logs): `DEBUG='ethjs-ovm:interpreter:*'` -- Call logging: `DEBUG='ethjs-ovm:interpreter:calls` -- Step logging: `DEBUG='ethjs-ovm:interpreter:calls:steps` -- Memory logging: `DEBUG='ethjs-ovm:interpreter:calls:memory` +- All OVM debug logging (warning, lots of logs): `DEBUG='*'` +- Call logging: `DEBUG='*:calls` (recommended to run first) +- Step logging: `DEBUG='*:calls:steps` (recommended to run filtered by address, e.g. `DEBUG='*:calls,js-ovm:intrp:0xdeadde..ad0005:d2:calls:steps'`) +- Memory logging: `DEBUG=*:calls:memory` (recommended to run filtered by address, see above) Or mix and match any of the above to get your desired logging level. From bc4dc4c188daa55b1ea664057d9e1ba43f009ab4 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Sat, 6 Mar 2021 18:25:56 -0800 Subject: [PATCH 29/31] Fixed an issue because gas limit was too low --- packages/vm/lib/evm/message.ts | 2 +- packages/vm/lib/index.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/vm/lib/evm/message.ts b/packages/vm/lib/evm/message.ts index dbf6a62a291..6c20a0134fe 100644 --- a/packages/vm/lib/evm/message.ts +++ b/packages/vm/lib/evm/message.ts @@ -59,7 +59,7 @@ export default class Message { throw new Error('Cannot create a message because the ExecutionManager does not exist.') } - const notTooBigGasLimit = BN.min(this.gasLimit, new BN(vm.emGasLimit)) + const notTooBigGasLimit = new BN(vm.emGasLimit) const calldata = vm.contracts.OVM_ExecutionManager.iface.encodeFunctionData('run', [ { diff --git a/packages/vm/lib/index.ts b/packages/vm/lib/index.ts index 581808e0bb7..ef6c340c55f 100644 --- a/packages/vm/lib/index.ts +++ b/packages/vm/lib/index.ts @@ -22,6 +22,7 @@ const promisify = require('util.promisify') // Custom imports import { Interface } from '@ethersproject/abi' import { fromHexString } from './ovm/utils/buffer-utils' +import { BigNumber } from 'ethers' interface OVMContract { name: string @@ -264,6 +265,20 @@ export default class VM extends AsyncEventEmitter { ) } } + + // Set maxTransactionGasLimit + await this.pStateManager.putContractStorage( + fromHexString('0xdeaddeaddeaddeaddeaddeaddeaddeaddead0005'), + fromHexString('0x0000000000000000000000000000000000000000000000000000000000000004'), + fromHexString(BigNumber.from(this.emGasLimit).toHexString()), + ) + + // Set maxGasPerQueuePerEpoch + await this.pStateManager.putContractStorage( + fromHexString('0xdeaddeaddeaddeaddeaddeaddeaddeaddead0005'), + fromHexString('0x0000000000000000000000000000000000000000000000000000000000000005'), + fromHexString(BigNumber.from(this.emGasLimit).toHexString()), + ) } /** From 17462fd4128dac09bb1661842496298cfe7f92c6 Mon Sep 17 00:00:00 2001 From: Kelvin Fichter Date: Sat, 6 Mar 2021 18:27:03 -0800 Subject: [PATCH 30/31] Bump version too --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d4800746056..01b1b5ec212 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@eth-optimism/ethereumjs-vm", - "version": "4.2.0-alpha.2", + "version": "4.2.0-alpha.3", "description": "An Ethereum VM implementation", "main": "dist/index.js", "types": "dist/index.d.ts", From 031257624de20a133dee6ba4976df065bb20315f Mon Sep 17 00:00:00 2001 From: cgewecke Date: Tue, 27 Apr 2021 08:12:01 -0700 Subject: [PATCH 31/31] Simplify diff --- README.md | 129 +++++++++++++++++++++++++++++++++++---- package.json | 35 ++++++++++- packages/vm/CHANGELOG.md | 1 - 3 files changed, 150 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index d6b10784b79..d2cde1e89ad 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,126 @@ -# ethereumjs-ovm +

+ +

-Implements Optimism's OVM in Javascript. Forked with <3 from `ethereumjs-vm`! +# EthereumJS Monorepo -## Logging +[![Code Coverage][coverage-badge]][coverage-link] +[![Gitter][gitter-badge]][gitter-link] +[![StackExchange][stackexchange-badge]][stackexchange-link] -This fork provides some custom logging tools for introspecting the OVM via the `debug` package. Particularly, the environment variable `DEBUG='ethjs-ovm:interpreter` will allow you to log various degrees of internal EVM execution such as calls, stack, and memory. -You must also add `DEBUG_OVM=true` to enable debugging. -The logging namespace includes the start and ending bytes of the address and the call depth (e.g. `js-ovm:intrp:0xdeadde..ad0005:d5`) +[![JS Standard Style][js-standard-style-badge]][js-standard-style-link] -Available namespaces are: +This was originally the EthereumJS VM repository. On Q1 2020 we brought some of its building blocks together to simplify development. Below you can find the packages included in this repository. -- All OVM debug logging (warning, lots of logs): `DEBUG='*'` -- Call logging: `DEBUG='*:calls` (recommended to run first) -- Step logging: `DEBUG='*:calls:steps` (recommended to run filtered by address, e.g. `DEBUG='*:calls,js-ovm:intrp:0xdeadde..ad0005:d2:calls:steps'`) -- Memory logging: `DEBUG=*:calls:memory` (recommended to run filtered by address, see above) +🚧 Please note that the `master` branch is updated on a daily basis, and to inspect code related to a specific package version, refer to the [tags](https://github.com/ethereumjs/ethereumjs-vm/tags). -Or mix and match any of the above to get your desired logging level. +| package | npm | issues | tests | coverage | +| ------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------- | +| [@ethereumjs/account][account-package] | [![NPM Package][account-npm-badge]][account-npm-link] | [![Account Issues][account-issues-badge]][account-issues-link] | [![Actions Status][account-actions-badge]][account-actions-link] | [![Code Coverage][account-coverage-badge]][account-coverage-link] | +| [@ethereumjs/block][block-package] | [![NPM Package][block-npm-badge]][block-npm-link] | [![Block Issues][block-issues-badge]][block-issues-link] | [![Actions Status][block-actions-badge]][block-actions-link] | [![Code Coverage][block-coverage-badge]][block-coverage-link] | +| [@ethereumjs/blockchain][blockchain-package] | [![NPM Package][blockchain-npm-badge]][blockchain-npm-link] | [![Blockchain Issues][blockchain-issues-badge]][blockchain-issues-link] | [![Actions Status][blockchain-actions-badge]][blockchain-actions-link] | [![Code Coverage][blockchain-coverage-badge]][blockchain-coverage-link] | +| [@ethereumjs/common][common-package] | [![NPM Package][common-npm-badge]][common-npm-link] | [![Common Issues][common-issues-badge]][common-issues-link] | [![Actions Status][common-actions-badge]][common-actions-link] | [![Code Coverage][common-coverage-badge]][common-coverage-link] | +| [@ethereumjs/ethash][ethash-package] | [![NPM Package][ethash-npm-badge]][ethash-npm-link] | [![Ethash Issues][ethash-issues-badge]][ethash-issues-link] | [![Actions Status][ethash-actions-badge]][ethash-actions-link] | [![Code Coverage][ethash-coverage-badge]][ethash-coverage-link] | +| [@ethereumjs/tx][tx-package] | [![NPM Package][tx-npm-badge]][tx-npm-link] | [![Tx Issues][tx-issues-badge]][tx-issues-link] | [![Actions Status][tx-actions-badge]][tx-actions-link] | [![Code Coverage][tx-coverage-badge]][tx-coverage-link] | +| [@ethereumjs/vm][vm-package] | [![NPM Package][vm-npm-badge]][vm-npm-link] | [![VM Issues][vm-issues-badge]][vm-issues-link] | [![Actions Status][vm-actions-badge]][vm-actions-link] | [![Code Coverage][vm-coverage-badge]][vm-coverage-link] | + +## Coverage report + +Detailed version can be seen on [Codecov.io][coverage-link] + +[![Code Coverage](https://codecov.io/gh/ethereumjs/ethereumjs-vm/branch/master/graphs/icicle.svg)][coverage-link] + +## Package dependency relationship + +

+ diagram +

+ + + +## Development quick start + +This monorepo uses [Lerna](https://lerna.js.org/). It links the local packages together, making development a lot easier. + +TLDR: Setup +```sh +npm install +npm build +``` + +TLDR: To update dependencies and (re-)link packages +```sh +npm run bootstrap +npm build +``` + +Above is the quickest way to set you up. Going down the road, there are two sets of commands: *project* and *package-specific* commands. You can find them at `./package.json` and `./packages/*/package.json`, respectively. Here's a breakdown: + +### Project scripts — run from repository root + +#### `npm install` +Adds dependencies listed in the root package. Also, it executes the `bootstrap` script described below, installing all sub-packages dependencies. + +#### `npm run bootstrap` + +Installs dependencies for all sub-packages, and links them to create an integrated development environment. + +#### `npm run build` + +Produces `dist` files for all sub-packages. This command can be scoped + +#### `npm run build:tree -- --scope @ethereumjs/blockchain` + +Builds all local packages that the provided package (eg: @ethereumjs/blockchain) depends on, and itself. This unusual syntax just means: pass whatever arguments are after `--` to the underlying script. + +If no scope is provided, `npm run build:tree`, will build all sub-packages. + +### Package scripts — run from `./packages/` + + **⚠️ Important: if you run `npm install` from the package directory, it will remove all links to the local packages, pulling all dependencies from npm. Run `npm install` from the root only.** + +There's a set of rather standardized commands you will find in each package of this repository. + +#### `npm run build` + +Uses TypeScript compiler to build files from `src` or `lib`. Files can be found at `packages//dist`. + +#### `npm run coverage` + +Runs whatever is on `npm run test` script, capturing coverage information. By the end, it displays a coverage table. Additional reports can be found at `packages//coverage`. + +#### `npm run docs:build` + +Generates package documentation and outputs it to `./packages//docs`. + +#### `npm run lint` + +Checks code style, according to the rules defined in [ethereumjs-config](https://github.com/ethereumjs/ethereumjs-config). + +#### `npm run lint:fix` + +Fixes code style, according to the rules + +#### `npm run test` + +Runs all package tests. Note that the VM have several test scopes. Refer to their package.json for more info. + +### Going further + +As this project is powered by Lerna, you can install it globally to enjoy lots more options. Refer to [Lerna docs](https://github.com/lerna/lerna/tree/master/commands/run) for additional commands. + +- `npm install -g lerna` +- `lerna run` +- `lerna exec` +- `lerna clean` + +# EthereumJS + +See our organizational [documentation](https://ethereumjs.readthedocs.io) for an introduction to `EthereumJS` as well as information on current standards and best practices. + +If you want to join for work or do improvements on the libraries have a look at our [contribution guidelines](https://ethereumjs.readthedocs.io/en/latest/contributing.html). # LICENSE diff --git a/package.json b/package.json index 01b1b5ec212..c8559ad5852 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,42 @@ { - "name": "@eth-optimism/ethereumjs-vm", - "version": "4.2.0-alpha.3", + "name": "ethereumjs-vm", + "version": "4.2.0", "description": "An Ethereum VM implementation", "main": "dist/index.js", "types": "dist/index.d.ts", "files": [ "dist/**/*" ], + "scripts": { + "build": "ethereumjs-config-build", + "prepublishOnly": "npm run lint && npm run build && npm run test:buildIntegrity", + "coverage": "nyc npm run coverage:test && nyc report --reporter=lcov", + "coverage:test": "npm run build && tape './tests/api/**/*.js' ./tests/tester.js --state --dist", + "docs:build": "typedoc lib", + "test:vm": "node ./tests/tester --vm", + "test:state": "ts-node ./tests/tester --state", + "test:state:allForks": "npm run test:state -- --fork=Byzantium && npm run test:state -- --fork=Constantinople && npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=Istanbul && npm run test:state -- --fork=MuirGlacier", + "test:state:selectedForks": "npm run test:state -- --fork=Petersburg && npm run test:state -- --fork=Istanbul && npm run test:state -- --fork=MuirGlacier", + "test:state:slow": "npm run test:state -- --runSkipped=slow", + "test:buildIntegrity": "npm run test:state -- --test='stackOverflow'", + "test:blockchain": "node -r ts-node/register --stack-size=1500 ./tests/tester --blockchain", + "test:API": "npm run build && ts-node ./node_modules/tape/bin/tape './tests/api/**/*.js'", + "test:API:browser": "npm run build && karma start karma.conf.js", + "test": "echo \"[INFO] Generic test cmd not used. See package.json for more specific test run cmds.\"", + "tslint": "ethereumjs-config-tslint", + "tslint:fix": "ethereumjs-config-tslint-fix", + "lint": "ethereumjs-config-lint", + "lint:fix": "ethereumjs-config-lint-fix", + "format": "ethereumjs-config-format", + "format:fix": "ethereumjs-config-format-fix", + "formatTest": "node ./scripts/formatTest", + "tsc": "ethereumjs-config-tsc" + }, + "husky": { + "hooks": { + "pre-push": "npm run lint" + } + }, "scripts": { "postinstall": "npm run bootstrap", "bootstrap": "lerna bootstrap --ignore-scripts --include-dependencies --no-ci --hoist && npm run build", @@ -30,4 +60,5 @@ "lint:fix": "lerna run lint:fix --stream --parallel", "test": "lerna exec npm run test --parallel", "coverage": "lerna run coverage --stream" + } } diff --git a/packages/vm/CHANGELOG.md b/packages/vm/CHANGELOG.md index 8ad95def3ca..3569d19ff81 100644 --- a/packages/vm/CHANGELOG.md +++ b/packages/vm/CHANGELOG.md @@ -21,7 +21,6 @@ This is a maintenance release preceding the v5. - Properly copying BigNumbers on stack. PR [#733](https://github.com/ethereumjs/ethereumjs-vm/pull/733) - - Fixes installation on Node 12, by bumping `level` dependency from `^4.0.0` to `^6.0.0` PR [#662](https://github.com/ethereumjs/ethereumjs-vm/pull/662)