コード例 #1
0
 public void Can_call_with_just_basic_addresses()
 {
     _specProvider.SpecToReturn = MuirGlacier.Instance;
     byte[] code = Prepare.EvmCode
         .Op(Instruction.STOP)
         .Done;
     CallResultWithProof result = TestCallWithCode(code);
     Assert.AreEqual(1 + (_useNonZeroGasPrice ? 1 : 0), result.Accounts.Length);
 }
コード例 #2
0
 public void Can_call_with_extcodesize_to_system_account()
 {
     byte[] code = Prepare.EvmCode
         .PushData(Address.SystemUser)
         .Op(Instruction.EXTCODESIZE)
         .Done;
     CallResultWithProof result = TestCallWithCode(code);
     Assert.AreEqual(2, result.Accounts.Length);
 }
コード例 #3
0
 public void Can_call_with_extcodesize()
 {
     byte[] code = Prepare.EvmCode
         .PushData(TestItem.AddressC)
         .Op(Instruction.EXTCODESIZE)
         .Done;
     CallResultWithProof result = TestCallWithCode(code);
     Assert.AreEqual(2 + (_useNonZeroGasPrice ? 1 : 0), result.Accounts.Length);
 }
コード例 #4
0
 public void Can_call_with_block_hashes()
 {
     byte[] code = Prepare.EvmCode
         .PushData("0x01")
         .Op(Instruction.BLOCKHASH)
         .Done;
     CallResultWithProof result = TestCallWithCode(code);
     Assert.AreEqual(2, result.BlockHeaders.Length);
 }
コード例 #5
0
 public void Can_call_with_self_destruct_to_system_account()
 {
     _specProvider.SpecToReturn = MuirGlacier.Instance;
     byte[] code = Prepare.EvmCode
         .PushData(Address.SystemUser)
         .Op(Instruction.SELFDESTRUCT)
         .Done;
     CallResultWithProof result = TestCallWithCode(code);
     Assert.AreEqual(2, result.Accounts.Length);
 }
コード例 #6
0
 public void Can_call_with_extcodehash()
 {
     _specProvider.SpecToReturn = MuirGlacier.Instance;
     byte[] code = Prepare.EvmCode
         .PushData(TestItem.AddressC)
         .Op(Instruction.EXTCODEHASH)
         .Done;
     CallResultWithProof result = TestCallWithCode(code);
     Assert.AreEqual(2 + (_useNonZeroGasPrice ? 1 : 0), result.Accounts.Length);
 }
コード例 #7
0
        public void Can_call_with_storage_load()
        {
            byte[] code = Prepare.EvmCode
                .PushData("0x01")
                .Op(Instruction.SLOAD)
                .Done;

            CallResultWithProof result = TestCallWithCode(code);
            Assert.AreEqual(1 + (_useNonZeroGasPrice ? 1 : 0), result.Accounts.Length);
        }
コード例 #8
0
 public void Can_call_with_delegate_call()
 {
     _specProvider.SpecToReturn = MuirGlacier.Instance;
     byte[] code = Prepare.EvmCode
         .PushData(0)
         .PushData(0)
         .PushData(0)
         .PushData(0)
         .PushData(TestItem.AddressC)
         .PushData(1000000)
         .Op(Instruction.DELEGATECALL)
         .Done;
     CallResultWithProof result = TestCallWithCode(code);
     Assert.AreEqual(3, result.Accounts.Length);
 }
コード例 #9
0
 public void Can_call_with_call_to_system_account_with_non_zero_value()
 {
     _specProvider.SpecToReturn = MuirGlacier.Instance;
     byte[] code = Prepare.EvmCode
         .PushData(0)
         .PushData(0)
         .PushData(0)
         .PushData(0)
         .PushData(1)
         .PushData(Address.SystemUser)
         .PushData(1000000)
         .Op(Instruction.CALL)
         .Done;
     CallResultWithProof result = TestCallWithCode(code);
     Assert.AreEqual(2, result.Accounts.Length);
 }
