Exemplo n.º 1
0
        public void Best_suggested_block_gets_updated()
        {
            BlockTree blockTree = BuildBlockTree();
            Block     block0    = Build.A.Block.WithNumber(0).WithDifficulty(1).TestObject;
            Block     block1    = Build.A.Block.WithNumber(1).WithDifficulty(2).WithParent(block0).TestObject;

            AddToMain(blockTree, block0);
            blockTree.SuggestBlock(block1);

            Assert.AreEqual(block0.Hash, BlockHeader.CalculateHash(blockTree.Head), "head block");
            Assert.AreEqual(block1.Hash, BlockHeader.CalculateHash(blockTree.BestSuggested), "best suggested");
        }
Exemplo n.º 2
0
        public async Task <Block> SealBlock(Block processed, CancellationToken cancellationToken)
        {
            Block sealedBlock = Seal(processed);

            if (sealedBlock == null)
            {
                return(null);
            }

            sealedBlock.Hash = BlockHeader.CalculateHash(sealedBlock.Header);
            return(await Task.FromResult(sealedBlock));
        }
Exemplo n.º 3
0
        private Block CreateBlock(int splitVariant, int splitFrom, int blockIndex, Block parent, Address beneficiary)
        {
            Block current;

            if (_receiptStorage != null && blockIndex % 3 == 0)
            {
                Transaction[] transactions = new[]
                {
                    Build.A.Transaction.WithValue(1).WithData(Rlp.Encode(blockIndex).Bytes).Signed(_ecdsa, TestItem.PrivateKeyA, blockIndex + 1).TestObject,
                    Build.A.Transaction.WithValue(2).WithData(Rlp.Encode(blockIndex + 1).Bytes).Signed(_ecdsa, TestItem.PrivateKeyA, blockIndex + 1).TestObject
                };

                current = Build.A.Block
                          .WithNumber(blockIndex + 1)
                          .WithParent(parent)
                          .WithDifficulty(BlockHeaderBuilder.DefaultDifficulty - (splitFrom > parent.Number ? 0 : (ulong)splitVariant))
                          .WithTransactions(transactions)
                          .WithBloom(new Bloom())
                          .WithBeneficiary(beneficiary)
                          .TestObject;

                List <TxReceipt> receipts = new List <TxReceipt>();
                foreach (var transaction in current.Transactions)
                {
                    var       logEntries = _logCreationFunction?.Invoke(current, transaction)?.ToArray() ?? Array.Empty <LogEntry>();
                    TxReceipt receipt    = new TxReceipt
                    {
                        Logs   = logEntries,
                        TxHash = transaction.Hash,
                        Bloom  = new Bloom(logEntries)
                    };
                    _receiptStorage.Add(receipt, false);
                    receipts.Add(receipt);
                    current.Bloom.Add(receipt.Logs);
                }

                current.Header.TxRoot       = current.CalculateTxRoot();
                current.Header.ReceiptsRoot = current.CalculateReceiptRoot(_specProvider, receipts.ToArray());
                current.Hash = BlockHeader.CalculateHash(current);
            }
            else
            {
                current = Build.A.Block.WithNumber(blockIndex + 1)
                          .WithParent(parent)
                          .WithDifficulty(BlockHeaderBuilder.DefaultDifficulty - (splitFrom > parent.Number ? 0 : (ulong)splitVariant))
                          .WithBeneficiary(beneficiary)
                          .TestObject;
            }

            current.Header.AuRaStep = blockIndex;

            return(current);
        }
Exemplo n.º 4
0
        public ResultWrapper <CallResultWithProof> proof_call(TransactionForRpc tx, BlockParameter blockParameter)
        {
            SearchResult <BlockHeader> searchResult = _blockFinder.SearchForHeader(blockParameter);

            if (searchResult.IsError)
            {
                return(ResultWrapper <CallResultWithProof> .Fail(searchResult));
            }

            BlockHeader sourceHeader = searchResult.Object;
            BlockHeader callHeader   = new BlockHeader(
                sourceHeader.Hash,
                Keccak.OfAnEmptySequenceRlp,
                Address.Zero,
                0,
                sourceHeader.Number + 1,
                sourceHeader.GasLimit,
                sourceHeader.Timestamp,
                Array.Empty <byte>());

            callHeader.TxRoot          = Keccak.EmptyTreeHash;
            callHeader.ReceiptsRoot    = Keccak.EmptyTreeHash;
            callHeader.Author          = Address.SystemUser;
            callHeader.TotalDifficulty = sourceHeader.TotalDifficulty + callHeader.Difficulty;
            callHeader.Hash            = callHeader.CalculateHash();

            Transaction transaction = tx.ToTransaction();

            transaction.SenderAddress ??= Address.SystemUser;

            if (transaction.GasLimit == 0)
            {
                transaction.GasLimit = callHeader.GasLimit;
            }

            Block block = new Block(callHeader, new[] { transaction }, Enumerable.Empty <BlockHeader>());

            ProofBlockTracer proofBlockTracer = new ProofBlockTracer(null, transaction.SenderAddress == Address.SystemUser);

            _tracer.Trace(block, proofBlockTracer);

            CallResultWithProof callResultWithProof = new CallResultWithProof();
            ProofTxTracer       proofTxTracer       = proofBlockTracer.BuildResult().Single();

            callResultWithProof.BlockHeaders = CollectHeaderBytes(proofTxTracer, sourceHeader);
            callResultWithProof.Result       = proofTxTracer.Output;

            // we collect proofs from before execution (after learning which addresses will be touched)
            // if we wanted to collect post execution proofs then we would need to use BeforeRestore on the tracer
            callResultWithProof.Accounts = CollectAccountProofs(sourceHeader.StateRoot, proofTxTracer);

            return(ResultWrapper <CallResultWithProof> .Success(callResultWithProof));
        }
