Exemple #1
0
        public void DetermineStateRootHash()
        {
            Address address     = _contents.Tx0InBlock1.Signer;
            var     blockAction = new SetStatesAtBlock(address, (Bencodex.Types.Integer) 123, 0);
            var     policy      = new BlockPolicy <Arithmetic>(
                blockAction: blockAction,
                blockInterval: TimeSpan.FromMilliseconds(3 * 60 * 60 * 1000),
                minimumDifficulty: 2,
                difficultyStability: 1
                );
            var stagePolicy = new VolatileStagePolicy <Arithmetic>();

            PreEvaluationBlock <Arithmetic> preEvalGenesis =
                _contents.Genesis.Mine(policy.GetHashAlgorithm(0));

            using (var fx = new DefaultStoreFixture())
            {
                HashDigest <SHA256> genesisStateRootHash =
                    preEvalGenesis.DetermineStateRootHash(blockAction, fx.StateStore);
                _output.WriteLine("#0 StateRootHash: {0}", genesisStateRootHash);
                Block <Arithmetic> genesis =
                    preEvalGenesis.Sign(_contents.GenesisKey, genesisStateRootHash);
                _output.WriteLine("#1: {0}", genesis);

                var blockChain = new BlockChain <Arithmetic>(
                    policy,
                    stagePolicy,
                    fx.Store,
                    fx.StateStore,
                    genesis
                    );
                AssertBencodexEqual((Bencodex.Types.Integer) 123, blockChain.GetState(address));

                HashDigest <SHA256> identicalGenesisStateRootHash =
                    preEvalGenesis.DetermineStateRootHash(blockChain);
                AssertBytesEqual(genesisStateRootHash, identicalGenesisStateRootHash);

                BlockContent <Arithmetic> content1 = _contents.Block1;
                content1.PreviousHash = genesis.Hash;
                content1.Difficulty   = 2;
                content1.Transactions = new[] { _contents.Tx0InBlock1 };
                PreEvaluationBlock <Arithmetic> preEval1 = content1.Mine(policy.GetHashAlgorithm(1));

                HashDigest <SHA256> b1StateRootHash = preEval1.DetermineStateRootHash(blockChain);
                _output.WriteLine("#1 StateRootHash: {0}", b1StateRootHash);
                Block <Arithmetic> block1 = preEval1.Sign(_contents.Block1Key, b1StateRootHash);
                _output.WriteLine("#1: {0}", block1);

                blockChain.Append(block1);
                AssertBencodexEqual((Bencodex.Types.Integer) 158, blockChain.GetState(address));
            }
        }
Exemple #2
0
        public override BlockChain <DumbAction> TransferAssetInBlock()
        {
            BlockChain <DumbAction> chain = base.TransferAssetInBlock();

            DumbAction action           = new DumbAction(_addr[0], "a", _addr[0], _addr[0], 1);
            Transaction <DumbAction> tx = Transaction <DumbAction> .Create(
                chain.GetNextTxNonce(_addr[0]),
                _keys[0],
                chain.Genesis.Hash,
                new[] { action }
                );

            PreEvaluationBlock <DumbAction> preEval = TestUtils.MineNext(
                chain.Tip,
                chain.Policy.GetHashAlgorithm,
                new[] { tx },
                miner: _keys[1].PublicKey,
                protocolVersion: ProtocolVersion
                );

            chain.Append(
                new Block <DumbAction>(
                    preEval,
                    preEval.DetermineStateRootHash(chain),
                    signature: null
                    )
                );
            Assert.Equal(
                DumbAction.DumbCurrency * 6,
                chain.GetBalance(_addr[0], DumbAction.DumbCurrency)
                );

            return(chain);
        }
