Пример #1
0
    public void Can_suggest_terminal_block_correctly()
    {
        // every block has difficulty 1000000, block 9 TD: 10000000
        TestSpecProvider specProvider = new(London.Instance);

        specProvider.TerminalTotalDifficulty = (UInt256)9999900;
        BlockTreeBuilder treeBuilder = Build.A.BlockTree().OfChainLength(10);
        BlockTree        tree        = new(
            treeBuilder.BlocksDb,
            treeBuilder.HeadersDb,
            treeBuilder.BlockInfoDb,
            treeBuilder.MetadataDb,
            treeBuilder.ChainLevelInfoRepository,
            specProvider,
            NullBloomStorage.Instance,
            new SyncConfig(),
            LimboLogs.Instance);
        PoSSwitcher poSSwitcher = new(new MergeConfig(), new SyncConfig(), new MemDb(), tree, specProvider, LimboLogs.Instance);

        Block?block8 = tree.FindBlock(8, BlockTreeLookupOptions.None);

        Assert.False(block8 !.IsTerminalBlock(specProvider));
        Assert.AreEqual(9, tree.BestKnownNumber);
        Assert.AreEqual(9, tree.BestSuggestedBody !.Number);
        Assert.AreEqual(9, tree.Head !.Number);
        Assert.True(tree.Head.IsTerminalBlock(specProvider));
    }
        public void RunMigration(int?migratedBlockNumber)
        {
            int                    chainLength             = 10;
            IConfigProvider        configProvider          = Substitute.For <IConfigProvider>();
            BlockTreeBuilder       blockTreeBuilder        = Core.Test.Builders.Build.A.BlockTree().OfChainLength(chainLength);
            InMemoryReceiptStorage inMemoryReceiptStorage  = new() { MigratedBlockNumber = migratedBlockNumber != null ? 0 : long.MaxValue };
            InMemoryReceiptStorage outMemoryReceiptStorage = new() { MigratedBlockNumber = migratedBlockNumber != null ? 0 : long.MaxValue };
            NethermindApi          context = new()
            {
                ConfigProvider         = configProvider,
                EthereumJsonSerializer = new EthereumJsonSerializer(),
                LogManager             = LimboLogs.Instance,
                ReceiptStorage         = new TestReceiptStorage(inMemoryReceiptStorage, outMemoryReceiptStorage),
                DbProvider             = Substitute.For <IDbProvider>(),
                BlockTree                = blockTreeBuilder.TestObject,
                Synchronizer             = Substitute.For <ISynchronizer>(),
                ChainLevelInfoRepository = blockTreeBuilder.ChainLevelInfoRepository,
                SyncModeSelector         = Substitute.For <ISyncModeSelector>()
            };

            configProvider.GetConfig <IInitConfig>().StoreReceipts.Returns(true);
            configProvider.GetConfig <IInitConfig>().ReceiptsMigration.Returns(true);
            context.SyncModeSelector.Current.Returns(SyncMode.WaitingForBlock);

            int txIndex = 0;

            for (int i = 1; i < chainLength; i++)
            {
                Block block = context.BlockTree.FindBlock(i);
                inMemoryReceiptStorage.Insert(block, new[] {
                    Core.Test.Builders.Build.A.Receipt.WithTransactionHash(TestItem.Keccaks[txIndex++]).TestObject,
                    Core.Test.Builders.Build.A.Receipt.WithTransactionHash(TestItem.Keccaks[txIndex++]).TestObject
                });
            }

            ManualResetEvent guard           = new(false);
            Keccak           lastTransaction = TestItem.Keccaks[txIndex - 1];

            context.DbProvider.ReceiptsDb.When(x => x.Remove(lastTransaction.Bytes)).Do(c => guard.Set());
            ReceiptMigration migration = new(context);

            if (migratedBlockNumber.HasValue)
            {
                migration.Run(migratedBlockNumber.Value);
            }
            else
            {
                migration.Run();
            }


            guard.WaitOne(TimeSpan.FromSeconds(1));
            int txCount = ((migratedBlockNumber ?? chainLength) - 1 - 1) * 2;

            context.DbProvider.ReceiptsDb.Received(Quantity.Exactly(txCount)).Remove(Arg.Any <byte[]>());
            outMemoryReceiptStorage.Count.Should().Be(txCount);
        }

        private class TestReceiptStorage : IReceiptStorage
        {
Пример #3
0
        public void Can_call_by_hash()
        {
            StateProvider stateProvider = CreateInitialState(null);

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

            BlockTreeBuilder.AddBlock(_blockTree, block);

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

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

            _proofModule.proof_call(tx, new BlockParameter(block.Hash));

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

            Assert.True(response.Contains("\"result\""));
        }
        public void correctly_finalizes_blocks_in_chain(int chainLength, long twoThirdsMajorityTransition, Address[] blockCreators, int notFinalizedExpectedCount)
        {
            _validatorStore.GetValidators(Arg.Any <long?>()).Returns(blockCreators);

            BlockTreeBuilder      blockTreeBuilder = Build.A.BlockTree();
            HashSet <BlockHeader> finalizedBlocks  = new();

            AuRaBlockFinalizationManager finalizationManager = new(blockTreeBuilder.TestObject, blockTreeBuilder.ChainLevelInfoRepository, _blockProcessor, _validatorStore, _validSealerStrategy, _logManager, twoThirdsMajorityTransition);

            finalizationManager.BlocksFinalized += (sender, args) =>
            {
                foreach (BlockHeader block in args.FinalizedBlocks)
                {
                    finalizedBlocks.Add(block);
                }
            };

            blockTreeBuilder.OfChainLength(chainLength, 0, 0, blockCreators);

            int start = 0;

            for (int i = start; i < chainLength; i++)
            {
                Keccak blockHash = blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i).MainChainBlock.BlockHash;
                Block? block     = blockTreeBuilder.TestObject.FindBlock(blockHash, BlockTreeLookupOptions.None);
                _blockProcessor.BlockProcessed += Raise.EventWith(new BlockProcessedEventArgs(block, Array.Empty <TxReceipt>()));
            }

            IEnumerable <bool> isBlockFinalized = Enumerable.Range(start, chainLength).Select(i => blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i).MainChainBlock.IsFinalized);
            IEnumerable <bool> expected         = Enumerable.Range(start, chainLength).Select(i => i < chainLength - notFinalizedExpectedCount);

            finalizedBlocks.Count.Should().Be(chainLength - notFinalizedExpectedCount);
            isBlockFinalized.Should().BeEquivalentTo(expected);
        }