Exemplo n.º 5
0
        public void Best_suggested_block_gets_updated()
        {
            BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance);
            Block     block0    = Build.A.Block.WithNumber(0).WithDifficulty(1).TestObject;
            Block     block1    = Build.A.Block.WithNumber(1).WithDifficulty(2).WithParent(block0).TestObject;

            AddToMain(blockTree, block0);
            blockTree.SuggestBlock(block1);

            Assert.AreEqual(block0.Hash, BlockHeader.CalculateHash(blockTree.Head), "head block");
            Assert.AreEqual(block1.Hash, BlockHeader.CalculateHash(blockTree.BestSuggested), "best suggested");
        }
Exemplo n.º 6
0
        public static Keccak CalculateCliqueHeaderHash(BlockHeader blockHeader)
        {
            int extraSeal        = 65;
            int shortExtraLength = blockHeader.ExtraData.Length - extraSeal;

            byte[] fullExtraData  = blockHeader.ExtraData;
            byte[] shortExtraData = blockHeader.ExtraData.Slice(0, shortExtraLength);
            blockHeader.ExtraData = shortExtraData;
            Keccak sigHash = BlockHeader.CalculateHash(blockHeader);

            blockHeader.ExtraData = fullExtraData;
            return(sigHash);
        }
Exemplo n.º 7
0
        public bool ValidateHash(BlockHeader header)
        {
            bool hashAsExpected = header.Hash == BlockHeader.CalculateHash(header);

            if (!hashAsExpected)
            {
                if (_logger.IsWarn)
                {
                    _logger.Warn($"Invalid block header ({header.Hash}) - invalid block hash");
                }
            }

            return(hashAsExpected);
        }
Exemplo n.º 8
0
        private static void LoadGenesisBlock(
            ChainSpec chainSpec,
            Keccak expectedGenesisHash,
            IBlockTree blockTree,
            IStateProvider stateProvider,
            ISpecProvider specProvider)
        {
            // if we already have a database with blocks then we do not need to load genesis from spec
            if (blockTree.Genesis != null)
            {
                return;
            }

            foreach (KeyValuePair <Address, UInt256> allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value);
            }

            stateProvider.Commit(specProvider.GenesisSpec);

            Block genesis = chainSpec.Genesis;

            genesis.StateRoot = stateProvider.StateRoot;
            genesis.Hash      = BlockHeader.CalculateHash(genesis.Header);

            ManualResetEventSlim genesisProcessedEvent = new ManualResetEventSlim(false);

            bool genesisLoaded = false;

            void GenesisProcessed(object sender, BlockEventArgs args)
            {
                genesisLoaded           = true;
                blockTree.NewHeadBlock -= GenesisProcessed;
                genesisProcessedEvent.Set();
            }

            blockTree.NewHeadBlock += GenesisProcessed;
            blockTree.SuggestBlock(genesis);
            genesisProcessedEvent.Wait(TimeSpan.FromSeconds(5));
            if (!genesisLoaded)
            {
                throw new BlockchainException("Genesis block processing failure");
            }

            // if expectedGenesisHash is null here then it means that we do not care about the exact value in advance (e.g. in test scenarios)
            if (expectedGenesisHash != null && blockTree.Genesis.Hash != expectedGenesisHash)
            {
                throw new Exception($"Unexpected genesis hash, expected {expectedGenesisHash}, but was {blockTree.Genesis.Hash}");
            }
        }
Exemplo n.º 9
0
        public void Stores_multiple_blocks_per_level()
        {
            BlockTree blockTree = BuildBlockTree();
            Block     block0    = Build.A.Block.WithNumber(0).WithDifficulty(1).TestObject;
            Block     block1    = Build.A.Block.WithNumber(1).WithDifficulty(2).WithParent(block0).TestObject;
            Block     block1B   = Build.A.Block.WithNumber(1).WithDifficulty(3).WithParent(block0).TestObject;

            AddToMain(blockTree, block0);
            AddToMain(blockTree, block1);
            blockTree.SuggestBlock(block1B);

            Block found = blockTree.FindBlock(block1B.Hash, false);

            Assert.AreEqual(block1B.Hash, BlockHeader.CalculateHash(found.Header));
        }
Exemplo n.º 10
0
        public void Find_by_number_basic()
        {
            BlockTree blockTree = BuildBlockTree();
            Block     block0    = Build.A.Block.WithNumber(0).TestObject;
            Block     block1    = Build.A.Block.WithNumber(1).WithParent(block0).TestObject;
            Block     block2    = Build.A.Block.WithNumber(2).WithParent(block1).TestObject;

            AddToMain(blockTree, block0);
            AddToMain(blockTree, block1);
            AddToMain(blockTree, block2);

            Block found = blockTree.FindBlock(2);

            Assert.AreEqual(block2.Hash, BlockHeader.CalculateHash(found.Header));
        }