Exemple #3
0
        public static BlockChain <T> MakeBlockChain <T>(
            IBlockPolicy <T> policy,
            IStore store,
            IStateStore stateStore,
            IEnumerable <T> actions  = null,
            PrivateKey privateKey    = null,
            DateTimeOffset?timestamp = null,
            IEnumerable <IRenderer <T> > renderers = null,
            Block <T> genesisBlock = null,
            int protocolVersion    = Block <T> .CurrentProtocolVersion
            )
            where T : IAction, new()
        {
            actions    = actions ?? ImmutableArray <T> .Empty;
            privateKey = privateKey ?? ChainPrivateKey;

            var tx = Transaction <T> .Create(
                0,
                privateKey,
                null,
                actions,
                timestamp : timestamp ?? DateTimeOffset.MinValue);

            if (genesisBlock is null)
            {
                var content = new BlockContent <T>()
                {
                    Miner           = GenesisMiner.ToAddress(),
                    PublicKey       = protocolVersion < 2 ? null : GenesisMiner.PublicKey,
                    Timestamp       = timestamp ?? DateTimeOffset.MinValue,
                    Transactions    = new[] { tx },
                    ProtocolVersion = protocolVersion,
                };
                var preEval = new PreEvaluationBlock <T>(
                    content,
                    policy.GetHashAlgorithm(0),
                    new Nonce(new byte[] { 0x01, 0x00, 0x00, 0x00 })
                    );
                genesisBlock = protocolVersion < 2
                 ? new Block <T>(
                    preEval,
                    preEval.DetermineStateRootHash(policy.BlockAction, stateStore),
                    signature: null)
                 : preEval.Evaluate(GenesisMiner, policy.BlockAction, stateStore);
            }

            ValidatingActionRenderer <T> validator = null;

#pragma warning disable S1121
            var chain = new BlockChain <T>(
                policy,
                new VolatileStagePolicy <T>(),
                store,
                stateStore,
                genesisBlock,
                renderers: renderers ?? new[] { validator = new ValidatingActionRenderer <T>() }
                );
#pragma warning restore S1121

            if (validator != null)
            {
                validator.BlockChain = chain;
            }

            return(chain);
        }