Пример #5
0
        public async Task Can_resync_if_missed_a_block()
        {
            _remoteBlockTree = Build.A.BlockTree(_genesisBlock).OfChainLength(QueueBasedSyncManager.MaxBatchSize).TestObject;
            ISynchronizationPeer peer = new SynchronizationPeerMock(_remoteBlockTree);

            SemaphoreSlim semaphore = new SemaphoreSlim(0);

            _manager.SyncEvent += (sender, args) =>
            {
                if (args.SyncStatus == SyncStatus.Completed || args.SyncStatus == SyncStatus.Failed)
                {
                    semaphore.Release(1);
                }
            };
            _manager.Start();
            Task addPeerTask     = _manager.AddPeer(peer);
            Task firstToComplete = await Task.WhenAny(addPeerTask, Task.Delay(_standardTimeoutUnit));

            Assert.AreSame(addPeerTask, firstToComplete);

            BlockTreeBuilder.ExtendTree(_remoteBlockTree, QueueBasedSyncManager.MaxBatchSize * 2);
            _manager.AddNewBlock(_remoteBlockTree.RetrieveHeadBlock(), peer.NodeId);

            semaphore.Wait(_standardTimeoutUnit);
            semaphore.Wait(_standardTimeoutUnit);

            Assert.AreEqual(QueueBasedSyncManager.MaxBatchSize * 2 - 1, (int)_blockTree.BestSuggested.Number);
        }