Exemplo n.º 11
0
        public void Can_decode()
        {
            BlockHeader header = Build.A.BlockHeader
                                 .WithMixHash(Keccak.Compute("mix_hash"))
                                 .WithNonce(1000)
                                 .TestObject;

            HeaderDecoder decoder = new HeaderDecoder();
            Rlp           rlp     = decoder.Encode(header);
            BlockHeader   decoded = decoder.Decode(new Rlp.ValueDecoderContext(rlp.Bytes));

            decoded.Hash = BlockHeader.CalculateHash(decoded);

            Assert.AreEqual(header.Hash, decoded.Hash, "hash");
        }
Exemplo n.º 12
0
        public void Stores_multiple_blocks_per_level()
        {
            BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance);
            Block     block0    = Build.A.Block.WithNumber(0).WithDifficulty(1).TestObject;
            Block     block1    = Build.A.Block.WithNumber(1).WithDifficulty(2).WithParent(block0).TestObject;
            Block     block1B   = Build.A.Block.WithNumber(1).WithDifficulty(3).WithParent(block0).TestObject;

            AddToMain(blockTree, block0);
            AddToMain(blockTree, block1);
            blockTree.SuggestBlock(block1B);

            Block found = blockTree.FindBlock(block1B.Hash, false);

            Assert.AreEqual(block1B.Hash, BlockHeader.CalculateHash(found.Header));
        }
Exemplo n.º 13
0
        public void Find_by_number_basic()
        {
            BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance);
            Block     block0    = Build.A.Block.WithNumber(0).TestObject;
            Block     block1    = Build.A.Block.WithNumber(1).WithParent(block0).TestObject;
            Block     block2    = Build.A.Block.WithNumber(2).WithParent(block1).TestObject;

            AddToMain(blockTree, block0);
            AddToMain(blockTree, block1);
            AddToMain(blockTree, block2);

            Block found = blockTree.FindBlock(2);

            Assert.AreEqual(block2.Hash, BlockHeader.CalculateHash(found.Header));
        }
Exemplo n.º 14
0
        private Block ProcessOne(Block suggestedBlock, ProcessingOptions options, IBlockTracer blockTracer)
        {
            if (suggestedBlock.IsGenesis)
            {
                return(suggestedBlock);
            }

            if (_specProvider.DaoBlockNumber.HasValue && _specProvider.DaoBlockNumber.Value == suggestedBlock.Header.Number)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info("Applying DAO transition");
                }
                ApplyDaoTransition();
            }

            Block block    = PrepareBlockForProcessing(suggestedBlock);
            var   receipts = ProcessTransactions(block, options, blockTracer);

            SetReceiptsRootAndBloom(block, receipts);
            ApplyMinerRewards(block, blockTracer);

            _stateProvider.Commit(_specProvider.GetSpec(block.Number));

            block.Header.StateRoot = _stateProvider.StateRoot;
            block.Header.Hash      = BlockHeader.CalculateHash(block.Header);
            if ((options & ProcessingOptions.NoValidation) == 0 && !_blockValidator.ValidateProcessedBlock(block, receipts, suggestedBlock))
            {
                if (_logger.IsError)
                {
                    _logger.Error($"Processed block is not valid {suggestedBlock.ToString(Block.Format.FullHashAndNumber)}");
                }
                throw new InvalidBlockException(suggestedBlock.Hash);
            }

            if ((options & ProcessingOptions.StoreReceipts) != 0)
            {
                StoreTxReceipts(block, receipts);
            }

            if ((options & ProcessingOptions.StoreTraces) != 0)
            {
                StoreTraces(blockTracer as ParityLikeBlockTracer);
            }

            BlockProcessed?.Invoke(this, new BlockProcessedEventArgs(block));
            return(block);
        }
Exemplo n.º 15
0
        public void Find_sequence_basic_skip()
        {
            BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance);
            Block     block0    = Build.A.Block.WithNumber(0).TestObject;
            Block     block1    = Build.A.Block.WithNumber(1).WithParent(block0).TestObject;
            Block     block2    = Build.A.Block.WithNumber(2).WithParent(block1).TestObject;

            AddToMain(blockTree, block0);
            AddToMain(blockTree, block1);
            AddToMain(blockTree, block2);

            Block[] blocks = blockTree.FindBlocks(block0.Hash, 2, 1, false);
            Assert.AreEqual(2, blocks.Length, "length");
            Assert.AreEqual(block0.Hash, BlockHeader.CalculateHash(blocks[0].Header));
            Assert.AreEqual(block2.Hash, BlockHeader.CalculateHash(blocks[1].Header));
        }
Exemplo n.º 16
0
        public void Find_sequence_basic_skip()
        {
            BlockTree blockTree = BuildBlockTree();
            Block     block0    = Build.A.Block.WithNumber(0).TestObject;
            Block     block1    = Build.A.Block.WithNumber(1).WithParent(block0).TestObject;
            Block     block2    = Build.A.Block.WithNumber(2).WithParent(block1).TestObject;

            AddToMain(blockTree, block0);
            AddToMain(blockTree, block1);
            AddToMain(blockTree, block2);

            Block[] blocks = blockTree.FindBlocks(block0.Hash, 2, 1, false);
            Assert.AreEqual(2, blocks.Length, "length");
            Assert.AreEqual(block0.Hash, BlockHeader.CalculateHash(blocks[0].Header));
            Assert.AreEqual(block2.Hash, BlockHeader.CalculateHash(blocks[1].Header));
        }