コード例 #10
0
        private CallResultWithProof TestCallWithCode(byte[] code, Address from = null)
        {
            StateProvider stateProvider = CreateInitialState(code);

            Keccak root  = stateProvider.StateRoot;
            Block  block = Build.A.Block.WithParent(_blockTree.Head).WithStateRoot(root).WithBeneficiary(TestItem.AddressD).TestObject;

            BlockTreeBuilder.AddBlock(_blockTree, block);
            Block blockOnTop = Build.A.Block.WithParent(block).WithStateRoot(root).WithBeneficiary(TestItem.AddressD).TestObject;

            BlockTreeBuilder.AddBlock(_blockTree, blockOnTop);

            // would need to setup state root somehow...

            TransactionForRpc tx = new TransactionForRpc
            {
                From     = from,
                To       = TestItem.AddressB,
                GasPrice = _useNonZeroGasPrice ? 10.GWei() : 0
            };

            CallResultWithProof callResultWithProof = _proofModule.proof_call(tx, new BlockParameter(blockOnTop.Number)).Data;

            Assert.Greater(callResultWithProof.Accounts.Length, 0);

            foreach (AccountProof accountProof in callResultWithProof.Accounts)
            {
                ProofVerifier.Verify(accountProof.Proof, block.StateRoot);
                foreach (StorageProof storageProof in accountProof.StorageProofs)
                {
                    ProofVerifier.Verify(storageProof.Proof, accountProof.StorageRoot);
                }
            }

            EthereumJsonSerializer serializer = new EthereumJsonSerializer();
            string response = RpcTest.TestSerializedRequest(_proofModule, "proof_call", $"{serializer.Serialize(tx)}", $"{blockOnTop.Number}");

            Assert.True(response.Contains("\"result\""));

            return(callResultWithProof);
        }
コード例 #11
0
        private void TestCallWithStorageAndCode(byte[] code, UInt256 gasPrice, Address from = null)
        {
            StateProvider   stateProvider   = CreateInitialState(code);
            StorageProvider storageProvider = new StorageProvider(new TrieStore(_dbProvider.StateDb, LimboLogs.Instance), stateProvider, LimboLogs.Instance);

            for (int i = 0; i < 10000; i++)
            {
                storageProvider.Set(new StorageCell(TestItem.AddressB, (UInt256)i), i.ToBigEndianByteArray());
            }

            storageProvider.Commit();
            storageProvider.CommitTrees(0);

            stateProvider.Commit(MainnetSpecProvider.Instance.GenesisSpec, null);
            stateProvider.CommitTree(0);

            Keccak root = stateProvider.StateRoot;

            Block block = Build.A.Block.WithParent(_blockTree.Head).WithStateRoot(root).TestObject;

            BlockTreeBuilder.AddBlock(_blockTree, block);
            Block blockOnTop = Build.A.Block.WithParent(block).WithStateRoot(root).TestObject;

            BlockTreeBuilder.AddBlock(_blockTree, blockOnTop);

            // would need to setup state root somehow...

            TransactionForRpc tx = new TransactionForRpc
            {
                // we are testing system transaction here when From is null
                From     = from,
                To       = TestItem.AddressB,
                GasPrice = gasPrice,
                Nonce    = 1000
            };

            CallResultWithProof callResultWithProof = _proofModule.proof_call(tx, new BlockParameter(blockOnTop.Number)).Data;

            Assert.Greater(callResultWithProof.Accounts.Length, 0);

            // just the keys for debugging
            Span <byte> span = stackalloc byte[32];

            new UInt256(0).ToBigEndian(span);
            Keccak k0 = Keccak.Compute(span);

            // just the keys for debugging
            new UInt256(1).ToBigEndian(span);
            Keccak k1 = Keccak.Compute(span);

            // just the keys for debugging
            new UInt256(2).ToBigEndian(span);
            Keccak k2 = Keccak.Compute(span);

            foreach (AccountProof accountProof in callResultWithProof.Accounts)
            {
                // this is here for diagnostics - so you can read what happens in the test
                // generally the account here should be consistent with the values inside the proof
                // the exception will be thrown if the account did not exist before the call
                Account account;
                try
                {
                    account = new AccountDecoder().Decode(new RlpStream(ProofVerifier.Verify(accountProof.Proof, block.StateRoot)));
                }
                catch (Exception)
                {
                    // ignored
                }

                foreach (StorageProof storageProof in accountProof.StorageProofs)
                {
                    // we read the values here just to allow easier debugging so you can confirm that the value is same as the one in the proof and in the trie
                    byte[] value = ProofVerifier.Verify(storageProof.Proof, accountProof.StorageRoot);
                }
            }

            EthereumJsonSerializer serializer = new EthereumJsonSerializer();
            string response = RpcTest.TestSerializedRequest(_proofModule, "proof_call", $"{serializer.Serialize(tx)}", $"{blockOnTop.Number}");

            Assert.True(response.Contains("\"result\""));
        }