Пример #6
0
    private (BlockTree notSyncedTree, BlockTree syncedTree) BuildBlockTrees(
        int notSyncedTreeSize, int syncedTreeSize)
    {
        Block            genesisBlock = Build.A.Block.WithNumber(0).TestObject;
        TestSpecProvider specProvider = new(London.Instance);

        specProvider.TerminalTotalDifficulty = 0;
        ;
        BlockTreeBuilder treeBuilder   = Build.A.BlockTree(genesisBlock, specProvider).OfChainLength(notSyncedTreeSize);
        BlockTree        notSyncedTree = new(
            treeBuilder.BlocksDb,
            treeBuilder.HeadersDb,
            treeBuilder.BlockInfoDb,
            treeBuilder.MetadataDb,
            treeBuilder.ChainLevelInfoRepository,
            MainnetSpecProvider.Instance,
            NullBloomStorage.Instance,
            new SyncConfig(),
            LimboLogs.Instance);

        BlockTreeBuilder syncedTreeBuilder = Build.A.BlockTree(genesisBlock, specProvider).OfChainLength(syncedTreeSize);
        BlockTree        syncedTree        = new(
            syncedTreeBuilder.BlocksDb,
            syncedTreeBuilder.HeadersDb,
            syncedTreeBuilder.BlockInfoDb,
            syncedTreeBuilder.MetadataDb,
            syncedTreeBuilder.ChainLevelInfoRepository,
            specProvider,
            NullBloomStorage.Instance,
            new SyncConfig(),
            LimboLogs.Instance);

        return(notSyncedTree, syncedTree);
    }
        public void correctly_de_finalizes_blocks_on_block_reprocessing(int chainLength, int rerun, int validatorCount, bool twoThirdsMajorityTransition)
        {
            Address[] blockCreators = TestItem.Addresses.Take(validatorCount).ToArray();
            _validatorStore.GetValidators(Arg.Any <long?>()).Returns(blockCreators);

            BlockTreeBuilder             blockTreeBuilder    = Build.A.BlockTree();
            AuRaBlockFinalizationManager finalizationManager = new(
                blockTreeBuilder.TestObject,
                blockTreeBuilder.ChainLevelInfoRepository,
                _blockProcessor,
                _validatorStore,
                _validSealerStrategy,
                _logManager,
                twoThirdsMajorityTransition ? 0 : long.MaxValue);

            blockTreeBuilder.OfChainLength(chainLength, 0, 0, blockCreators);
            FinalizeToLevel(chainLength, blockTreeBuilder.ChainLevelInfoRepository);

            List <Block> blocks = Enumerable.Range(1, rerun)
                                  .Select(i => blockTreeBuilder.TestObject.FindBlock(chainLength - i, BlockTreeLookupOptions.None))
                                  .Reverse()
                                  .ToList();

            _blockProcessor.BlocksProcessing += Raise.EventWith(new BlocksProcessingEventArgs(blocks));

            int majority = (twoThirdsMajorityTransition ? (validatorCount - 1) * 2 / 3 : (validatorCount - 1) / 2) + 1;

            for (int i = 1; i < rerun + majority; i++)
            {
                blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(chainLength - i).MainChainBlock.IsFinalized.Should().BeFalse();
            }

            blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(chainLength - rerun - majority - 1).MainChainBlock.IsFinalized.Should().BeTrue();
        }