Exemplo n.º 17
0
        public async Task seal_can_recover_address()
        {
            _auRaStepCalculator.CurrentStep.Returns(11);
            _auRaValidator.IsValidSealer(_address, 11).Returns(true);
            var block = Build.A.Block.WithHeader(Build.A.BlockHeader.WithBeneficiary(_address).WithAura(11, null).TestObject).TestObject;

            block = await _auRaSealer.SealBlock(block, CancellationToken.None);

            var ecdsa     = new EthereumEcdsa(new MordenSpecProvider(), NullLogManager.Instance);
            var signature = new Signature(block.Header.AuRaSignature);

            signature.V += Signature.VOffset;
            var recoveredAddress = ecdsa.RecoverAddress(signature, BlockHeader.CalculateHash(block.Header, RlpBehaviors.ForSealing));

            recoveredAddress.Should().Be(_address);
        }
Exemplo n.º 18
0
        public void Can_decode_aura()
        {
            var auRaSignature = new byte[64];

            new Random().NextBytes(auRaSignature);
            BlockHeader header = Build.A.BlockHeader
                                 .WithAura(100000000, auRaSignature)
                                 .TestObject;

            HeaderDecoder decoder = new HeaderDecoder();
            Rlp           rlp     = decoder.Encode(header);
            BlockHeader   decoded = decoder.Decode(new Rlp.ValueDecoderContext(rlp.Bytes));

            decoded.Hash = BlockHeader.CalculateHash(decoded);

            Assert.AreEqual(header.Hash, decoded.Hash, "hash");
        }
Exemplo n.º 19
0
        public void Find_sequence_reverse()
        {
            BlockTree blockTree = BuildBlockTree();
            Block     block0    = Build.A.Block.WithNumber(0).TestObject;
            Block     block1    = Build.A.Block.WithNumber(1).WithParent(block0).TestObject;
            Block     block2    = Build.A.Block.WithNumber(2).WithParent(block1).TestObject;

            AddToMain(blockTree, block0);
            AddToMain(blockTree, block1);
            AddToMain(blockTree, block2);

            Block[] blocks = blockTree.FindBlocks(block2.Hash, 3, 0, true);
            Assert.AreEqual(3, blocks.Length);

            Assert.AreEqual(block2.Hash, BlockHeader.CalculateHash(blocks[0].Header));
            Assert.AreEqual(block0.Hash, BlockHeader.CalculateHash(blocks[2].Header));
        }
Exemplo n.º 20
0
        public bool validate_seal(long blockNumber, Address signedAddress, Address recoveredAddress)
        {
            signedAddress ??= _address;
            recoveredAddress ??= _address;

            var block = Build.A.BlockHeader
                        .WithAura(10, Bytes.Empty)
                        .WithBeneficiary(_address)
                        .WithNumber(blockNumber)
                        .TestObject;

            var hash = BlockHeader.CalculateHash(block, RlpBehaviors.ForSealing);

            block.AuRaSignature = _wallet.Sign(hash, signedAddress).BytesWithRecovery;
            _ethereumEcdsa.RecoverAddress(Arg.Any <Signature>(), hash).Returns(recoveredAddress);

            return(_sealValidator.ValidateSeal(block));
        }
Exemplo n.º 21
0
        private Block Seal(Block block)
        {
            // Bail out if we're unauthorized to sign a block
            if (!CanSeal(block.Number, block.ParentHash))
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"Not authorized to seal the block {block.ToString(Block.Format.Short)}");
                }
                return(null);
            }

            var headerHash = BlockHeader.CalculateHash(block.Header, RlpBehaviors.ForSealing);
            var signature  = _wallet.Sign(headerHash, _nodeAddress);

            block.Header.AuRaSignature = signature.BytesWithRecovery;

            return(block);
        }
Exemplo n.º 22
0
        private Block CreateBlock(int blockDifficulty, int blockNumber, Block lastBlock)
        {
            Keccak  parentHash  = lastBlock.Hash;
            Keccak  ommersHash  = Keccak.OfAnEmptySequenceRlp;
            Address beneficiary = Address.Zero;
            UInt256 difficulty  = new UInt256(blockDifficulty);
            long    number      = blockNumber;
            int     gasLimit    = 4700000;
            UInt256 timestamp   = new UInt256(DateTimeOffset.UtcNow.ToUnixTimeSeconds());

            byte[]      extraData = Bytes.FromHexString("d883010812846765746888676f312e31312e31856c696e75780000000000000028eb026ab5355b45499053382886754f1db544618d45edc979de1864d83a626b77513bd34d7f21059e79e303c3ab210e1424e71bcb8347835cbd378a785a06f800");
            BlockHeader header    = new BlockHeader(parentHash, ommersHash, beneficiary, difficulty, number, gasLimit, timestamp, extraData);

            header.MixHash = Keccak.Zero;
            Block block = new Block(header, new BlockHeader[0]);

            block.Hash        = BlockHeader.CalculateHash(block);
            block.Header.Hash = BlockHeader.CalculateHash(block.Header);
            return(block);
        }