Exemple #4
0
        public void Rebuild(
            [Option('v', Description = "Print more logs.")]
            bool verbose,
            [Option('s', Description = "Path to the chain store.")]
            string storePath,
            [Option('c', Description = "Optional chain ID.  Default is the canonical chain ID.")]
            Guid?chainId = null,
            [Option(
                 't',
                 Description = "Optional topmost block to execute last.  Can be either a block " +
                               "hash or block index.  Tip by default.")]
            string topmost = null,
            [Option(
                 new char[] { 'f', 'B' },
                 Description = "Optional bottommost block to execute first.  Can be either a " +
                               "block hash or block index.  Genesis by default.")]
            string bottommost = null,
            [Option('b', Description = "Bypass the state root hash check.")]
            bool bypassStateRootHashCheck = false,
            [Option(
                 'm',
                 Description = "Use the in-memory key-value state store and dump it to " +
                               "the specified directory path in the end.",
                 ValueName = "DIR")]
            string useMemoryKvStore = null
            )
        {
            using Logger logger = Utils.ConfigureLogger(verbose);
            CancellationToken cancellationToken = GetInterruptSignalCancellationToken();
            TextWriter        stderr            = Console.Error;

            (
                BlockChain <NCAction> chain,
                IStore store,
                IKeyValueStore stateKvStore,
                IStateStore stateStore
            ) = Utils.GetBlockChain(
                logger,
                storePath,
                chainId,
                useMemoryKvStore is string p ? new MemoryKeyValueStore(p, stderr) : null
                );
            Block <NCAction> bottom = Utils.ParseBlockOffset(chain, bottommost, 0);
            Block <NCAction> top    = Utils.ParseBlockOffset(chain, topmost);

            stderr.WriteLine("It will execute all actions (tx actions & block actions)");
            stderr.WriteLine(
                "  ...from the block #{0} {1}",
                bottom.Index.ToString(CultureInfo.InvariantCulture).PadRight(
                    top.Index.ToString(CultureInfo.InvariantCulture).Length),
                bottom.Hash);
            stderr.WriteLine("    ...to the block #{0} {1}.", top.Index, top.Hash);

            IBlockPolicy <NCAction> policy = chain.Policy;

            (Block <NCAction>, string)? invalidStateRootHashBlock = null;
            long                    totalBlocks    = top.Index - bottom.Index + 1;
            long                    blocksExecuted = 0L;
            long                    txsExecuted    = 0L;
            DateTimeOffset          started        = DateTimeOffset.Now;
            IEnumerable <BlockHash> blockHashes    = store.IterateIndexes(
                chain.Id,
                (int)bottom.Index,
                (int)(top.Index - bottom.Index + 1L)
                );

            foreach (BlockHash blockHash in blockHashes)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    throw new CommandExitedException(1);
                }

                Block <NCAction> block =
                    store.GetBlock <NCAction>(policy.GetHashAlgorithm, blockHash);
                var preEvalBlock = new PreEvaluationBlock <NCAction>(
                    block,
                    block.HashAlgorithm,
                    block.Nonce,
                    block.PreEvaluationHash
                    );
                stderr.WriteLine(
                    "[{0}/{1}] Executing block #{2} {3}...",
                    block.Index - bottom.Index + 1L,
                    top.Index - bottom.Index + 1L,
                    block.Index,
                    block.Hash
                    );
                IImmutableDictionary <string, IValue> delta;
                HashDigest <SHA256> stateRootHash = block.Index < 1
                    ? preEvalBlock.DetermineStateRootHash(chain.Policy.BlockAction, stateStore, out delta)
                    : preEvalBlock.DetermineStateRootHash(
                    chain,
                    StateCompleterSet <NCAction> .Reject,
                    out delta);
                DateTimeOffset now = DateTimeOffset.Now;
                if (invalidStateRootHashBlock is null && !stateRootHash.Equals(block.StateRootHash))
                {
                    string blockDump = DumpBencodexToFile(
                        block.MarshalBlock(),
                        $"block_{block.Index}_{block.Hash}"
                        );
                    string deltaDump = DumpBencodexToFile(
                        new Dictionary(
                            delta.Select(kv =>
                                         new KeyValuePair <IKey, IValue>(new Text(kv.Key), kv.Value))),
                        $"delta_{block.Index}_{block.Hash}"
                        );
                    string message =
                        $"Unexpected state root hash for block #{block.Index} {block.Hash}.\n" +
                        $"  Expected: {block.StateRootHash}\n  Actual:   {stateRootHash}\n" +
                        $"  Block file: {blockDump}\n  Evaluated delta file: {deltaDump}\n";
                    if (!bypassStateRootHashCheck)
                    {
                        throw new CommandExitedException(message, 1);
                    }

                    stderr.WriteLine(message);
                    invalidStateRootHashBlock = (block, message);
                }

                blocksExecuted++;
                txsExecuted += block.Transactions.Count;
                TimeSpan elapsed = now - started;

                if (blocksExecuted >= totalBlocks || block.Hash.Equals(top.Hash))
                {
                    stderr.WriteLine("Elapsed: {0:c}.", elapsed);
                    break;
                }
                else
                {
                    TimeSpan estimatedRemaining =
                        elapsed / blocksExecuted * (totalBlocks - blocksExecuted);
                    stderr.WriteLine(
                        "Elapsed: {0:c}, estimated remaining: {1:c}.",
                        elapsed,
                        estimatedRemaining
                        );
                }
            }

            if (invalidStateRootHashBlock is { } b)
            {
                stderr.WriteLine(
                    "Note that the state root hash check is bypassed, " +
                    "but there was an invalid state root hash for block #{0} {1}.  {2}",
                    b.Item1.Index,
                    b.Item1.Hash,
                    b.Item2
                    );
            }

            TimeSpan totalElapsed = DateTimeOffset.Now - started;

            stderr.WriteLine("Total elapsed: {0:c}", totalElapsed);
            stderr.WriteLine("Avg block execution time: {0:c}", totalElapsed / totalBlocks);
            stderr.WriteLine("Avg tx execution time: {0:c}", totalElapsed / txsExecuted);
            stateKvStore.Dispose();
            stateStore.Dispose();
        }