Пример #8
0
    public void Suggest_terminal_block_with_lower_number_and_lower_total_difficulty()
    {
        TestSpecProvider specProvider = new(London.Instance);

        specProvider.TerminalTotalDifficulty = (UInt256)9999900;
        BlockTreeBuilder treeBuilder = Build.A.BlockTree().OfChainLength(10);
        BlockTree        tree        = new(
            treeBuilder.BlocksDb,
            treeBuilder.HeadersDb,
            treeBuilder.BlockInfoDb,
            treeBuilder.MetadataDb,
            treeBuilder.ChainLevelInfoRepository,
            specProvider,
            NullBloomStorage.Instance,
            new SyncConfig(),
            LimboLogs.Instance);
        PoSSwitcher poSSwitcher = new(new MergeConfig(), new SyncConfig(), new MemDb(), tree, specProvider, LimboLogs.Instance);

        Block?block7           = tree.FindBlock(7, BlockTreeLookupOptions.None);
        Block newTerminalBlock = Build.A.Block
                                 .WithHeader(Build.A.BlockHeader.WithParent(block7 !.Header).TestObject)
                                 .WithParent(block7 !)
                                 .WithTotalDifficulty((UInt256)9999950)
                                 .WithNumber(block7 !.Number + 1).WithDifficulty(1999950).TestObject;

        // current Head TD: 10000000, block7 TD: 8000000, TTD 9999900, newTerminalBlock 9999950
        tree.SuggestBlock(newTerminalBlock);
        Assert.True(newTerminalBlock.IsTerminalBlock(specProvider));
        Assert.AreEqual(9, tree.BestKnownNumber);
        Assert.AreEqual(9, tree.BestSuggestedBody !.Number);
        Assert.AreEqual(9, tree.Head !.Number);
        Assert.True(tree.Head.IsTerminalBlock(specProvider));
    }
        public void Can_resync_if_missed_a_block()
        {
            _remoteBlockTree = Build.A.BlockTree(_genesisBlock).OfChainLength(SyncBatchSize.Max).TestObject;
            ISyncPeer peer = new SyncPeerMock(_remoteBlockTree);

            SemaphoreSlim semaphore = new SemaphoreSlim(0);

            _synchronizer.SyncEvent += (sender, args) =>
            {
                if (args.SyncEvent == SyncEvent.Completed || args.SyncEvent == SyncEvent.Failed)
                {
                    semaphore.Release(1);
                }
            };
            _pool.Start();
            _synchronizer.Start();
            _pool.AddPeer(peer);

            BlockTreeBuilder.ExtendTree(_remoteBlockTree, SyncBatchSize.Max * 2);
            _syncServer.AddNewBlock(_remoteBlockTree.RetrieveHeadBlock(), peer);

            semaphore.Wait(_standardTimeoutUnit);
            semaphore.Wait(_standardTimeoutUnit);

            Assert.AreEqual(SyncBatchSize.Max * 2 - 1, (int)_blockTree.BestSuggestedHeader.Number);
        }
Пример #10
0
        public void Can_call_by_hash_canonical()
        {
            Block lastHead       = _blockTree.Head;
            Block block          = Build.A.Block.WithParent(lastHead).TestObject;
            Block newBlockOnMain = Build.A.Block.WithParent(lastHead).WithDifficulty(block.Difficulty + 1).TestObject;

            BlockTreeBuilder.AddBlock(_blockTree, block);
            BlockTreeBuilder.AddBlock(_blockTree, newBlockOnMain);

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

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

            EthereumJsonSerializer serializer = new EthereumJsonSerializer();
            string response = RpcTest.TestSerializedRequest(_proofModule, "proof_call", $"{serializer.Serialize(tx)}", $"{{\"blockHash\" : \"{block.Hash}\", \"requireCanonical\" : true}}");

            Assert.True(response.Contains("-32000"));

            response = RpcTest.TestSerializedRequest(_proofModule, "proof_call", $"{serializer.Serialize(tx)}", $"{{\"blockHash\" : \"{TestItem.KeccakG}\", \"requireCanonical\" : true}}");
            Assert.True(response.Contains("-32001"));
        }
        public void correctly_initializes_lastFinalizedBlock()
        {
            BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree().OfChainLength(3, 1, 1);

            FinalizeToLevel(1, blockTreeBuilder.ChainLevelInfoRepository);

            AuRaBlockFinalizationManager finalizationManager = new(blockTreeBuilder.TestObject, blockTreeBuilder.ChainLevelInfoRepository, _blockProcessor, _validatorStore, _validSealerStrategy, _logManager);

            finalizationManager.LastFinalizedBlockLevel.Should().Be(1);
        }
        public void correctly_finalizes_blocks_in_already_in_chain_on_initialize()
        {
            int count = 2;
            BlockTreeBuilder             blockTreeBuilder    = Build.A.BlockTree().OfChainLength(count, 0, 0, TestItem.AddressA, TestItem.AddressB);
            AuRaBlockFinalizationManager finalizationManager = new(blockTreeBuilder.TestObject, blockTreeBuilder.ChainLevelInfoRepository, _blockProcessor, _validatorStore, _validSealerStrategy, _logManager);

            IEnumerable <bool> result = Enumerable.Range(0, count).Select(i => blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i).MainChainBlock.IsFinalized);

            result.Should().BeEquivalentTo(new[] { true, false });
        }
        public long?GetFinalizationLevel_tests(int chainLength, Address[] beneficiaries, int minForFinalization, long level)
        {
            SetupValidators(minForFinalization, beneficiaries);
            BlockTreeBuilder             blockTreeBuilder    = Build.A.BlockTree().OfChainLength(chainLength, 0, 0, beneficiaries);
            BlockTree                    blockTree           = blockTreeBuilder.TestObject;
            AuRaBlockFinalizationManager finalizationManager = new(blockTree, blockTreeBuilder.ChainLevelInfoRepository, _blockProcessor, _validatorStore, _validSealerStrategy, _logManager);

            long?result = finalizationManager.GetFinalizationLevel(level);

            return(result);
        }