Exemplo n.º 23
0
        private Block GetRinkebyGenesis()
        {
            Keccak  parentHash  = Keccak.Zero;
            Keccak  ommersHash  = Keccak.OfAnEmptySequenceRlp;
            Address beneficiary = Address.Zero;
            UInt256 difficulty  = new UInt256(1);
            long    number      = 0L;
            int     gasLimit    = 4700000;
            UInt256 timestamp   = new UInt256(1492009146);

            byte[]      extraData = Bytes.FromHexString(GetGenesisExtraData());
            BlockHeader header    = new BlockHeader(parentHash, ommersHash, beneficiary, difficulty, number, gasLimit, timestamp, extraData);
            Block       genesis   = new Block(header, new BlockHeader[0]);

            genesis.Hash = BlockHeader.CalculateHash(genesis);

            // this would need to be loaded from rinkeby chainspec to include allocations
//            Assert.AreEqual(new Keccak("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177"), genesis.Hash);

            genesis.Header.Hash = BlockHeader.CalculateHash(genesis.Header);
            return(genesis);
        }
Exemplo n.º 24
0
        public async Task Find_nonce()
        {
            BlockHeader parentHeader = new BlockHeader(Keccak.Zero, Keccak.OfAnEmptySequenceRlp, Address.Zero, 131072, 0, 21000, 0, new byte[] { });

            parentHeader.Hash = parentHeader.CalculateHash();

            BlockHeader blockHeader = new BlockHeader(parentHeader.Hash, Keccak.OfAnEmptySequenceRlp, Address.Zero, 131136, 1, 21000, 1, new byte[] { });

            blockHeader.Nonce   = 7217048144105167954;
            blockHeader.MixHash = new Keccak("0x37d9fb46a55e9dbbffc428f3a1be6f191b3f8eaf52f2b6f53c4b9bae62937105");
            blockHeader.Hash    = blockHeader.CalculateHash();
            Block block = new Block(blockHeader);

            IEthash      ethash       = new Ethash(LimboLogs.Instance);
            EthashSealer ethashSealer = new EthashSealer(ethash, LimboLogs.Instance);
            await ethashSealer.MineAsync(CancellationToken.None, block, 7217048144105167954);

            Assert.True(ethash.Validate(block.Header));

            Console.WriteLine(block.Header.Nonce);
            Console.WriteLine(block.Header.MixHash);
        }
Exemplo n.º 25
0
        internal async Task <Block> MineAsync(CancellationToken cancellationToken, Block processed, ulong?startNonce)
        {
            if (processed.Header.TransactionsRoot == null ||
                processed.Header.StateRoot == null ||
                processed.Header.ReceiptsRoot == null ||
                processed.Header.OmmersHash == null ||
                processed.Header.Bloom == null ||
                processed.Header.ExtraData == null)
            {
                throw new InvalidOperationException($"Requested to mine an invalid block {processed.Header}");
            }

            Task <Block> miningTask = Task.Factory.StartNew(() => Mine(processed, startNonce), cancellationToken);
            await miningTask.ContinueWith(
                t =>
            {
                if (t.IsCompleted)
                {
                    t.Result.Header.Hash = BlockHeader.CalculateHash(t.Result.Header);
                }
            }, cancellationToken, TaskContinuationOptions.NotOnFaulted, TaskScheduler.Default);

            return(await miningTask);
        }
