From 057e86d0ebc81d67ccd45567ff6bf41c56e9733d Mon Sep 17 00:00:00 2001 From: Diego Essaya Date: Thu, 7 Sep 2023 17:41:59 -0300 Subject: [PATCH] fix(evm): properly revert emitted logs after revert Also fixes calculation of logIndex value in jsonrpc. closes #2847 --- packages/evm/evmtest/ISCTest.abi | 2 +- packages/evm/evmtest/ISCTest.bin | 2 +- packages/evm/evmtest/ISCTest.sol | 7 ++ packages/evm/jsonrpc/types.go | 31 +++---- packages/vm/core/evm/emulator/blockchaindb.go | 53 ++++++++---- packages/vm/core/evm/emulator/emulator.go | 14 +--- .../vm/core/evm/emulator/emulator_test.go | 83 ++++++++++++++++--- packages/vm/core/evm/emulator/statedb.go | 23 +++-- packages/vm/core/evm/evmtest/evm_test.go | 11 +++ 9 files changed, 159 insertions(+), 67 deletions(-) diff --git a/packages/evm/evmtest/ISCTest.abi b/packages/evm/evmtest/ISCTest.abi index 2b02502de2..c77d13176b 100644 --- a/packages/evm/evmtest/ISCTest.abi +++ b/packages/evm/evmtest/ISCTest.abi @@ -1 +1 @@ -[{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"CustomError","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"entropy","type":"bytes32"}],"name":"EntropyEvent","type":"event"},{"anonymous":false,"inputs":[],"name":"LoopEvent","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct ISCRequestID","name":"reqID","type":"tuple"}],"name":"RequestIDEvent","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct ISCAgentID","name":"sender","type":"tuple"}],"name":"SenderAccountEvent","type":"event"},{"inputs":[],"name":"TokensForGas","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callInccounter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emitEntropy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emitRequestID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emitSenderAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getChainID","outputs":[{"internalType":"ISCChainID","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"loopWithGasLeft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"makeISCPanic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"foundrySN","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint64","name":"storageDeposit","type":"uint64"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ISCAgentID","name":"targetAgentID","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"nativeTokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAssets","name":"allowance","type":"tuple"}],"name":"moveToAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revertWithCustomError","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"receiver","type":"tuple"},{"internalType":"uint64","name":"baseTokens","type":"uint64"}],"name":"sendBaseTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"receiver","type":"tuple"},{"internalType":"NFTID","name":"id","type":"bytes32"},{"internalType":"uint64","name":"storageDeposit","type":"uint64"}],"name":"sendNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"testCallViewCaller","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"testRevertReason","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"testSelfDestruct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"testStackOverflow","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"testStaticCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"triggerEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"triggerEventFail","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"CustomError","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"entropy","type":"bytes32"}],"name":"EntropyEvent","type":"event"},{"anonymous":false,"inputs":[],"name":"LoopEvent","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct ISCRequestID","name":"reqID","type":"tuple"}],"name":"RequestIDEvent","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct ISCAgentID","name":"sender","type":"tuple"}],"name":"SenderAccountEvent","type":"event"},{"anonymous":false,"inputs":[],"name":"SomeEvent","type":"event"},{"inputs":[],"name":"TokensForGas","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callInccounter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emitEntropy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emitEventAndRevert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emitRequestID","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emitSenderAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getChainID","outputs":[{"internalType":"ISCChainID","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"loopWithGasLeft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"makeISCPanic","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"foundrySN","type":"uint32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint64","name":"storageDeposit","type":"uint64"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ISCAgentID","name":"targetAgentID","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"nativeTokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAssets","name":"allowance","type":"tuple"}],"name":"moveToAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revertWithCustomError","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"receiver","type":"tuple"},{"internalType":"uint64","name":"baseTokens","type":"uint64"}],"name":"sendBaseTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"receiver","type":"tuple"},{"internalType":"NFTID","name":"id","type":"bytes32"},{"internalType":"uint64","name":"storageDeposit","type":"uint64"}],"name":"sendNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sendTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"testCallViewCaller","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"testRevertReason","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address payable","name":"beneficiary","type":"address"}],"name":"testSelfDestruct","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"testStackOverflow","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[],"name":"testStaticCall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"triggerEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"triggerEventFail","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/packages/evm/evmtest/ISCTest.bin b/packages/evm/evmtest/ISCTest.bin index 85c5c066a3..a85d8a3119 100644 --- a/packages/evm/evmtest/ISCTest.bin +++ b/packages/evm/evmtest/ISCTest.bin @@ -1 +1 @@ -608060405234801561000f575f80fd5b506142238061001d5f395ff3fe608060405260043610610129575f3560e01c8063a038a3e6116100aa578063c36ba8561161006e578063c36ba856146102ff578063c5e6994514610315578063d411defb1461033d578063dc91b3d014610353578063e29a58a31461037d578063e6c75c6b1461039357610129565b8063a038a3e614610259578063a4a05e2114610281578063b3ee694214610297578063bcaeb8a8146102ad578063bcfb1959146102d757610129565b806346fc4bb1116100f157806346fc4bb1146101bf578063564b81ef146101d557806357c8750e146101ff5780636a68a760146102275780639e1a00aa1461023d57610129565b806301fc25761461012d57806336c34640146101555780633772d53f1461016b57806339bfb2fa1461018157806346d11676146101a9575b5f80fd5b348015610138575f80fd5b50610153600480360381019061014e91906120a4565b6103bb565b005b348015610160575f80fd5b506101696105fc565b005b348015610176575f80fd5b5061017f6106be565b005b34801561018c575f80fd5b506101a760048036038101906101a2919061216a565b61077d565b005b3480156101b4575f80fd5b506101bd610828565b005b3480156101ca575f80fd5b506101d36108ea565b005b3480156101e0575f80fd5b506101e9610928565b6040516101f691906121e3565b60405180910390f35b34801561020a575f80fd5b5061022560048036038101906102209190612574565b6109af565b005b348015610232575f80fd5b5061023b610c31565b005b61025760048036038101906102529190612644565b610c6c565b005b348015610264575f80fd5b5061027f600480360381019061027a9190612720565b610cb4565b005b34801561028c575f80fd5b50610295610d2e565b005b3480156102a2575f80fd5b506102ab610fee565b005b3480156102b8575f80fd5b506102c161128f565b6040516102ce91906127e1565b60405180910390f35b3480156102e2575f80fd5b506102fd60048036038101906102f89190612801565b61151a565b005b34801561030a575f80fd5b50610313611533565b005b348015610320575f80fd5b5061033b6004803603810190610336919061282c565b6116f0565b005b348015610348575f80fd5b50610351611923565b005b34801561035e575f80fd5b50610367611d01565b60405161037491906128a7565b60405180910390f35b348015610388575f80fd5b50610391611d07565b005b34801561039e575f80fd5b506103b960048036038101906103b49190612720565b611d44565b005b6103c3611dc1565b5f8267ffffffffffffffff160361046a5773107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a714b58d336040518263ffffffff1660e01b815260040161042191906128e0565b5f60405180830381865afa15801561043b573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906104639190612c42565b905061048a565b81815f019067ffffffffffffffff16908167ffffffffffffffff16815250505b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663423fa15133836040518363ffffffff1660e01b81526004016104d9929190612f16565b5f604051808303815f87803b1580156104f0575f80fd5b505af1158015610502573d5f803e3d5ffd5b5050505061050e611dc1565b6101f467ffffffffffffffff16825f015167ffffffffffffffff1611610532575f80fd5b6101f4825f01516105439190612f71565b815f019067ffffffffffffffff16908167ffffffffffffffff1681525050610569611deb565b610571611e39565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b7a53f538785600186866040518663ffffffff1660e01b81526004016105c79594939291906132cd565b5f604051808303815f87803b1580156105de575f80fd5b505af11580156105f0573d5f803e3d5ffd5b50505050505050505050565b5f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ca6528ce6040518163ffffffff1660e01b81526004015f604051808303815f875af115801561065a573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610682919061338f565b90507f41aec7e1afdd771a4a8d3d2f4195266991744d24445781617c2151aa73e30186816040516106b391906133fd565b60405180910390a150565b5f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635404bbf76040518163ffffffff1660e01b81526004016020604051808303815f875af115801561071d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107419190613447565b90507f2778726dc1b9d6d2ee2628a18174907da485ba8765490e157ddf1202528ed5bc816040516107729190613481565b60405180910390a150565b610785611dc1565b81815f019067ffffffffffffffff16908167ffffffffffffffff168152505073107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638adfedc78585846040518463ffffffff1660e01b81526004016107f5939291906134b8565b5f604051808303815f87803b15801561080c575f80fd5b505af115801561081e573d5f803e3d5ffd5b5050505050505050565b5f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f31317496040518163ffffffff1660e01b81526004015f604051808303815f875af1158015610886573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906108ae9190613549565b90507faded0c26c8cc65771b245ec36a4a290a35b0cd003545068bcef2dcac18b8815c816040516108df91906135b7565b60405180910390a150565b602a6040517fa8b4db6200000000000000000000000000000000000000000000000000000000815260040161091f919061361c565b60405180910390fd5b5f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663564b81ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610986573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109aa919061365f565b905090565b5f6040518060200160405280600267ffffffffffffffff8111156109d6576109d5611ee2565b5b604051908082528060200260200182016040528015610a0f57816020015b6109fc611e5b565b8152602001906001900390816109f45790505b50815250905060405180604001604052806040518060400160405280600181526020017f61000000000000000000000000000000000000000000000000000000000000008152508152602001845f0151815250815f01515f81518110610a7857610a7761368a565b5b602002602001018190525073107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663907327e973107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610afe90613711565b602060405180830381865afa158015610b19573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3d9190613759565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610b88906137ce565b602060405180830381865afa158015610ba3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bc79190613759565b84866040518563ffffffff1660e01b8152600401610be89493929190613822565b5f604051808303815f875af1158015610c03573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610c2b9190613a2b565b50505050565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c6390613abc565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610caf573d5f803e3d5ffd5b505050565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e6c75c6b826040518263ffffffff1660e01b8152600401610d019190613b1c565b5f604051808303815f87803b158015610d18575f80fd5b505af1158015610d2a573d5f803e3d5ffd5b5f80fd5b5f6040518060200160405280600167ffffffffffffffff811115610d5557610d54611ee2565b5b604051908082528060200260200182016040528015610d8e57816020015b610d7b611e5b565b815260200190600190039081610d735790505b5081525090505f6040518060400160405280600881526020017f2a00000000000000000000000000000000000000000000000000000000000000815250905060405180604001604052806040518060400160405280600781526020017f636f756e74657200000000000000000000000000000000000000000000000000815250815260200182815250825f01515f81518110610e2d57610e2c61368a565b5b6020026020010181905250610e40611dc1565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663907327e973107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610ebb90613b86565b602060405180830381865afa158015610ed6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610efa9190613759565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610f4590613bee565b602060405180830381865afa158015610f60573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f849190613759565b86856040518563ffffffff1660e01b8152600401610fa59493929190613822565b5f604051808303815f875af1158015610fc0573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610fe89190613a2b565b50505050565b5f3060601b6040516020016110039190613c86565b60405160208183030381529060405290505f6040518060200160405280600167ffffffffffffffff81111561103b5761103a611ee2565b5b60405190808252806020026020018201604052801561107457816020015b611061611e5b565b8152602001906001900390816110595790505b50815250905060405180604001604052806040518060400160405280600181526020017f6300000000000000000000000000000000000000000000000000000000000000815250815260200183815250815f01515f815181106110da576110d961368a565b5b602002602001018190525073107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630a26061773107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b815260040161116090613d08565b602060405180830381865afa15801561117b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061119f9190613759565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b81526004016111ea90613d70565b602060405180830381865afa158015611205573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112299190613759565b846040518463ffffffff1660e01b815260040161124893929190613d8e565b5f60405180830381865afa158015611262573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061128a9190613a2b565b505050565b60605f60405180602001604052805f67ffffffffffffffff8111156112b7576112b6611ee2565b5b6040519080825280602002602001820160405280156112f057816020015b6112dd611e5b565b8152602001906001900390816112d55790505b5081525090505f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630a26061773107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b815260040161137290613711565b602060405180830381865afa15801561138d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113b19190613759565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b81526004016113fc90613e14565b602060405180830381865afa158015611417573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061143b9190613759565b856040518463ffffffff1660e01b815260040161145a93929190613d8e565b5f60405180830381865afa158015611474573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061149c9190613a2b565b90505f5b815f015151811015611513575f825f015182815181106114c3576114c261368a565b5b60200260200101515f0151510361150057815f015181815181106114ea576114e961368a565b5b6020026020010151602001519350505050611517565b808061150b90613e32565b9150506114a0565b5f80fd5b90565b8073ffffffffffffffffffffffffffffffffffffffff16ff5b61153b611e75565b611543611dc1565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663907327e973107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b81526004016115be90613ec3565b602060405180830381865afa1580156115d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115fd9190613759565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b815260040161164890613f2b565b602060405180830381865afa158015611663573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116879190613759565b85856040518563ffffffff1660e01b81526004016116a89493929190613822565b5f604051808303815f875af11580156116c3573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906116eb9190613a2b565b505050565b6116f8611dc1565b81815f019067ffffffffffffffff16908167ffffffffffffffff1681525050600167ffffffffffffffff81111561173257611731611ee2565b5b6040519080825280602002602001820160405280156117605781602001602082028036833780820191505090505b5081604001819052508281604001515f815181106117815761178061368a565b5b60200260200101818152505073107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663423fa15133836040518363ffffffff1660e01b81526004016117dc929190612f16565b5f604051808303815f87803b1580156117f3575f80fd5b505af1158015611805573d5f803e3d5ffd5b50505050611811611dc1565b600167ffffffffffffffff81111561182c5761182b611ee2565b5b60405190808252806020026020018201604052801561185a5781602001602082028036833780820191505090505b5081604001819052508381604001515f8151811061187b5761187a61368a565b5b60200260200101818152505061188f611deb565b611897611e39565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b7a53f538885600186866040518663ffffffff1660e01b81526004016118ed9594939291906132cd565b5f604051808303815f87803b158015611904575f80fd5b505af1158015611916573d5f803e3d5ffd5b5050505050505050505050565b5f606073107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1660405160240161196090613f93565b6040516020818303038152906040527fe6c75c6b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516119ea9190613feb565b5f604051808303815f865af19150503d805f8114611a23576040519150601f19603f3d011682016040523d82523d5f602084013e611a28565b606091505b50809250819350505081611a71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a689061404b565b60405180910390fd5b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f564b81ef000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611b2c9190613feb565b5f60405180830381855afa9150503d805f8114611b64576040519150601f19603f3d011682016040523d82523d5f602084013e611b69565b606091505b50809250819350505081611bb2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ba9906140d9565b60405180910390fd5b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16604051602401611bec90614141565b6040516020818303038152906040527fe6c75c6b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611c769190613feb565b5f60405180830381855afa9150503d805f8114611cae576040519150601f19603f3d011682016040523d82523d5f602084013e611cb3565b606091505b5080925081935050508115611cfd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf4906141cf565b60405180910390fd5b5050565b6101f481565b5b6127105a10611d42577ff9c7a13c2c2ddb716633ae77fd03fb7d2e3bf5ab3a45ba50ec2d3decc9ee650c60405160405180910390a1611d08565b565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e6c75c6b826040518263ffffffff1660e01b8152600401611d919190613b1c565b5f604051808303815f87803b158015611da8575f80fd5b505af1158015611dba573d5f803e3d5ffd5b5050505050565b60405180606001604052805f67ffffffffffffffff16815260200160608152602001606081525090565b6040518060a001604052805f63ffffffff1681526020015f63ffffffff168152602001611e16611e75565b8152602001611e23611dc1565b81526020015f67ffffffffffffffff1681525090565b60405180604001604052805f60070b8152602001611e55611e88565b81525090565b604051806040016040528060608152602001606081525090565b6040518060200160405280606081525090565b60405180604001604052805f60070b8152602001611ea4611eaa565b81525090565b6040518060200160405280606081525090565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611f1882611ed2565b810181811067ffffffffffffffff82111715611f3757611f36611ee2565b5b80604052505050565b5f611f49611ebd565b9050611f558282611f0f565b919050565b5f80fd5b5f80fd5b5f80fd5b5f67ffffffffffffffff821115611f8057611f7f611ee2565b5b611f8982611ed2565b9050602081019050919050565b828183375f83830152505050565b5f611fb6611fb184611f66565b611f40565b905082815260208101848484011115611fd257611fd1611f62565b5b611fdd848285611f96565b509392505050565b5f82601f830112611ff957611ff8611f5e565b5b8135612009848260208601611fa4565b91505092915050565b5f6020828403121561202757612026611ece565b5b6120316020611f40565b90505f82013567ffffffffffffffff8111156120505761204f611f5a565b5b61205c84828501611fe5565b5f8301525092915050565b5f67ffffffffffffffff82169050919050565b61208381612067565b811461208d575f80fd5b50565b5f8135905061209e8161207a565b92915050565b5f80604083850312156120ba576120b9611ec6565b5b5f83013567ffffffffffffffff8111156120d7576120d6611eca565b5b6120e385828601612012565b92505060206120f485828601612090565b9150509250929050565b5f63ffffffff82169050919050565b612116816120fe565b8114612120575f80fd5b50565b5f813590506121318161210d565b92915050565b5f819050919050565b61214981612137565b8114612153575f80fd5b50565b5f8135905061216481612140565b92915050565b5f805f6060848603121561218157612180611ec6565b5b5f61218e86828701612123565b935050602061219f86828701612156565b92505060406121b086828701612090565b9150509250925092565b5f819050919050565b5f6121cd826121ba565b9050919050565b6121dd816121c3565b82525050565b5f6020820190506121f65f8301846121d4565b92915050565b5f6020828403121561221157612210611ece565b5b61221b6020611f40565b90505f82013567ffffffffffffffff81111561223a57612239611f5a565b5b61224684828501611fe5565b5f8301525092915050565b5f67ffffffffffffffff82111561226b5761226a611ee2565b5b602082029050602081019050919050565b5f80fd5b5f6020828403121561229557612294611ece565b5b61229f6020611f40565b90505f82013567ffffffffffffffff8111156122be576122bd611f5a565b5b6122ca84828501611fe5565b5f8301525092915050565b5f604082840312156122ea576122e9611ece565b5b6122f46040611f40565b90505f82013567ffffffffffffffff81111561231357612312611f5a565b5b61231f84828501612280565b5f83015250602061233284828501612156565b60208301525092915050565b5f61235061234b84612251565b611f40565b905080838252602082019050602084028301858111156123735761237261227c565b5b835b818110156123ba57803567ffffffffffffffff81111561239857612397611f5e565b5b8086016123a589826122d5565b85526020850194505050602081019050612375565b5050509392505050565b5f82601f8301126123d8576123d7611f5e565b5b81356123e884826020860161233e565b91505092915050565b5f67ffffffffffffffff82111561240b5761240a611ee2565b5b602082029050602081019050919050565b612425816121ba565b811461242f575f80fd5b50565b5f813590506124408161241c565b92915050565b5f612458612453846123f1565b611f40565b9050808382526020820190506020840283018581111561247b5761247a61227c565b5b835b818110156124a457806124908882612432565b84526020840193505060208101905061247d565b5050509392505050565b5f82601f8301126124c2576124c1611f5e565b5b81356124d2848260208601612446565b91505092915050565b5f606082840312156124f0576124ef611ece565b5b6124fa6060611f40565b90505f61250984828501612090565b5f83015250602082013567ffffffffffffffff81111561252c5761252b611f5a565b5b612538848285016123c4565b602083015250604082013567ffffffffffffffff81111561255c5761255b611f5a565b5b612568848285016124ae565b60408301525092915050565b5f806040838503121561258a57612589611ec6565b5b5f83013567ffffffffffffffff8111156125a7576125a6611eca565b5b6125b3858286016121fc565b925050602083013567ffffffffffffffff8111156125d4576125d3611eca565b5b6125e0858286016124db565b9150509250929050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612613826125ea565b9050919050565b61262381612609565b811461262d575f80fd5b50565b5f8135905061263e8161261a565b92915050565b5f806040838503121561265a57612659611ec6565b5b5f61266785828601612630565b925050602061267885828601612156565b9150509250929050565b5f67ffffffffffffffff82111561269c5761269b611ee2565b5b6126a582611ed2565b9050602081019050919050565b5f6126c46126bf84612682565b611f40565b9050828152602081018484840111156126e0576126df611f62565b5b6126eb848285611f96565b509392505050565b5f82601f83011261270757612706611f5e565b5b81356127178482602086016126b2565b91505092915050565b5f6020828403121561273557612734611ec6565b5b5f82013567ffffffffffffffff81111561275257612751611eca565b5b61275e848285016126f3565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561279e578082015181840152602081019050612783565b5f8484015250505050565b5f6127b382612767565b6127bd8185612771565b93506127cd818560208601612781565b6127d681611ed2565b840191505092915050565b5f6020820190508181035f8301526127f981846127a9565b905092915050565b5f6020828403121561281657612815611ec6565b5b5f61282384828501612630565b91505092915050565b5f805f6060848603121561284357612842611ec6565b5b5f84013567ffffffffffffffff8111156128605761285f611eca565b5b61286c86828701612012565b935050602061287d86828701612432565b925050604061288e86828701612090565b9150509250925092565b6128a181612067565b82525050565b5f6020820190506128ba5f830184612898565b92915050565b5f6128ca826125ea565b9050919050565b6128da816128c0565b82525050565b5f6020820190506128f35f8301846128d1565b92915050565b5f815190506129078161207a565b92915050565b5f61291f61291a84611f66565b611f40565b90508281526020810184848401111561293b5761293a611f62565b5b612946848285612781565b509392505050565b5f82601f83011261296257612961611f5e565b5b815161297284826020860161290d565b91505092915050565b5f602082840312156129905761298f611ece565b5b61299a6020611f40565b90505f82015167ffffffffffffffff8111156129b9576129b8611f5a565b5b6129c58482850161294e565b5f8301525092915050565b5f815190506129de81612140565b92915050565b5f604082840312156129f9576129f8611ece565b5b612a036040611f40565b90505f82015167ffffffffffffffff811115612a2257612a21611f5a565b5b612a2e8482850161297b565b5f830152506020612a41848285016129d0565b60208301525092915050565b5f612a5f612a5a84612251565b611f40565b90508083825260208201905060208402830185811115612a8257612a8161227c565b5b835b81811015612ac957805167ffffffffffffffff811115612aa757612aa6611f5e565b5b808601612ab489826129e4565b85526020850194505050602081019050612a84565b5050509392505050565b5f82601f830112612ae757612ae6611f5e565b5b8151612af7848260208601612a4d565b91505092915050565b5f81519050612b0e8161241c565b92915050565b5f612b26612b21846123f1565b611f40565b90508083825260208201905060208402830185811115612b4957612b4861227c565b5b835b81811015612b725780612b5e8882612b00565b845260208401935050602081019050612b4b565b5050509392505050565b5f82601f830112612b9057612b8f611f5e565b5b8151612ba0848260208601612b14565b91505092915050565b5f60608284031215612bbe57612bbd611ece565b5b612bc86060611f40565b90505f612bd7848285016128f9565b5f83015250602082015167ffffffffffffffff811115612bfa57612bf9611f5a565b5b612c0684828501612ad3565b602083015250604082015167ffffffffffffffff811115612c2a57612c29611f5a565b5b612c3684828501612b7c565b60408301525092915050565b5f60208284031215612c5757612c56611ec6565b5b5f82015167ffffffffffffffff811115612c7457612c73611eca565b5b612c8084828501612ba9565b91505092915050565b612c9281612067565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f82825260208201905092915050565b5f612cdb82612767565b612ce58185612cc1565b9350612cf5818560208601612781565b612cfe81611ed2565b840191505092915050565b5f602083015f8301518482035f860152612d238282612cd1565b9150508091505092915050565b612d3981612137565b82525050565b5f604083015f8301518482035f860152612d598282612d09565b9150506020830151612d6e6020860182612d30565b508091505092915050565b5f612d848383612d3f565b905092915050565b5f602082019050919050565b5f612da282612c98565b612dac8185612ca2565b935083602082028501612dbe85612cb2565b805f5b85811015612df95784840389528151612dda8582612d79565b9450612de583612d8c565b925060208a01995050600181019050612dc1565b50829750879550505050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b612e3d816121c3565b82525050565b5f612e4e8383612e34565b60208301905092915050565b5f602082019050919050565b5f612e7082612e0b565b612e7a8185612e15565b9350612e8583612e25565b805f5b83811015612eb5578151612e9c8882612e43565b9750612ea783612e5a565b925050600181019050612e88565b5085935050505092915050565b5f606083015f830151612ed75f860182612c89565b5060208301518482036020860152612eef8282612d98565b91505060408301518482036040860152612f098282612e66565b9150508091505092915050565b5f604082019050612f295f8301856128d1565b8181036020830152612f3b8184612ec2565b90509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612f7b82612067565b9150612f8683612067565b9250828203905067ffffffffffffffff811115612fa657612fa5612f44565b5b92915050565b5f602083015f8301518482035f860152612fc68282612cd1565b9150508091505092915050565b5f8115159050919050565b612fe781612fd3565b82525050565b5f819050919050565b5f61301061300b613006846120fe565b612fed565b6120fe565b9050919050565b61302081612ff6565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f604083015f8301518482035f8601526130698282612cd1565b915050602083015184820360208601526130838282612cd1565b9150508091505092915050565b5f61309b838361304f565b905092915050565b5f602082019050919050565b5f6130b982613026565b6130c38185613030565b9350836020820285016130d585613040565b805f5b8581101561311057848403895281516130f18582613090565b94506130fc836130a3565b925060208a019950506001810190506130d8565b50829750879550505050505092915050565b5f602083015f8301518482035f86015261313c82826130af565b9150508091505092915050565b5f606083015f83015161315e5f860182612c89565b50602083015184820360208601526131768282612d98565b915050604083015184820360408601526131908282612e66565b9150508091505092915050565b5f60a083015f8301516131b25f860182613017565b5060208301516131c56020860182613017565b50604083015184820360408601526131dd8282613122565b915050606083015184820360608601526131f78282613149565b915050608083015161320c6080860182612c89565b508091505092915050565b5f8160070b9050919050565b61322c81613217565b82525050565b5f602083015f8301518482035f86015261324c8282612cd1565b9150508091505092915050565b5f604083015f83015161326e5f860182613223565b50602083015184820360208601526132868282613232565b9150508091505092915050565b5f604083015f8301516132a85f860182613223565b50602083015184820360208601526132c08282613259565b9150508091505092915050565b5f60a0820190508181035f8301526132e58188612fac565b905081810360208301526132f98187612ec2565b90506133086040830186612fde565b818103606083015261331a818561319d565b9050818103608083015261332e8184613293565b90509695505050505050565b5f6020828403121561334f5761334e611ece565b5b6133596020611f40565b90505f82015167ffffffffffffffff81111561337857613377611f5a565b5b6133848482850161294e565b5f8301525092915050565b5f602082840312156133a4576133a3611ec6565b5b5f82015167ffffffffffffffff8111156133c1576133c0611eca565b5b6133cd8482850161333a565b91505092915050565b5f602083015f8301518482035f8601526133f08282612cd1565b9150508091505092915050565b5f6020820190508181035f83015261341581846133d6565b905092915050565b613426816121ba565b8114613430575f80fd5b50565b5f815190506134418161341d565b92915050565b5f6020828403121561345c5761345b611ec6565b5b5f61346984828501613433565b91505092915050565b61347b816121ba565b82525050565b5f6020820190506134945f830184613472565b92915050565b6134a3816120fe565b82525050565b6134b281612137565b82525050565b5f6060820190506134cb5f83018661349a565b6134d860208301856134a9565b81810360408301526134ea8184612ec2565b9050949350505050565b5f6020828403121561350957613508611ece565b5b6135136020611f40565b90505f82015167ffffffffffffffff81111561353257613531611f5a565b5b61353e8482850161294e565b5f8301525092915050565b5f6020828403121561355e5761355d611ec6565b5b5f82015167ffffffffffffffff81111561357b5761357a611eca565b5b613587848285016134f4565b91505092915050565b5f602083015f8301518482035f8601526135aa8282612cd1565b9150508091505092915050565b5f6020820190508181035f8301526135cf8184613590565b905092915050565b5f819050919050565b5f60ff82169050919050565b5f6136066136016135fc846135d7565b612fed565b6135e0565b9050919050565b613616816135ec565b82525050565b5f60208201905061362f5f83018461360d565b92915050565b61363e816121ba565b8114613648575f80fd5b50565b5f8151905061365981613635565b92915050565b5f6020828403121561367457613673611ec6565b5b5f6136818482850161364b565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82825260208201905092915050565b7f6163636f756e74730000000000000000000000000000000000000000000000005f82015250565b5f6136fb6008836136b7565b9150613706826136c7565b602082019050919050565b5f6020820190508181035f830152613728816136ef565b9050919050565b613738816120fe565b8114613742575f80fd5b50565b5f815190506137538161372f565b92915050565b5f6020828403121561376e5761376d611ec6565b5b5f61377b84828501613745565b91505092915050565b7f7472616e73666572416c6c6f77616e6365546f000000000000000000000000005f82015250565b5f6137b86013836136b7565b91506137c382613784565b602082019050919050565b5f6020820190508181035f8301526137e5816137ac565b9050919050565b6137f581612ff6565b82525050565b5f602083015f8301518482035f86015261381582826130af565b9150508091505092915050565b5f6080820190506138355f8301876137ec565b61384260208301866137ec565b818103604083015261385481856137fb565b905081810360608301526138688184612ec2565b905095945050505050565b5f67ffffffffffffffff82111561388d5761388c611ee2565b5b602082029050602081019050919050565b5f604082840312156138b3576138b2611ece565b5b6138bd6040611f40565b90505f82015167ffffffffffffffff8111156138dc576138db611f5a565b5b6138e88482850161294e565b5f83015250602082015167ffffffffffffffff81111561390b5761390a611f5a565b5b6139178482850161294e565b60208301525092915050565b5f61393561393084613873565b611f40565b905080838252602082019050602084028301858111156139585761395761227c565b5b835b8181101561399f57805167ffffffffffffffff81111561397d5761397c611f5e565b5b80860161398a898261389e565b8552602085019450505060208101905061395a565b5050509392505050565b5f82601f8301126139bd576139bc611f5e565b5b81516139cd848260208601613923565b91505092915050565b5f602082840312156139eb576139ea611ece565b5b6139f56020611f40565b90505f82015167ffffffffffffffff811115613a1457613a13611f5a565b5b613a20848285016139a9565b5f8301525092915050565b5f60208284031215613a4057613a3f611ec6565b5b5f82015167ffffffffffffffff811115613a5d57613a5c611eca565b5b613a69848285016139d6565b91505092915050565b7f666f6f62617200000000000000000000000000000000000000000000000000005f82015250565b5f613aa66006836136b7565b9150613ab182613a72565b602082019050919050565b5f6020820190508181035f830152613ad381613a9a565b9050919050565b5f81519050919050565b5f613aee82613ada565b613af881856136b7565b9350613b08818560208601612781565b613b1181611ed2565b840191505092915050565b5f6020820190508181035f830152613b348184613ae4565b905092915050565b7f696e63636f756e746572000000000000000000000000000000000000000000005f82015250565b5f613b70600a836136b7565b9150613b7b82613b3c565b602082019050919050565b5f6020820190508181035f830152613b9d81613b64565b9050919050565b7f696e63436f756e746572000000000000000000000000000000000000000000005f82015250565b5f613bd8600a836136b7565b9150613be382613ba4565b602082019050919050565b5f6020820190508181035f830152613c0581613bcc565b9050919050565b6b010000000000000000000000815250565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f819050919050565b613c63613c5e82613c1e565b613c49565b82525050565b7604000000b3ee6942000000000000000000000000000000815250565b5f613c9082613c0c565b601582019150613ca08284613c52565b601482019150613caf82613c69565b60118201915081905092915050565b7f65766d00000000000000000000000000000000000000000000000000000000005f82015250565b5f613cf26003836136b7565b9150613cfd82613cbe565b602082019050919050565b5f6020820190508181035f830152613d1f81613ce6565b9050919050565b7f63616c6c436f6e747261637400000000000000000000000000000000000000005f82015250565b5f613d5a600c836136b7565b9150613d6582613d26565b602082019050919050565b5f6020820190508181035f830152613d8781613d4e565b9050919050565b5f606082019050613da15f8301866137ec565b613dae60208301856137ec565b8181036040830152613dc081846137fb565b9050949350505050565b7f62616c616e6365000000000000000000000000000000000000000000000000005f82015250565b5f613dfe6007836136b7565b9150613e0982613dca565b602082019050919050565b5f6020820190508181035f830152613e2b81613df2565b9050919050565b5f613e3c82612137565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613e6e57613e6d612f44565b5b600182019050919050565b7f676f7665726e616e6365000000000000000000000000000000000000000000005f82015250565b5f613ead600a836136b7565b9150613eb882613e79565b602082019050919050565b5f6020820190508181035f830152613eda81613ea1565b9050919050565b7f636c61696d436861696e4f776e657273686970000000000000000000000000005f82015250565b5f613f156013836136b7565b9150613f2082613ee1565b602082019050919050565b5f6020820190508181035f830152613f4281613f09565b9050919050565b7f6e6f6e2d737461746963000000000000000000000000000000000000000000005f82015250565b5f613f7d600a836136b7565b9150613f8882613f49565b602082019050919050565b5f6020820190508181035f830152613faa81613f71565b9050919050565b5f81905092915050565b5f613fc582612767565b613fcf8185613fb1565b9350613fdf818560208601612781565b80840191505092915050565b5f613ff68284613fbb565b915081905092915050565b7f63616c6c2073686f756c642073756363656564000000000000000000000000005f82015250565b5f6140356013836136b7565b915061404082614001565b602082019050919050565b5f6020820190508181035f83015261406281614029565b9050919050565b7f73746174696363616c6c20746f20766965772073686f756c64207375636365655f8201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b5f6140c36021836136b7565b91506140ce82614069565b604082019050919050565b5f6020820190508181035f8301526140f0816140b7565b9050919050565b7f73746174696300000000000000000000000000000000000000000000000000005f82015250565b5f61412b6006836136b7565b9150614136826140f7565b602082019050919050565b5f6020820190508181035f8301526141588161411f565b9050919050565b7f73746174696363616c6c20746f206e6f6e2d766965772073686f756c642066615f8201527f696c000000000000000000000000000000000000000000000000000000000000602082015250565b5f6141b96022836136b7565b91506141c48261415f565b604082019050919050565b5f6020820190508181035f8301526141e6816141ad565b905091905056fea26469706673582212203e0227c2e926d05bd7228d6d4a48b8197c51182dd5e8bccd6401ce430b51372c64736f6c63430008150033 \ No newline at end of file +608060405234801561000f575f80fd5b506142748061001d5f395ff3fe608060405260043610610134575f3560e01c8063a4a05e21116100aa578063c36ba8561161006e578063c36ba85614610320578063c5e6994514610336578063d411defb1461035e578063dc91b3d014610374578063e29a58a31461039e578063e6c75c6b146103b457610134565b8063a4a05e211461028c578063b3ee6942146102a2578063bb21d921146102b8578063bcaeb8a8146102ce578063bcfb1959146102f857610134565b806346fc4bb1116100fc57806346fc4bb1146101ca578063564b81ef146101e057806357c8750e1461020a5780636a68a760146102325780639e1a00aa14610248578063a038a3e61461026457610134565b806301fc25761461013857806336c34640146101605780633772d53f1461017657806339bfb2fa1461018c57806346d11676146101b4575b5f80fd5b348015610143575f80fd5b5061015e600480360381019061015991906120f5565b6103dc565b005b34801561016b575f80fd5b5061017461061d565b005b348015610181575f80fd5b5061018a6106df565b005b348015610197575f80fd5b506101b260048036038101906101ad91906121bb565b61079e565b005b3480156101bf575f80fd5b506101c8610849565b005b3480156101d5575f80fd5b506101de61090b565b005b3480156101eb575f80fd5b506101f4610949565b6040516102019190612234565b60405180910390f35b348015610215575f80fd5b50610230600480360381019061022b91906125c5565b6109d0565b005b34801561023d575f80fd5b50610246610c52565b005b610262600480360381019061025d9190612695565b610c8d565b005b34801561026f575f80fd5b5061028a60048036038101906102859190612771565b610cd5565b005b348015610297575f80fd5b506102a0610d4f565b005b3480156102ad575f80fd5b506102b661100f565b005b3480156102c3575f80fd5b506102cc6112b0565b005b3480156102d9575f80fd5b506102e26112e0565b6040516102ef9190612832565b60405180910390f35b348015610303575f80fd5b5061031e60048036038101906103199190612852565b61156b565b005b34801561032b575f80fd5b50610334611584565b005b348015610341575f80fd5b5061035c6004803603810190610357919061287d565b611741565b005b348015610369575f80fd5b50610372611974565b005b34801561037f575f80fd5b50610388611d52565b60405161039591906128f8565b60405180910390f35b3480156103a9575f80fd5b506103b2611d58565b005b3480156103bf575f80fd5b506103da60048036038101906103d59190612771565b611d95565b005b6103e4611e12565b5f8267ffffffffffffffff160361048b5773107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a714b58d336040518263ffffffff1660e01b81526004016104429190612931565b5f60405180830381865afa15801561045c573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906104849190612c93565b90506104ab565b81815f019067ffffffffffffffff16908167ffffffffffffffff16815250505b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663423fa15133836040518363ffffffff1660e01b81526004016104fa929190612f67565b5f604051808303815f87803b158015610511575f80fd5b505af1158015610523573d5f803e3d5ffd5b5050505061052f611e12565b6101f467ffffffffffffffff16825f015167ffffffffffffffff1611610553575f80fd5b6101f4825f01516105649190612fc2565b815f019067ffffffffffffffff16908167ffffffffffffffff168152505061058a611e3c565b610592611e8a565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b7a53f538785600186866040518663ffffffff1660e01b81526004016105e895949392919061331e565b5f604051808303815f87803b1580156105ff575f80fd5b505af1158015610611573d5f803e3d5ffd5b50505050505050505050565b5f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ca6528ce6040518163ffffffff1660e01b81526004015f604051808303815f875af115801561067b573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906106a391906133e0565b90507f41aec7e1afdd771a4a8d3d2f4195266991744d24445781617c2151aa73e30186816040516106d4919061344e565b60405180910390a150565b5f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635404bbf76040518163ffffffff1660e01b81526004016020604051808303815f875af115801561073e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107629190613498565b90507f2778726dc1b9d6d2ee2628a18174907da485ba8765490e157ddf1202528ed5bc8160405161079391906134d2565b60405180910390a150565b6107a6611e12565b81815f019067ffffffffffffffff16908167ffffffffffffffff168152505073107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638adfedc78585846040518463ffffffff1660e01b815260040161081693929190613509565b5f604051808303815f87803b15801561082d575f80fd5b505af115801561083f573d5f803e3d5ffd5b5050505050505050565b5f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f31317496040518163ffffffff1660e01b81526004015f604051808303815f875af11580156108a7573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906108cf919061359a565b90507faded0c26c8cc65771b245ec36a4a290a35b0cd003545068bcef2dcac18b8815c816040516109009190613608565b60405180910390a150565b602a6040517fa8b4db62000000000000000000000000000000000000000000000000000000008152600401610940919061366d565b60405180910390fd5b5f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663564b81ef6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109a7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109cb91906136b0565b905090565b5f6040518060200160405280600267ffffffffffffffff8111156109f7576109f6611f33565b5b604051908082528060200260200182016040528015610a3057816020015b610a1d611eac565b815260200190600190039081610a155790505b50815250905060405180604001604052806040518060400160405280600181526020017f61000000000000000000000000000000000000000000000000000000000000008152508152602001845f0151815250815f01515f81518110610a9957610a986136db565b5b602002602001018190525073107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663907327e973107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610b1f90613762565b602060405180830381865afa158015610b3a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b5e91906137aa565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610ba99061381f565b602060405180830381865afa158015610bc4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610be891906137aa565b84866040518563ffffffff1660e01b8152600401610c099493929190613873565b5f604051808303815f875af1158015610c24573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f82011682018060405250810190610c4c9190613a7c565b50505050565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8490613b0d565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc8290811502906040515f60405180830381858888f19350505050158015610cd0573d5f803e3d5ffd5b505050565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e6c75c6b826040518263ffffffff1660e01b8152600401610d229190613b6d565b5f604051808303815f87803b158015610d39575f80fd5b505af1158015610d4b573d5f803e3d5ffd5b5f80fd5b5f6040518060200160405280600167ffffffffffffffff811115610d7657610d75611f33565b5b604051908082528060200260200182016040528015610daf57816020015b610d9c611eac565b815260200190600190039081610d945790505b5081525090505f6040518060400160405280600881526020017f2a00000000000000000000000000000000000000000000000000000000000000815250905060405180604001604052806040518060400160405280600781526020017f636f756e74657200000000000000000000000000000000000000000000000000815250815260200182815250825f01515f81518110610e4e57610e4d6136db565b5b6020026020010181905250610e61611e12565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663907327e973107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610edc90613bd7565b602060405180830381865afa158015610ef7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f1b91906137aa565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610f6690613c3f565b602060405180830381865afa158015610f81573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fa591906137aa565b86856040518563ffffffff1660e01b8152600401610fc69493929190613873565b5f604051808303815f875af1158015610fe1573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906110099190613a7c565b50505050565b5f3060601b6040516020016110249190613cd7565b60405160208183030381529060405290505f6040518060200160405280600167ffffffffffffffff81111561105c5761105b611f33565b5b60405190808252806020026020018201604052801561109557816020015b611082611eac565b81526020019060019003908161107a5790505b50815250905060405180604001604052806040518060400160405280600181526020017f6300000000000000000000000000000000000000000000000000000000000000815250815260200183815250815f01515f815181106110fb576110fa6136db565b5b602002602001018190525073107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630a26061773107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b815260040161118190613d59565b602060405180830381865afa15801561119c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111c091906137aa565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b815260040161120b90613dc1565b602060405180830381865afa158015611226573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061124a91906137aa565b846040518463ffffffff1660e01b815260040161126993929190613ddf565b5f60405180830381865afa158015611283573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906112ab9190613a7c565b505050565b7fb7575244c27f0af0a38da3d7e04920b4409766ef4699eea08f74dff24db98a1a60405160405180910390a15f80fd5b60605f60405180602001604052805f67ffffffffffffffff81111561130857611307611f33565b5b60405190808252806020026020018201604052801561134157816020015b61132e611eac565b8152602001906001900390816113265790505b5081525090505f73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630a26061773107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b81526004016113c390613762565b602060405180830381865afa1580156113de573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061140291906137aa565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b815260040161144d90613e65565b602060405180830381865afa158015611468573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061148c91906137aa565b856040518463ffffffff1660e01b81526004016114ab93929190613ddf565b5f60405180830381865afa1580156114c5573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f820116820180604052508101906114ed9190613a7c565b90505f5b815f015151811015611564575f825f01518281518110611514576115136136db565b5b60200260200101515f0151510361155157815f0151818151811061153b5761153a6136db565b5b6020026020010151602001519350505050611568565b808061155c90613e83565b9150506114f1565b5f80fd5b90565b8073ffffffffffffffffffffffffffffffffffffffff16ff5b61158c611ec6565b611594611e12565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663907327e973107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b815260040161160f90613f14565b602060405180830381865afa15801561162a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061164e91906137aa565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b815260040161169990613f7c565b602060405180830381865afa1580156116b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116d891906137aa565b85856040518563ffffffff1660e01b81526004016116f99493929190613873565b5f604051808303815f875af1158015611714573d5f803e3d5ffd5b505050506040513d5f823e3d601f19601f8201168201806040525081019061173c9190613a7c565b505050565b611749611e12565b81815f019067ffffffffffffffff16908167ffffffffffffffff1681525050600167ffffffffffffffff81111561178357611782611f33565b5b6040519080825280602002602001820160405280156117b15781602001602082028036833780820191505090505b5081604001819052508281604001515f815181106117d2576117d16136db565b5b60200260200101818152505073107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663423fa15133836040518363ffffffff1660e01b815260040161182d929190612f67565b5f604051808303815f87803b158015611844575f80fd5b505af1158015611856573d5f803e3d5ffd5b50505050611862611e12565b600167ffffffffffffffff81111561187d5761187c611f33565b5b6040519080825280602002602001820160405280156118ab5781602001602082028036833780820191505090505b5081604001819052508381604001515f815181106118cc576118cb6136db565b5b6020026020010181815250506118e0611e3c565b6118e8611e8a565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663b7a53f538885600186866040518663ffffffff1660e01b815260040161193e95949392919061331e565b5f604051808303815f87803b158015611955575f80fd5b505af1158015611967573d5f803e3d5ffd5b5050505050505050505050565b5f606073107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166040516024016119b190613fe4565b6040516020818303038152906040527fe6c75c6b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611a3b919061403c565b5f604051808303815f865af19150503d805f8114611a74576040519150601f19603f3d011682016040523d82523d5f602084013e611a79565b606091505b50809250819350505081611ac2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ab99061409c565b60405180910390fd5b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166040516024016040516020818303038152906040527f564b81ef000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611b7d919061403c565b5f60405180830381855afa9150503d805f8114611bb5576040519150601f19603f3d011682016040523d82523d5f602084013e611bba565b606091505b50809250819350505081611c03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bfa9061412a565b60405180910390fd5b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16604051602401611c3d90614192565b6040516020818303038152906040527fe6c75c6b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051611cc7919061403c565b5f60405180830381855afa9150503d805f8114611cff576040519150601f19603f3d011682016040523d82523d5f602084013e611d04565b606091505b5080925081935050508115611d4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4590614220565b60405180910390fd5b5050565b6101f481565b5b6127105a10611d93577ff9c7a13c2c2ddb716633ae77fd03fb7d2e3bf5ab3a45ba50ec2d3decc9ee650c60405160405180910390a1611d59565b565b73107400000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e6c75c6b826040518263ffffffff1660e01b8152600401611de29190613b6d565b5f604051808303815f87803b158015611df9575f80fd5b505af1158015611e0b573d5f803e3d5ffd5b5050505050565b60405180606001604052805f67ffffffffffffffff16815260200160608152602001606081525090565b6040518060a001604052805f63ffffffff1681526020015f63ffffffff168152602001611e67611ec6565b8152602001611e74611e12565b81526020015f67ffffffffffffffff1681525090565b60405180604001604052805f60070b8152602001611ea6611ed9565b81525090565b604051806040016040528060608152602001606081525090565b6040518060200160405280606081525090565b60405180604001604052805f60070b8152602001611ef5611efb565b81525090565b6040518060200160405280606081525090565b5f604051905090565b5f80fd5b5f80fd5b5f80fd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611f6982611f23565b810181811067ffffffffffffffff82111715611f8857611f87611f33565b5b80604052505050565b5f611f9a611f0e565b9050611fa68282611f60565b919050565b5f80fd5b5f80fd5b5f80fd5b5f67ffffffffffffffff821115611fd157611fd0611f33565b5b611fda82611f23565b9050602081019050919050565b828183375f83830152505050565b5f61200761200284611fb7565b611f91565b90508281526020810184848401111561202357612022611fb3565b5b61202e848285611fe7565b509392505050565b5f82601f83011261204a57612049611faf565b5b813561205a848260208601611ff5565b91505092915050565b5f6020828403121561207857612077611f1f565b5b6120826020611f91565b90505f82013567ffffffffffffffff8111156120a1576120a0611fab565b5b6120ad84828501612036565b5f8301525092915050565b5f67ffffffffffffffff82169050919050565b6120d4816120b8565b81146120de575f80fd5b50565b5f813590506120ef816120cb565b92915050565b5f806040838503121561210b5761210a611f17565b5b5f83013567ffffffffffffffff81111561212857612127611f1b565b5b61213485828601612063565b9250506020612145858286016120e1565b9150509250929050565b5f63ffffffff82169050919050565b6121678161214f565b8114612171575f80fd5b50565b5f813590506121828161215e565b92915050565b5f819050919050565b61219a81612188565b81146121a4575f80fd5b50565b5f813590506121b581612191565b92915050565b5f805f606084860312156121d2576121d1611f17565b5b5f6121df86828701612174565b93505060206121f0868287016121a7565b9250506040612201868287016120e1565b9150509250925092565b5f819050919050565b5f61221e8261220b565b9050919050565b61222e81612214565b82525050565b5f6020820190506122475f830184612225565b92915050565b5f6020828403121561226257612261611f1f565b5b61226c6020611f91565b90505f82013567ffffffffffffffff81111561228b5761228a611fab565b5b61229784828501612036565b5f8301525092915050565b5f67ffffffffffffffff8211156122bc576122bb611f33565b5b602082029050602081019050919050565b5f80fd5b5f602082840312156122e6576122e5611f1f565b5b6122f06020611f91565b90505f82013567ffffffffffffffff81111561230f5761230e611fab565b5b61231b84828501612036565b5f8301525092915050565b5f6040828403121561233b5761233a611f1f565b5b6123456040611f91565b90505f82013567ffffffffffffffff81111561236457612363611fab565b5b612370848285016122d1565b5f830152506020612383848285016121a7565b60208301525092915050565b5f6123a161239c846122a2565b611f91565b905080838252602082019050602084028301858111156123c4576123c36122cd565b5b835b8181101561240b57803567ffffffffffffffff8111156123e9576123e8611faf565b5b8086016123f68982612326565b855260208501945050506020810190506123c6565b5050509392505050565b5f82601f83011261242957612428611faf565b5b813561243984826020860161238f565b91505092915050565b5f67ffffffffffffffff82111561245c5761245b611f33565b5b602082029050602081019050919050565b6124768161220b565b8114612480575f80fd5b50565b5f813590506124918161246d565b92915050565b5f6124a96124a484612442565b611f91565b905080838252602082019050602084028301858111156124cc576124cb6122cd565b5b835b818110156124f557806124e18882612483565b8452602084019350506020810190506124ce565b5050509392505050565b5f82601f83011261251357612512611faf565b5b8135612523848260208601612497565b91505092915050565b5f6060828403121561254157612540611f1f565b5b61254b6060611f91565b90505f61255a848285016120e1565b5f83015250602082013567ffffffffffffffff81111561257d5761257c611fab565b5b61258984828501612415565b602083015250604082013567ffffffffffffffff8111156125ad576125ac611fab565b5b6125b9848285016124ff565b60408301525092915050565b5f80604083850312156125db576125da611f17565b5b5f83013567ffffffffffffffff8111156125f8576125f7611f1b565b5b6126048582860161224d565b925050602083013567ffffffffffffffff81111561262557612624611f1b565b5b6126318582860161252c565b9150509250929050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6126648261263b565b9050919050565b6126748161265a565b811461267e575f80fd5b50565b5f8135905061268f8161266b565b92915050565b5f80604083850312156126ab576126aa611f17565b5b5f6126b885828601612681565b92505060206126c9858286016121a7565b9150509250929050565b5f67ffffffffffffffff8211156126ed576126ec611f33565b5b6126f682611f23565b9050602081019050919050565b5f612715612710846126d3565b611f91565b90508281526020810184848401111561273157612730611fb3565b5b61273c848285611fe7565b509392505050565b5f82601f83011261275857612757611faf565b5b8135612768848260208601612703565b91505092915050565b5f6020828403121561278657612785611f17565b5b5f82013567ffffffffffffffff8111156127a3576127a2611f1b565b5b6127af84828501612744565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b838110156127ef5780820151818401526020810190506127d4565b5f8484015250505050565b5f612804826127b8565b61280e81856127c2565b935061281e8185602086016127d2565b61282781611f23565b840191505092915050565b5f6020820190508181035f83015261284a81846127fa565b905092915050565b5f6020828403121561286757612866611f17565b5b5f61287484828501612681565b91505092915050565b5f805f6060848603121561289457612893611f17565b5b5f84013567ffffffffffffffff8111156128b1576128b0611f1b565b5b6128bd86828701612063565b93505060206128ce86828701612483565b92505060406128df868287016120e1565b9150509250925092565b6128f2816120b8565b82525050565b5f60208201905061290b5f8301846128e9565b92915050565b5f61291b8261263b565b9050919050565b61292b81612911565b82525050565b5f6020820190506129445f830184612922565b92915050565b5f81519050612958816120cb565b92915050565b5f61297061296b84611fb7565b611f91565b90508281526020810184848401111561298c5761298b611fb3565b5b6129978482856127d2565b509392505050565b5f82601f8301126129b3576129b2611faf565b5b81516129c384826020860161295e565b91505092915050565b5f602082840312156129e1576129e0611f1f565b5b6129eb6020611f91565b90505f82015167ffffffffffffffff811115612a0a57612a09611fab565b5b612a168482850161299f565b5f8301525092915050565b5f81519050612a2f81612191565b92915050565b5f60408284031215612a4a57612a49611f1f565b5b612a546040611f91565b90505f82015167ffffffffffffffff811115612a7357612a72611fab565b5b612a7f848285016129cc565b5f830152506020612a9284828501612a21565b60208301525092915050565b5f612ab0612aab846122a2565b611f91565b90508083825260208201905060208402830185811115612ad357612ad26122cd565b5b835b81811015612b1a57805167ffffffffffffffff811115612af857612af7611faf565b5b808601612b058982612a35565b85526020850194505050602081019050612ad5565b5050509392505050565b5f82601f830112612b3857612b37611faf565b5b8151612b48848260208601612a9e565b91505092915050565b5f81519050612b5f8161246d565b92915050565b5f612b77612b7284612442565b611f91565b90508083825260208201905060208402830185811115612b9a57612b996122cd565b5b835b81811015612bc35780612baf8882612b51565b845260208401935050602081019050612b9c565b5050509392505050565b5f82601f830112612be157612be0611faf565b5b8151612bf1848260208601612b65565b91505092915050565b5f60608284031215612c0f57612c0e611f1f565b5b612c196060611f91565b90505f612c288482850161294a565b5f83015250602082015167ffffffffffffffff811115612c4b57612c4a611fab565b5b612c5784828501612b24565b602083015250604082015167ffffffffffffffff811115612c7b57612c7a611fab565b5b612c8784828501612bcd565b60408301525092915050565b5f60208284031215612ca857612ca7611f17565b5b5f82015167ffffffffffffffff811115612cc557612cc4611f1b565b5b612cd184828501612bfa565b91505092915050565b612ce3816120b8565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f82825260208201905092915050565b5f612d2c826127b8565b612d368185612d12565b9350612d468185602086016127d2565b612d4f81611f23565b840191505092915050565b5f602083015f8301518482035f860152612d748282612d22565b9150508091505092915050565b612d8a81612188565b82525050565b5f604083015f8301518482035f860152612daa8282612d5a565b9150506020830151612dbf6020860182612d81565b508091505092915050565b5f612dd58383612d90565b905092915050565b5f602082019050919050565b5f612df382612ce9565b612dfd8185612cf3565b935083602082028501612e0f85612d03565b805f5b85811015612e4a5784840389528151612e2b8582612dca565b9450612e3683612ddd565b925060208a01995050600181019050612e12565b50829750879550505050505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b612e8e81612214565b82525050565b5f612e9f8383612e85565b60208301905092915050565b5f602082019050919050565b5f612ec182612e5c565b612ecb8185612e66565b9350612ed683612e76565b805f5b83811015612f06578151612eed8882612e94565b9750612ef883612eab565b925050600181019050612ed9565b5085935050505092915050565b5f606083015f830151612f285f860182612cda565b5060208301518482036020860152612f408282612de9565b91505060408301518482036040860152612f5a8282612eb7565b9150508091505092915050565b5f604082019050612f7a5f830185612922565b8181036020830152612f8c8184612f13565b90509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612fcc826120b8565b9150612fd7836120b8565b9250828203905067ffffffffffffffff811115612ff757612ff6612f95565b5b92915050565b5f602083015f8301518482035f8601526130178282612d22565b9150508091505092915050565b5f8115159050919050565b61303881613024565b82525050565b5f819050919050565b5f61306161305c6130578461214f565b61303e565b61214f565b9050919050565b61307181613047565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f604083015f8301518482035f8601526130ba8282612d22565b915050602083015184820360208601526130d48282612d22565b9150508091505092915050565b5f6130ec83836130a0565b905092915050565b5f602082019050919050565b5f61310a82613077565b6131148185613081565b93508360208202850161312685613091565b805f5b85811015613161578484038952815161314285826130e1565b945061314d836130f4565b925060208a01995050600181019050613129565b50829750879550505050505092915050565b5f602083015f8301518482035f86015261318d8282613100565b9150508091505092915050565b5f606083015f8301516131af5f860182612cda565b50602083015184820360208601526131c78282612de9565b915050604083015184820360408601526131e18282612eb7565b9150508091505092915050565b5f60a083015f8301516132035f860182613068565b5060208301516132166020860182613068565b506040830151848203604086015261322e8282613173565b91505060608301518482036060860152613248828261319a565b915050608083015161325d6080860182612cda565b508091505092915050565b5f8160070b9050919050565b61327d81613268565b82525050565b5f602083015f8301518482035f86015261329d8282612d22565b9150508091505092915050565b5f604083015f8301516132bf5f860182613274565b50602083015184820360208601526132d78282613283565b9150508091505092915050565b5f604083015f8301516132f95f860182613274565b506020830151848203602086015261331182826132aa565b9150508091505092915050565b5f60a0820190508181035f8301526133368188612ffd565b9050818103602083015261334a8187612f13565b9050613359604083018661302f565b818103606083015261336b81856131ee565b9050818103608083015261337f81846132e4565b90509695505050505050565b5f602082840312156133a05761339f611f1f565b5b6133aa6020611f91565b90505f82015167ffffffffffffffff8111156133c9576133c8611fab565b5b6133d58482850161299f565b5f8301525092915050565b5f602082840312156133f5576133f4611f17565b5b5f82015167ffffffffffffffff81111561341257613411611f1b565b5b61341e8482850161338b565b91505092915050565b5f602083015f8301518482035f8601526134418282612d22565b9150508091505092915050565b5f6020820190508181035f8301526134668184613427565b905092915050565b6134778161220b565b8114613481575f80fd5b50565b5f815190506134928161346e565b92915050565b5f602082840312156134ad576134ac611f17565b5b5f6134ba84828501613484565b91505092915050565b6134cc8161220b565b82525050565b5f6020820190506134e55f8301846134c3565b92915050565b6134f48161214f565b82525050565b61350381612188565b82525050565b5f60608201905061351c5f8301866134eb565b61352960208301856134fa565b818103604083015261353b8184612f13565b9050949350505050565b5f6020828403121561355a57613559611f1f565b5b6135646020611f91565b90505f82015167ffffffffffffffff81111561358357613582611fab565b5b61358f8482850161299f565b5f8301525092915050565b5f602082840312156135af576135ae611f17565b5b5f82015167ffffffffffffffff8111156135cc576135cb611f1b565b5b6135d884828501613545565b91505092915050565b5f602083015f8301518482035f8601526135fb8282612d22565b9150508091505092915050565b5f6020820190508181035f83015261362081846135e1565b905092915050565b5f819050919050565b5f60ff82169050919050565b5f61365761365261364d84613628565b61303e565b613631565b9050919050565b6136678161363d565b82525050565b5f6020820190506136805f83018461365e565b92915050565b61368f8161220b565b8114613699575f80fd5b50565b5f815190506136aa81613686565b92915050565b5f602082840312156136c5576136c4611f17565b5b5f6136d28482850161369c565b91505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82825260208201905092915050565b7f6163636f756e74730000000000000000000000000000000000000000000000005f82015250565b5f61374c600883613708565b915061375782613718565b602082019050919050565b5f6020820190508181035f83015261377981613740565b9050919050565b6137898161214f565b8114613793575f80fd5b50565b5f815190506137a481613780565b92915050565b5f602082840312156137bf576137be611f17565b5b5f6137cc84828501613796565b91505092915050565b7f7472616e73666572416c6c6f77616e6365546f000000000000000000000000005f82015250565b5f613809601383613708565b9150613814826137d5565b602082019050919050565b5f6020820190508181035f830152613836816137fd565b9050919050565b61384681613047565b82525050565b5f602083015f8301518482035f8601526138668282613100565b9150508091505092915050565b5f6080820190506138865f83018761383d565b613893602083018661383d565b81810360408301526138a5818561384c565b905081810360608301526138b98184612f13565b905095945050505050565b5f67ffffffffffffffff8211156138de576138dd611f33565b5b602082029050602081019050919050565b5f6040828403121561390457613903611f1f565b5b61390e6040611f91565b90505f82015167ffffffffffffffff81111561392d5761392c611fab565b5b6139398482850161299f565b5f83015250602082015167ffffffffffffffff81111561395c5761395b611fab565b5b6139688482850161299f565b60208301525092915050565b5f613986613981846138c4565b611f91565b905080838252602082019050602084028301858111156139a9576139a86122cd565b5b835b818110156139f057805167ffffffffffffffff8111156139ce576139cd611faf565b5b8086016139db89826138ef565b855260208501945050506020810190506139ab565b5050509392505050565b5f82601f830112613a0e57613a0d611faf565b5b8151613a1e848260208601613974565b91505092915050565b5f60208284031215613a3c57613a3b611f1f565b5b613a466020611f91565b90505f82015167ffffffffffffffff811115613a6557613a64611fab565b5b613a71848285016139fa565b5f8301525092915050565b5f60208284031215613a9157613a90611f17565b5b5f82015167ffffffffffffffff811115613aae57613aad611f1b565b5b613aba84828501613a27565b91505092915050565b7f666f6f62617200000000000000000000000000000000000000000000000000005f82015250565b5f613af7600683613708565b9150613b0282613ac3565b602082019050919050565b5f6020820190508181035f830152613b2481613aeb565b9050919050565b5f81519050919050565b5f613b3f82613b2b565b613b498185613708565b9350613b598185602086016127d2565b613b6281611f23565b840191505092915050565b5f6020820190508181035f830152613b858184613b35565b905092915050565b7f696e63636f756e746572000000000000000000000000000000000000000000005f82015250565b5f613bc1600a83613708565b9150613bcc82613b8d565b602082019050919050565b5f6020820190508181035f830152613bee81613bb5565b9050919050565b7f696e63436f756e746572000000000000000000000000000000000000000000005f82015250565b5f613c29600a83613708565b9150613c3482613bf5565b602082019050919050565b5f6020820190508181035f830152613c5681613c1d565b9050919050565b6b010000000000000000000000815250565b5f7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000082169050919050565b5f819050919050565b613cb4613caf82613c6f565b613c9a565b82525050565b7604000000b3ee6942000000000000000000000000000000815250565b5f613ce182613c5d565b601582019150613cf18284613ca3565b601482019150613d0082613cba565b60118201915081905092915050565b7f65766d00000000000000000000000000000000000000000000000000000000005f82015250565b5f613d43600383613708565b9150613d4e82613d0f565b602082019050919050565b5f6020820190508181035f830152613d7081613d37565b9050919050565b7f63616c6c436f6e747261637400000000000000000000000000000000000000005f82015250565b5f613dab600c83613708565b9150613db682613d77565b602082019050919050565b5f6020820190508181035f830152613dd881613d9f565b9050919050565b5f606082019050613df25f83018661383d565b613dff602083018561383d565b8181036040830152613e11818461384c565b9050949350505050565b7f62616c616e6365000000000000000000000000000000000000000000000000005f82015250565b5f613e4f600783613708565b9150613e5a82613e1b565b602082019050919050565b5f6020820190508181035f830152613e7c81613e43565b9050919050565b5f613e8d82612188565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613ebf57613ebe612f95565b5b600182019050919050565b7f676f7665726e616e6365000000000000000000000000000000000000000000005f82015250565b5f613efe600a83613708565b9150613f0982613eca565b602082019050919050565b5f6020820190508181035f830152613f2b81613ef2565b9050919050565b7f636c61696d436861696e4f776e657273686970000000000000000000000000005f82015250565b5f613f66601383613708565b9150613f7182613f32565b602082019050919050565b5f6020820190508181035f830152613f9381613f5a565b9050919050565b7f6e6f6e2d737461746963000000000000000000000000000000000000000000005f82015250565b5f613fce600a83613708565b9150613fd982613f9a565b602082019050919050565b5f6020820190508181035f830152613ffb81613fc2565b9050919050565b5f81905092915050565b5f614016826127b8565b6140208185614002565b93506140308185602086016127d2565b80840191505092915050565b5f614047828461400c565b915081905092915050565b7f63616c6c2073686f756c642073756363656564000000000000000000000000005f82015250565b5f614086601383613708565b915061409182614052565b602082019050919050565b5f6020820190508181035f8301526140b38161407a565b9050919050565b7f73746174696363616c6c20746f20766965772073686f756c64207375636365655f8201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b5f614114602183613708565b915061411f826140ba565b604082019050919050565b5f6020820190508181035f83015261414181614108565b9050919050565b7f73746174696300000000000000000000000000000000000000000000000000005f82015250565b5f61417c600683613708565b915061418782614148565b602082019050919050565b5f6020820190508181035f8301526141a981614170565b9050919050565b7f73746174696363616c6c20746f206e6f6e2d766965772073686f756c642066615f8201527f696c000000000000000000000000000000000000000000000000000000000000602082015250565b5f61420a602283613708565b9150614215826141b0565b604082019050919050565b5f6020820190508181035f830152614237816141fe565b905091905056fea2646970667358221220d3388d377a7b6849f409947d3cb9dba9c1f1e2d6d7b065365be276e7f048a99d64736f6c63430008150033 \ No newline at end of file diff --git a/packages/evm/evmtest/ISCTest.sol b/packages/evm/evmtest/ISCTest.sol index fadfcb1dd5..fd96291569 100644 --- a/packages/evm/evmtest/ISCTest.sol +++ b/packages/evm/evmtest/ISCTest.sol @@ -196,4 +196,11 @@ contract ISCTest { function revertWithCustomError() public pure { revert CustomError(42); } + + event SomeEvent(); + + function emitEventAndRevert() public { + emit SomeEvent(); + revert(); + } } diff --git a/packages/evm/jsonrpc/types.go b/packages/evm/jsonrpc/types.go index f0d9e60673..b60a736a6c 100644 --- a/packages/evm/jsonrpc/types.go +++ b/packages/evm/jsonrpc/types.go @@ -170,34 +170,29 @@ func RPCMarshalReceipt(r *types.Receipt, tx *types.Transaction) map[string]inter "cumulativeGasUsed": hexutil.Uint64(r.CumulativeGasUsed), "gasUsed": hexutil.Uint64(r.GasUsed), "contractAddress": r.ContractAddress, - "logs": RPCMarshalLogs(r), + "logs": rpcMarshalLogs(r), "logsBloom": r.Bloom, "status": hexutil.Uint64(r.Status), } } -func RPCMarshalLogs(r *types.Receipt) []interface{} { +func rpcMarshalLogs(r *types.Receipt) []interface{} { ret := make([]interface{}, len(r.Logs)) - for i := range r.Logs { - ret[i] = RPCMarshalLog(r, uint(i)) + for i, log := range r.Logs { + ret[i] = map[string]interface{}{ + "logIndex": hexutil.Uint(log.Index), + "blockNumber": hexutil.Uint(log.BlockNumber), + "blockHash": log.BlockHash, + "transactionHash": log.TxHash, + "transactionIndex": hexutil.Uint(log.TxIndex), + "address": log.Address, + "data": hexutil.Bytes(log.Data), + "topics": log.Topics, + } } return ret } -func RPCMarshalLog(r *types.Receipt, logIndex uint) map[string]interface{} { - log := r.Logs[logIndex] - return map[string]interface{}{ - "logIndex": hexutil.Uint64(logIndex), - "blockNumber": (*hexutil.Big)(r.BlockNumber), - "blockHash": r.BlockHash, - "transactionHash": r.TxHash, - "transactionIndex": hexutil.Uint64(r.TransactionIndex), - "address": log.Address, - "data": hexutil.Bytes(log.Data), - "topics": log.Topics, - } -} - type RPCCallArgs struct { From common.Address `json:"from"` To *common.Address `json:"to"` diff --git a/packages/vm/core/evm/emulator/blockchaindb.go b/packages/vm/core/evm/emulator/blockchaindb.go index 28ef8cb57d..7dea4369af 100644 --- a/packages/vm/core/evm/emulator/blockchaindb.go +++ b/packages/vm/core/evm/emulator/blockchaindb.go @@ -4,6 +4,7 @@ package emulator import ( + "fmt" "io" "math/big" @@ -131,14 +132,18 @@ func (bc *BlockchainDB) GetPendingHeader(timestamp uint64) *types.Header { } } -func (bc *BlockchainDB) GetLatestPendingReceipt() *types.Receipt { +func (bc *BlockchainDB) getPendingCumulativeGasUsed() uint64 { blockNumber := bc.GetPendingBlockNumber() receiptArray := bc.getReceiptArray(blockNumber) n := receiptArray.Len() if n == 0 { - return nil + return 0 + } + r, err := evmtypes.DecodeReceipt(receiptArray.GetAt(n - 1)) + if err != nil { + panic(err) } - return bc.GetReceiptByBlockNumberAndIndex(blockNumber, n-1) + return r.CumulativeGasUsed } func (bc *BlockchainDB) AddTransaction(tx *types.Transaction, receipt *types.Receipt) { @@ -300,7 +305,7 @@ func (bc *BlockchainDB) addBlock(header *types.Header) { bc.setNumber(blockNumber) } -func (bc *BlockchainDB) GetReceiptByBlockNumberAndIndex(blockNumber uint64, txIndex uint32) *types.Receipt { +func (bc *BlockchainDB) getRawReceiptByBlockNumberAndIndex(blockNumber uint64, txIndex uint32) *types.Receipt { receipts := bc.getReceiptArray(blockNumber) if txIndex >= receipts.Len() { return nil @@ -309,7 +314,18 @@ func (bc *BlockchainDB) GetReceiptByBlockNumberAndIndex(blockNumber uint64, txIn if err != nil { panic(err) } + return r +} + +func (bc *BlockchainDB) getReceiptByBlockNumberAndIndex( + blockNumber uint64, + txIndex uint32, + cumulativeGasUsed uint64, + logIndex uint, +) *types.Receipt { + r := bc.getRawReceiptByBlockNumberAndIndex(blockNumber, txIndex) tx := bc.GetTransactionByBlockNumberAndIndex(blockNumber, txIndex) + r.TxHash = tx.Hash() r.BlockHash = bc.GetBlockHashByBlockNumber(blockNumber) for i, log := range r.Logs { @@ -317,21 +333,15 @@ func (bc *BlockchainDB) GetReceiptByBlockNumberAndIndex(blockNumber uint64, txIn log.TxIndex = uint(txIndex) log.BlockHash = r.BlockHash log.BlockNumber = blockNumber - log.Index = uint(i) + log.Index = logIndex + uint(i) } if tx.To() == nil { from, _ := types.Sender(evmutil.Signer(big.NewInt(int64(bc.GetChainID()))), tx) r.ContractAddress = crypto.CreateAddress(from, tx.Nonce()) } - r.GasUsed = r.CumulativeGasUsed - if txIndex > 0 { - prev, err := evmtypes.DecodeReceipt(receipts.GetAt(txIndex - 1)) - if err != nil { - panic(err) - } - r.GasUsed -= prev.CumulativeGasUsed - } + r.GasUsed = r.CumulativeGasUsed - cumulativeGasUsed r.BlockNumber = new(big.Int).SetUint64(blockNumber) + r.TransactionIndex = uint(txIndex) return r } @@ -357,7 +367,11 @@ func (bc *BlockchainDB) GetReceiptByTxHash(txHash common.Hash) *types.Receipt { return nil } i := bc.GetTxIndexInBlockByTxHash(txHash) - return bc.GetReceiptByBlockNumberAndIndex(blockNumber, i) + receipts := bc.GetReceiptsByBlockNumber(blockNumber) + if int(i) >= len(receipts) { + panic(fmt.Sprintf("cannot find evm receipt for tx %s", txHash)) + } + return receipts[i] } func (bc *BlockchainDB) GetTransactionByBlockNumberAndIndex(blockNumber uint64, i uint32) *types.Transaction { @@ -479,8 +493,17 @@ func (bc *BlockchainDB) GetTransactionsByBlockNumber(blockNumber uint64) []*type func (bc *BlockchainDB) GetReceiptsByBlockNumber(blockNumber uint64) []*types.Receipt { txArray := bc.getTxArray(blockNumber) receipts := make([]*types.Receipt, txArray.Len()) + logIndex := uint(0) + cumulativeGasUsed := uint64(0) for i := range receipts { - receipts[i] = bc.GetReceiptByBlockNumberAndIndex(blockNumber, uint32(i)) + receipts[i] = bc.getReceiptByBlockNumberAndIndex( + blockNumber, + uint32(i), + cumulativeGasUsed, + logIndex, + ) + logIndex += uint(len(receipts[i].Logs)) + cumulativeGasUsed = receipts[i].CumulativeGasUsed } return receipts } diff --git a/packages/vm/core/evm/emulator/emulator.go b/packages/vm/core/evm/emulator/emulator.go index e645631dc8..907e056c87 100644 --- a/packages/vm/core/evm/emulator/emulator.go +++ b/packages/vm/core/evm/emulator/emulator.go @@ -311,23 +311,13 @@ func (e *EVMEmulator) SendTransaction( if result != nil { gasUsed = result.UsedGas } - - cumulativeGasUsed := gasUsed - index := uint(0) - latest := e.BlockchainDB().GetLatestPendingReceipt() - if latest != nil { - cumulativeGasUsed += latest.CumulativeGasUsed - index = latest.TransactionIndex + 1 - } + cumulativeGasUsed := e.BlockchainDB().getPendingCumulativeGasUsed() + gasUsed receipt = &types.Receipt{ Type: tx.Type(), CumulativeGasUsed: cumulativeGasUsed, - TxHash: tx.Hash(), GasUsed: gasUsed, - Logs: statedb.GetLogs(tx.Hash()), - BlockNumber: pendingHeader.Number, - TransactionIndex: index, + Logs: statedb.GetLogs(), } receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) diff --git a/packages/vm/core/evm/emulator/emulator_test.go b/packages/vm/core/evm/emulator/emulator_test.go index f86a7d6035..8c7066c154 100644 --- a/packages/vm/core/evm/emulator/emulator_test.go +++ b/packages/vm/core/evm/emulator/emulator_test.go @@ -97,7 +97,16 @@ func estimateGas(callMsg ethereum.CallMsg, e *EVMEmulator) (uint64, error) { return lastOk, nil } -func sendTransaction(t testing.TB, emu *EVMEmulator, sender *ecdsa.PrivateKey, receiverAddress common.Address, amount *big.Int, data []byte, gasLimit uint64) *types.Receipt { +func sendTransaction( + t testing.TB, + emu *EVMEmulator, + sender *ecdsa.PrivateKey, + receiverAddress common.Address, + amount *big.Int, + data []byte, + gasLimit uint64, + mintBlock bool, +) *types.Receipt { senderAddress := crypto.PubkeyToAddress(sender.PublicKey) if gasLimit == 0 { @@ -124,7 +133,9 @@ func sendTransaction(t testing.TB, emu *EVMEmulator, sender *ecdsa.PrivateKey, r if res.Err != nil { t.Logf("Execution failed: %v", res.Err) } - emu.MintBlock() + if mintBlock { + emu.MintBlock() + } return receipt } @@ -267,7 +278,9 @@ func TestBlockchain(t *testing.T) { require.EqualValues(t, 1, emu.BlockchainDB().GetNumber()) block := emu.BlockchainDB().GetCurrentBlock() require.EqualValues(t, 1, block.Header().Number.Uint64()) - receipt := emu.BlockchainDB().GetReceiptByBlockNumberAndIndex(1, 0) + receipts := emu.BlockchainDB().GetReceiptsByBlockNumber(1) + require.Len(t, receipts, 1) + receipt := receipts[0] require.EqualValues(t, receipt.Bloom, block.Bloom()) require.EqualValues(t, receipt.GasUsed, block.GasUsed()) require.EqualValues(t, emu.BlockchainDB().GetBlockByNumber(0).Hash(), block.ParentHash()) @@ -311,7 +324,13 @@ func TestBlockchainPersistence(t *testing.T) { } } -type contractFnCaller func(sender *ecdsa.PrivateKey, gasLimit uint64, name string, args ...interface{}) *types.Receipt +type contractFnCaller func( + mintBlock bool, + sender *ecdsa.PrivateKey, + gasLimit uint64, + name string, + args ...interface{}, +) *types.Receipt func deployEVMContract(t testing.TB, emu *EVMEmulator, creator *ecdsa.PrivateKey, contractABI abi.ABI, contractBytecode []byte, args ...interface{}) (common.Address, contractFnCaller) { creatorAddress := crypto.PubkeyToAddress(creator.PublicKey) @@ -370,10 +389,16 @@ func deployEVMContract(t testing.TB, emu *EVMEmulator, creator *ecdsa.PrivateKey } } - callFn := func(sender *ecdsa.PrivateKey, gasLimit uint64, name string, args ...interface{}) *types.Receipt { + callFn := func( + mintBlock bool, + sender *ecdsa.PrivateKey, + gasLimit uint64, + name string, + args ...interface{}, + ) *types.Receipt { callArguments, err := contractABI.Pack(name, args...) require.NoError(t, err) - receipt := sendTransaction(t, emu, sender, contractAddress, big.NewInt(0), callArguments, gasLimit) + receipt := sendTransaction(t, emu, sender, contractAddress, big.NewInt(0), callArguments, gasLimit, mintBlock) t.Logf("callFn %s Status: %d", name, receipt.Status) t.Log("Logs:") for _, log := range receipt.Logs { @@ -437,7 +462,7 @@ func TestStorageContract(t *testing.T) { // send tx that calls `store(43)` { - callFn(faucet, 0, "store", uint32(43)) + callFn(true, faucet, 0, "store", uint32(43)) ctx.timestamp++ require.EqualValues(t, 2, emu.BlockchainDB().GetNumber()) } @@ -518,7 +543,7 @@ func TestERC20Contract(t *testing.T) { transferAmount := big.NewInt(1337) // call `transfer` => send 1337 TestCoin to recipientAddress - receipt := callFn(erc20Owner, 0, "transfer", recipientAddress, transferAmount) + receipt := callFn(true, erc20Owner, 0, "transfer", recipientAddress, transferAmount) ctx.timestamp++ require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) require.Equal(t, 1, len(receipt.Logs)) @@ -527,7 +552,7 @@ func TestERC20Contract(t *testing.T) { require.Zero(t, callIntViewFn("balanceOf", recipientAddress).Cmp(transferAmount)) // call `transferFrom` as recipient without allowance => get error - receipt = callFn(recipient, gasLimits.Call, "transferFrom", erc20OwnerAddress, recipientAddress, transferAmount) + receipt = callFn(true, recipient, gasLimits.Call, "transferFrom", erc20OwnerAddress, recipientAddress, transferAmount) ctx.timestamp++ require.Equal(t, types.ReceiptStatusFailed, receipt.Status) require.Equal(t, 0, len(receipt.Logs)) @@ -536,19 +561,55 @@ func TestERC20Contract(t *testing.T) { require.Zero(t, callIntViewFn("balanceOf", recipientAddress).Cmp(transferAmount)) // call `approve` as erc20Owner - receipt = callFn(erc20Owner, 0, "approve", recipientAddress, transferAmount) + receipt = callFn(true, erc20Owner, 0, "approve", recipientAddress, transferAmount) ctx.timestamp++ require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) require.Equal(t, 1, len(receipt.Logs)) // call `transferFrom` as recipient with allowance => ok - receipt = callFn(recipient, 0, "transferFrom", erc20OwnerAddress, recipientAddress, transferAmount) + receipt = callFn(true, recipient, 0, "transferFrom", erc20OwnerAddress, recipientAddress, transferAmount) ctx.timestamp++ require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) require.Equal(t, 1, len(receipt.Logs)) // call `balanceOf` view => check balance of recipient = 2 * 1337 TestCoin require.Zero(t, callIntViewFn("balanceOf", recipientAddress).Cmp(new(big.Int).Mul(transferAmount, big.NewInt(2)))) + + // call `transfer` 10 times on the same block, check receipt and logs derived fields + { + for i := 0; i < 10; i++ { + receipt := callFn(false, erc20Owner, 0, "transfer", recipientAddress, transferAmount) + require.Equal(t, types.ReceiptStatusSuccessful, receipt.Status) + require.Equal(t, 1, len(receipt.Logs)) + } + emu.MintBlock() + ctx.timestamp++ + } + { + blockNumber := emu.BlockchainDB().GetNumber() + block := emu.BlockchainDB().GetBlockByNumber(blockNumber) + receipts := emu.BlockchainDB().GetReceiptsByBlockNumber(blockNumber) + require.Len(t, receipts, 10) + gas := uint64(0) + for i, r := range receipts { + tx := emu.BlockchainDB().GetTransactionByBlockNumberAndIndex(blockNumber, uint32(i)) + require.Equal(t, tx.Hash(), r.TxHash) + require.NotZero(t, r.GasUsed) + gas += r.GasUsed + require.Equal(t, block.Hash(), r.BlockHash) + require.Equal(t, blockNumber, r.BlockNumber.Uint64()) + require.EqualValues(t, i, r.TransactionIndex) + + require.Len(t, r.Logs, 1) + log := r.Logs[0] + require.Equal(t, blockNumber, log.BlockNumber) + require.Equal(t, tx.Hash(), log.TxHash) + require.EqualValues(t, i, log.TxIndex) + require.Equal(t, block.Hash(), log.BlockHash) + require.EqualValues(t, i, log.Index) + } + require.Equal(t, gas, receipts[len(receipts)-1].CumulativeGasUsed, gas) + } } func initBenchmark(b *testing.B) (*EVMEmulator, []*types.Transaction, *context) { diff --git a/packages/vm/core/evm/emulator/statedb.go b/packages/vm/core/evm/emulator/statedb.go index 65e60293b7..7af020d968 100644 --- a/packages/vm/core/evm/emulator/statedb.go +++ b/packages/vm/core/evm/emulator/statedb.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + "golang.org/x/exp/slices" "github.com/iotaledger/wasp/packages/kv" "github.com/iotaledger/wasp/packages/kv/codec" @@ -48,18 +49,20 @@ func accountSuicidedKey(addr common.Address) kv.Key { // StateDB implements vm.StateDB with a kv.KVStore as backend. // The Ethereum account balance is tied to the L1 balance. type StateDB struct { - ctx Context - kv kv.KVStore // subrealm of ctx.State() - logs []*types.Log - refund uint64 + ctx Context + kv kv.KVStore // subrealm of ctx.State() + logs []*types.Log + snapshots map[int][]*types.Log + refund uint64 } var _ vm.StateDB = &StateDB{} func NewStateDB(ctx Context) *StateDB { return &StateDB{ - ctx: ctx, - kv: StateDBSubrealm(ctx.State()), + ctx: ctx, + kv: StateDBSubrealm(ctx.State()), + snapshots: make(map[int][]*types.Log), } } @@ -258,19 +261,21 @@ func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { } func (s *StateDB) Snapshot() int { - return s.ctx.TakeSnapshot() + i := s.ctx.TakeSnapshot() + s.snapshots[i] = slices.Clone(s.logs) + return i } func (s *StateDB) RevertToSnapshot(i int) { s.ctx.RevertToSnapshot(i) + s.logs = s.snapshots[i] } func (s *StateDB) AddLog(log *types.Log) { - log.Index = uint(len(s.logs)) s.logs = append(s.logs, log) } -func (s *StateDB) GetLogs(_ common.Hash) []*types.Log { +func (s *StateDB) GetLogs() []*types.Log { return s.logs } diff --git a/packages/vm/core/evm/evmtest/evm_test.go b/packages/vm/core/evm/evmtest/evm_test.go index ea26f37e3a..b0511d7ec8 100644 --- a/packages/vm/core/evm/evmtest/evm_test.go +++ b/packages/vm/core/evm/evmtest/evm_test.go @@ -1974,3 +1974,14 @@ func TestCustomError(t *testing.T) { require.Len(t, args, 1) require.EqualValues(t, 42, args[0]) } + +func TestEmitEventAndRevert(t *testing.T) { + env := initEVM(t) + ethKey, _ := env.soloChain.NewEthereumAccountWithL2Funds() + iscTest := env.deployISCTestContract(ethKey) + res, err := iscTest.callFn([]ethCallOptions{{ + gasLimit: 100000, + }}, "emitEventAndRevert") + require.ErrorContains(t, err, "execution reverted") + require.Empty(t, res.evmReceipt.Logs) +}