Пример #14
0
    public void Cannot_change_best_suggested_to_terminal_block_after_merge_block()
    {
        // every block has difficulty 1000000, block 9 TD: 10000000
        TestSpecProvider specProvider = new(London.Instance);

        specProvider.TerminalTotalDifficulty = (UInt256)9999900;
        BlockTreeBuilder treeBuilder = Build.A.BlockTree().OfChainLength(10);
        BlockTree        tree        = new(
            treeBuilder.BlocksDb,
            treeBuilder.HeadersDb,
            treeBuilder.BlockInfoDb,
            treeBuilder.MetadataDb,
            treeBuilder.ChainLevelInfoRepository,
            specProvider,
            NullBloomStorage.Instance,
            new SyncConfig(),
            LimboLogs.Instance);
        PoSSwitcher poSSwitcher = new(new MergeConfig(), new SyncConfig(), new MemDb(), tree, specProvider, LimboLogs.Instance);

        Block?block8 = tree.FindBlock(8, BlockTreeLookupOptions.None);

        Assert.False(block8 !.Header.IsTerminalBlock(specProvider));
        Assert.AreEqual(9, tree.BestKnownNumber);
        Assert.AreEqual(9, tree.BestSuggestedBody !.Number);
        Assert.AreEqual(9, tree.Head !.Number);
        Assert.True(tree.Head.IsTerminalBlock(specProvider));

        Block firstPoSBlock = Build.A.Block
                              .WithHeader(Build.A.BlockHeader.WithParent(tree.Head !.Header).TestObject)
                              .WithParent(tree.Head.Header)
                              .WithDifficulty(0)
                              .WithNumber(tree.Head !.Number + 1).TestObject;

        tree.SuggestBlock(firstPoSBlock);
        tree.UpdateMainChain(new[] { firstPoSBlock }, true, true); // simulating fcU
        Assert.AreEqual(10, tree.BestKnownNumber);
        Assert.AreEqual(10, tree.BestSuggestedBody !.Number);

        Block newTerminalBlock = Build.A.Block
                                 .WithHeader(Build.A.BlockHeader.WithParent(block8 !.Header).TestObject)
                                 .WithParent(block8 !)
                                 .WithTotalDifficulty((UInt256)10000001)
                                 .WithNumber(block8 !.Number + 1).WithDifficulty(2000001).TestObject;

        Assert.True(newTerminalBlock.IsTerminalBlock(specProvider));
        tree.SuggestBlock(newTerminalBlock);
        Assert.AreEqual(10, tree.BestKnownNumber);
        Assert.AreEqual(10, tree.BestSuggestedBody !.Number);
    }