Exemplo n.º 26
0
        public void Hash_as_expected_2()
        {
            BlockHeader header = new BlockHeader();

            header.Bloom = new Bloom(
                Bytes.FromHexString("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
            header.Beneficiary  = new Address("0x8888f1f195afa192cfee860698584c030f4c9db1");
            header.Difficulty   = Bytes.FromHexString("0x020080").ToUInt256();
            header.ExtraData    = Bytes.Empty;
            header.GasLimit     = (long)Bytes.FromHexString("0x2fefba").ToUnsignedBigInteger();
            header.GasUsed      = (long)Bytes.FromHexString("0x5208").ToUnsignedBigInteger();
            header.MixHash      = new Keccak(Bytes.FromHexString("0x615bbf44eb133eab3cb24d5766ae9617d9e45ee00e7a5667db30672b47d22149"));
            header.Nonce        = (ulong)Bytes.FromHexString("0x4c4f3d3e055cb264").ToUnsignedBigInteger();
            header.Number       = (long)Bytes.FromHexString("0x03").ToUInt256();
            header.ParentHash   = new Keccak(Bytes.FromHexString("0xde1457da701ef916533750d46c124e9ae50b974410bd590fbcf4c935a4d19465"));
            header.ReceiptsRoot = new Keccak(Bytes.FromHexString("0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2"));
            header.StateRoot    = new Keccak(Bytes.FromHexString("0xfb4084a7f8b57e370fefe24a3da3aaea6c4dd8b6f6251916c32440336035160b"));
            header.Timestamp    = Bytes.FromHexString("0x59d79f1c").ToUInt256();
            header.TxRoot       = new Keccak(Bytes.FromHexString("0x1722b8a91bfc4f5614ce36ee77c7cce6620ab4af36d3c54baa66d7dbeb7bce1a"));
            header.OmmersHash   = new Keccak(Bytes.FromHexString("0xe676a42c388d2d24bb2927605d5d5d82fba50fb60d74d44b1cd7d1c4e4eee3c0"));
            header.Hash         = header.CalculateHash();

            Assert.AreEqual(new Keccak(Bytes.FromHexString("0x1423c2875714c31049cacfea8450f66a73ecbd61d7a6ab13089406a491aa9fc2")), header.Hash);
        }
Exemplo n.º 27
0
        public void Hash_as_expected()
        {
            BlockHeader header = new BlockHeader();

            header.Bloom = new Bloom(
                Bytes.FromHexString("0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
                .AsSpan().ToBigEndianBitArray2048());
            header.Beneficiary  = new Address("0x8888f1f195afa192cfee860698584c030f4c9db1");
            header.Difficulty   = Bytes.FromHexString("0x020000").ToUInt256();
            header.ExtraData    = Bytes.Empty;
            header.GasLimit     = (long)Bytes.FromHexString("0x2fefba").ToUnsignedBigInteger();
            header.GasUsed      = (long)Bytes.FromHexString("0x5208").ToUnsignedBigInteger();
            header.MixHash      = new Keccak(Bytes.FromHexString("0x00be1f287e0911ea2f070b3650a1a0346535895b6c919d7e992a0c255a83fc8b"));
            header.Nonce        = (ulong)Bytes.FromHexString("0xa0ddc06c6d7b9f48").ToUnsignedBigInteger();
            header.Number       = (long)Bytes.FromHexString("0x01").ToUInt256();
            header.ParentHash   = new Keccak(Bytes.FromHexString("0x5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae"));
            header.ReceiptsRoot = new Keccak(Bytes.FromHexString("0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2"));
            header.StateRoot    = new Keccak(Bytes.FromHexString("0x5c2e5a51a79da58791cdfe572bcfa3dfe9c860bf7fad7d9738a1aace56ef9332"));
            header.Timestamp    = Bytes.FromHexString("0x59d79f18").ToUInt256();
            header.TxRoot       = new Keccak(Bytes.FromHexString("0x5c9151c2413d1cd25c51ffb4ac38948acc1359bf08c6b49f283660e9bcf0f516"));
            header.OmmersHash   = new Keccak(Bytes.FromHexString("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"));

            Assert.AreEqual(new Keccak(Bytes.FromHexString("0x19a24085f6b1fb174aee0463264cc7163a7ffa165af04d3f40431ab3c3b08b98")), BlockHeader.CalculateHash(header));
        }
Exemplo n.º 28
0
        private Block ProcessNonGenesis(Block suggestedBlock, bool tryOnly)
        {
            if (_specProvider.DaoBlockNumber.HasValue && _specProvider.DaoBlockNumber.Value == suggestedBlock.Header.Number)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info($"Applying DAO transition");
                }

                ApplyDaoTransition();
            }

            // TODO: should be precalculated
            Keccak transactionsRoot = GetTransactionsRoot(suggestedBlock.Transactions);

            if (transactionsRoot != suggestedBlock.Header.TransactionsRoot)
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug($"TRANSACTIONS_ROOT {transactionsRoot} != TRANSACTIONS_ROOT {transactionsRoot}");
                }
            }

            if (_logger.IsDebugEnabled)
            {
                _logger.Debug($"Block beneficiary {suggestedBlock.Header.Beneficiary}");
                _logger.Debug($"Block gas limit {suggestedBlock.Header.GasLimit}");
                _logger.Debug($"Block gas used {suggestedBlock.Header.GasUsed}");
                _logger.Debug($"Block difficulty {suggestedBlock.Header.Difficulty}");
            }

            Block processedBlock = ProcessBlock(
                suggestedBlock.Header.ParentHash,
                suggestedBlock.Header.Difficulty,
                suggestedBlock.Header.Number,
                suggestedBlock.Header.Timestamp,
                suggestedBlock.Header.Beneficiary,
                suggestedBlock.Header.GasLimit,
                suggestedBlock.Header.ExtraData,
                suggestedBlock.Transactions,
                suggestedBlock.Header.MixHash,
                suggestedBlock.Header.Nonce,
                suggestedBlock.Header.OmmersHash,
                suggestedBlock.Ommers);

            processedBlock.Transactions            = suggestedBlock.Transactions;
            processedBlock.Header.TransactionsRoot = transactionsRoot;
            processedBlock.Header.Hash             = BlockHeader.CalculateHash(processedBlock.Header);

            if (!tryOnly && !_blockValidator.ValidateProcessedBlock(processedBlock, suggestedBlock))
            {
                if (_logger.IsErrorEnabled)
                {
                    _logger.Error($"Processed block is not valid {processedBlock.ToString(Block.Format.Short)}");
                }

                throw new InvalidBlockException($"{processedBlock}");
            }

            if (_logger.IsDebugEnabled)
            {
                _logger.Debug($"Committing block - state root {_stateProvider.StateRoot}");
            }

            return(processedBlock);
        }
            public On CreateNode(PrivateKey privateKey, bool withGenesisAlreadyProcessed = false)
            {
                if (_logger.IsInfo)
                {
                    _logger.Info($"CREATING NODE {privateKey.Address}");
                }
                _logManagers[privateKey] = LimboLogs.Instance;
//                _logManagers[privateKey] = new OneLoggerLogManager(new ConsoleAsyncLogger(LogLevel.Debug, $"{privateKey.Address} "));
                var nodeLogManager = _logManagers[privateKey];

                AutoResetEvent newHeadBlockEvent = new AutoResetEvent(false);

                _blockEvents.Add(privateKey, newHeadBlockEvent);

                MemDb blocksDb    = new MemDb();
                MemDb headersDb   = new MemDb();
                MemDb blockInfoDb = new MemDb();

                TxPool txPool = new TxPool(new InMemoryTransactionStorage(), new PendingTransactionThresholdValidator(), _timestamp, _ethereumEcdsa, GoerliSpecProvider.Instance, _logManager);

                _pools[privateKey] = txPool;

                BlockTree blockTree = new BlockTree(blocksDb, headersDb, blockInfoDb, GoerliSpecProvider.Instance, txPool, nodeLogManager);

                blockTree.NewHeadBlock += (sender, args) => { _blockEvents[privateKey].Set(); };

                BlockhashProvider blockhashProvider = new BlockhashProvider(blockTree);

                _blockTrees.Add(privateKey, blockTree);

                IBasicWallet    wallet          = new BasicWallet(privateKey);
                SnapshotManager snapshotManager = new SnapshotManager(_cliqueConfig, blocksDb, blockTree, _ethereumEcdsa, nodeLogManager);

                _snapshotManager[privateKey] = snapshotManager;
                CliqueSealer cliqueSealer = new CliqueSealer(wallet, _cliqueConfig, snapshotManager, privateKey.Address, nodeLogManager);

                ISnapshotableDb stateDb = new StateDb();
                ISnapshotableDb codeDb  = new StateDb();
                IDb             traceDb = new MemDb();

                StateProvider stateProvider = new StateProvider(stateDb, codeDb, nodeLogManager);

                stateProvider.CreateAccount(TestItem.PrivateKeyD.Address, 100.Ether());
                stateProvider.Commit(GoerliSpecProvider.Instance.GenesisSpec);

                _genesis.StateRoot       = _genesis3Validators.StateRoot = stateProvider.StateRoot;
                _genesis.Hash            = BlockHeader.CalculateHash(_genesis.Header);
                _genesis3Validators.Hash = BlockHeader.CalculateHash(_genesis3Validators.Header);

                StorageProvider      storageProvider      = new StorageProvider(stateDb, stateProvider, nodeLogManager);
                TransactionProcessor transactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, stateProvider, storageProvider, new VirtualMachine(stateProvider, storageProvider, blockhashProvider, nodeLogManager), nodeLogManager);
                BlockProcessor       blockProcessor       = new BlockProcessor(GoerliSpecProvider.Instance, TestBlockValidator.AlwaysValid, NoBlockRewards.Instance, transactionProcessor, stateDb, codeDb, traceDb, stateProvider, storageProvider, txPool, NullReceiptStorage.Instance, new SyncConfig(), nodeLogManager);
                BlockchainProcessor  processor            = new BlockchainProcessor(blockTree, blockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, false, false);

                processor.Start();

                StateProvider        minerStateProvider        = new StateProvider(stateDb, codeDb, nodeLogManager);
                StorageProvider      minerStorageProvider      = new StorageProvider(stateDb, minerStateProvider, nodeLogManager);
                VirtualMachine       minerVirtualMachine       = new VirtualMachine(minerStateProvider, minerStorageProvider, blockhashProvider, nodeLogManager);
                TransactionProcessor minerTransactionProcessor = new TransactionProcessor(GoerliSpecProvider.Instance, minerStateProvider, minerStorageProvider, minerVirtualMachine, nodeLogManager);
                BlockProcessor       minerBlockProcessor       = new BlockProcessor(GoerliSpecProvider.Instance, TestBlockValidator.AlwaysValid, NoBlockRewards.Instance, minerTransactionProcessor, stateDb, codeDb, traceDb, minerStateProvider, minerStorageProvider, txPool, NullReceiptStorage.Instance, new SyncConfig(), nodeLogManager);
                BlockchainProcessor  minerProcessor            = new BlockchainProcessor(blockTree, minerBlockProcessor, new AuthorRecoveryStep(snapshotManager), nodeLogManager, false, false);

                if (withGenesisAlreadyProcessed)
                {
                    ProcessGenesis(privateKey);
                }

                CliqueBlockProducer blockProducer = new CliqueBlockProducer(txPool, minerProcessor, blockTree, _timestamp, new CryptoRandom(), minerStateProvider, snapshotManager, cliqueSealer, privateKey.Address, _cliqueConfig, nodeLogManager);

                blockProducer.Start();

                _producers.Add(privateKey, blockProducer);

                return(this);
            }
Exemplo n.º 30
0
        public async Task Can_process_mined_blocks()
        {
            int timeMultiplier = 1; // for debugging

            TimeSpan miningDelay = TimeSpan.FromMilliseconds(50 * timeMultiplier);

            /* logging & instrumentation */
//            OneLoggerLogManager logger = new OneLoggerLogManager(new SimpleConsoleLogger(true));
            ILogManager logManager = NullLogManager.Instance;
            ILogger     logger     = logManager.GetClassLogger();

            /* spec */
            FakeSealer sealer = new FakeSealer(miningDelay);

            RopstenSpecProvider specProvider = RopstenSpecProvider.Instance;

            /* store & validation */

            EthereumEcdsa        ecdsa                = new EthereumEcdsa(specProvider, logManager);
            MemDb                receiptsDb           = new MemDb();
            MemDb                traceDb              = new MemDb();
            TxPool               txPool               = new TxPool(NullTxStorage.Instance, Timestamp.Default, ecdsa, specProvider, new TxPoolConfig(), logManager);
            IReceiptStorage      receiptStorage       = new PersistentReceiptStorage(receiptsDb, NullDb.Instance, specProvider, logManager);
            BlockTree            blockTree            = new BlockTree(new MemDb(), new MemDb(), new MemDb(), specProvider, txPool, logManager);
            Timestamp            timestamp            = new Timestamp();
            DifficultyCalculator difficultyCalculator = new DifficultyCalculator(specProvider);
            HeaderValidator      headerValidator      = new HeaderValidator(blockTree, sealer, specProvider, logManager);
            OmmersValidator      ommersValidator      = new OmmersValidator(blockTree, headerValidator, logManager);
            TxValidator          txValidator          = new TxValidator(ChainId.Ropsten);
            BlockValidator       blockValidator       = new BlockValidator(txValidator, headerValidator, ommersValidator, specProvider, logManager);

            /* state & storage */
            StateDb         codeDb          = new StateDb();
            StateDb         stateDb         = new StateDb();
            StateProvider   stateProvider   = new StateProvider(stateDb, codeDb, logManager);
            StorageProvider storageProvider = new StorageProvider(stateDb, stateProvider, logManager);

            TestTransactionsGenerator generator = new TestTransactionsGenerator(txPool, ecdsa, TimeSpan.FromMilliseconds(5 * timeMultiplier), NullLogManager.Instance);

            generator.Start();

            /* blockchain processing */
            BlockhashProvider    blockhashProvider = new BlockhashProvider(blockTree, LimboLogs.Instance);
            VirtualMachine       virtualMachine    = new VirtualMachine(stateProvider, storageProvider, blockhashProvider, logManager);
            TransactionProcessor processor         = new TransactionProcessor(specProvider, stateProvider, storageProvider, virtualMachine, logManager);
            RewardCalculator     rewardCalculator  = new RewardCalculator(specProvider);
            BlockProcessor       blockProcessor    = new BlockProcessor(specProvider, blockValidator, rewardCalculator,
                                                                        processor, stateDb, codeDb, traceDb, stateProvider, storageProvider, txPool, receiptStorage, logManager);
            BlockchainProcessor blockchainProcessor = new BlockchainProcessor(blockTree, blockProcessor, new TxSignaturesRecoveryStep(ecdsa, NullTxPool.Instance, LimboLogs.Instance), logManager, false, false);

            /* load ChainSpec and init */
            ChainSpecLoader loader = new ChainSpecLoader(new EthereumJsonSerializer());
            string          path   = "chainspec.json";

            logManager.GetClassLogger().Info($"Loading ChainSpec from {path}");
            ChainSpec chainSpec = loader.Load(File.ReadAllBytes(path));

            foreach (var allocation in chainSpec.Allocations)
            {
                stateProvider.CreateAccount(allocation.Key, allocation.Value.Balance);
                if (allocation.Value.Code != null)
                {
                    Keccak codeHash = stateProvider.UpdateCode(allocation.Value.Code);
                    stateProvider.UpdateCodeHash(allocation.Key, codeHash, specProvider.GenesisSpec);
                }
            }

            stateProvider.Commit(specProvider.GenesisSpec);
            chainSpec.Genesis.Header.StateRoot = stateProvider.StateRoot; // TODO: shall it be HeaderSpec and not BlockHeader?
            chainSpec.Genesis.Header.Hash      = BlockHeader.CalculateHash(chainSpec.Genesis.Header);
            if (chainSpec.Genesis.Hash != new Keccak("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"))
            {
                throw new Exception("Unexpected genesis hash");
            }

            /* start processing */
            blockTree.SuggestBlock(chainSpec.Genesis);
            blockchainProcessor.Start();

            MinedBlockProducer minedBlockProducer = new MinedBlockProducer(difficultyCalculator, txPool, blockchainProcessor, sealer, blockTree, timestamp, NullLogManager.Instance);

            minedBlockProducer.Start();

            ManualResetEventSlim manualResetEvent = new ManualResetEventSlim(false);

            blockTree.NewHeadBlock += (sender, args) =>
            {
                if (args.Block.Number == 6)
                {
                    manualResetEvent.Set();
                }
            };

            manualResetEvent.Wait(miningDelay * 12 * timeMultiplier);
            await minedBlockProducer.StopAsync();

            int previousCount = 0;
            int totalTx       = 0;

            for (int i = 0; i < 6; i++)
            {
                Block block = blockTree.FindBlock(i);
                logger.Info($"Block {i} with {block.Transactions.Length} txs");

                ManualResetEventSlim blockProcessedEvent = new ManualResetEventSlim(false);
                blockchainProcessor.ProcessingQueueEmpty += (sender, args) => blockProcessedEvent.Set();
                blockchainProcessor.SuggestBlock(block, ProcessingOptions.ForceProcessing | ProcessingOptions.StoreReceipts | ProcessingOptions.ReadOnlyChain);
                blockProcessedEvent.Wait(1000);

                Tracer tracer = new Tracer(blockchainProcessor, receiptStorage, blockTree, new MemDb());

                int currentCount = receiptsDb.Keys.Count;
                logger.Info($"Current count of receipts {currentCount}");
                logger.Info($"Previous count of receipts {previousCount}");

                if (block.Transactions.Length > 0)
                {
                    GethLikeTxTrace trace = tracer.Trace(block.Transactions[0].Hash);
                    Assert.AreSame(GethLikeTxTrace.QuickFail, trace);
                    Assert.AreNotEqual(previousCount, currentCount, $"receipts at block {i}");
                    totalTx += block.Transactions.Length;
                }

                previousCount = currentCount;
            }

            Assert.AreNotEqual(0, totalTx, "no tx in blocks");
        }