Пример #15
0
        public async Task Can_resync_if_missed_a_block()
        {
            _remoteBlockTree = Build.A.BlockTree(_genesisBlock).OfChainLength(SynchronizationManager.BatchSize).TestObject;
            ISynchronizationPeer peer = new SynchronizationPeerMock(_remoteBlockTree);

            ManualResetEvent resetEvent = new ManualResetEvent(false);

            _manager.SyncEvent += (sender, args) => { resetEvent.Set(); };
            Task addPeerTask     = _manager.AddPeer(peer);
            Task firstToComplete = await Task.WhenAny(addPeerTask, Task.Delay(2000));

            Assert.AreSame(addPeerTask, firstToComplete);
            _manager.Start();
            resetEvent.WaitOne(TimeSpan.FromMilliseconds(2000));

            BlockTreeBuilder.ExtendTree(_remoteBlockTree, SynchronizationManager.BatchSize * 2);
            _manager.AddNewBlock(_remoteBlockTree.RetrieveHeadBlock(), peer.NodeId);

            Assert.AreEqual(SynchronizationManager.BatchSize * 2 - 1, (int)_blockTree.BestSuggested.Number);
        }
Пример #16
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);
        }
Пример #17
0
    public void Can_build_correct_block_tree()
    {
        Block            genesisBlock = Build.A.Block.WithNumber(0).TestObject;
        TestSpecProvider specProvider = new(London.Instance);

        specProvider.TerminalTotalDifficulty = 0;
        BlockTreeBuilder treeBuilder = Build.A.BlockTree(genesisBlock, specProvider).OfChainLength(10);
        BlockTree        tree        = new(
            treeBuilder.BlocksDb,
            treeBuilder.HeadersDb,
            treeBuilder.BlockInfoDb,
            treeBuilder.MetadataDb,
            treeBuilder.ChainLevelInfoRepository,
            MainnetSpecProvider.Instance,
            NullBloomStorage.Instance,
            new SyncConfig(),
            LimboLogs.Instance);

        Assert.AreEqual(9, tree.BestKnownNumber);
        Assert.AreEqual(9, tree.BestSuggestedBody !.Number);
        Assert.AreEqual(9, tree.Head !.Number);
    }
        public int[] correctly_finalizes_blocks_on_reorganisations(int validators, int chainLength)
        {
            _validatorStore.GetValidators(Arg.Any <long?>()).Returns(TestItem.Addresses.Take(validators).ToArray());

            void ProcessBlock(BlockTreeBuilder blockTreeBuilder1, int level, int index)
            {
                Keccak blockHash = blockTreeBuilder1.ChainLevelInfoRepository.LoadLevel(level).BlockInfos[index].BlockHash;
                Block? block     = blockTreeBuilder1.TestObject.FindBlock(blockHash, BlockTreeLookupOptions.None);

                _blockProcessor.BlockProcessed += Raise.EventWith(new BlockProcessedEventArgs(block, Array.Empty <TxReceipt>()));
            }

            Block            genesis          = Build.A.Block.Genesis.TestObject;
            BlockTreeBuilder blockTreeBuilder = Build.A.BlockTree(genesis);

            AuRaBlockFinalizationManager finalizationManager = new(blockTreeBuilder.TestObject, blockTreeBuilder.ChainLevelInfoRepository, _blockProcessor, _validatorStore, _validSealerStrategy, _logManager);

            blockTreeBuilder
            .OfChainLength(out Block headBlock, chainLength, 1, 0, TestItem.Addresses.Take(validators).ToArray())
            .OfChainLength(out Block alternativeHeadBlock, chainLength, 0, splitFrom: 2, TestItem.Addresses.Skip(validators).Take(validators).ToArray());

            for (int i = 0; i < chainLength - 1; i++)
            {
                ProcessBlock(blockTreeBuilder, i, 0);
            }

            for (int i = 1; i < chainLength - 1; i++)
            {
                ProcessBlock(blockTreeBuilder, i, 1);
            }

            ProcessBlock(blockTreeBuilder, chainLength - 1, 0);

            int[] finalizedBLocks = Enumerable.Range(0, chainLength)
                                    .Select(i => blockTreeBuilder.ChainLevelInfoRepository.LoadLevel(i).BlockInfos.Select((b, j) => b.IsFinalized ? j + 1 : 0).Sum())
                                    .ToArray();
            return(finalizedBLocks);
        }
Пример #19
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\""));
        }