public void Idempotent() { // NOTE: This test checks that blocks can be evaluated idempotently. Also it checks // the action results in pre-evaluation step and in evaluation step are equal. const int repeatCount = 2; var signer = new PrivateKey(); var timestamp = DateTimeOffset.UtcNow; var txAddress = signer.ToAddress(); var txs = new[] { Transaction <RandomAction> .Create( nonce : 0, privateKey : signer, genesisHash : null, actions : new[] { new RandomAction(txAddress), }), }; var stateStore = new TrieStateStore(new MemoryKeyValueStore()); HashAlgorithmGetter hashAlgorithmGetter = _ => HashAlgorithmType.Of <SHA256>(); PreEvaluationBlock <RandomAction> noStateRootBlock = MineGenesis( hashAlgorithmGetter: hashAlgorithmGetter, miner: GenesisMiner.PublicKey, timestamp: timestamp, transactions: txs ); Block <RandomAction> stateRootBlock = noStateRootBlock.Evaluate(GenesisMiner, null, stateStore); var actionEvaluator = new ActionEvaluator <RandomAction>( hashAlgorithmGetter: hashAlgorithmGetter, policyBlockAction: null, stateGetter: ActionEvaluator <RandomAction> .NullStateGetter, balanceGetter: ActionEvaluator <RandomAction> .NullBalanceGetter, trieGetter: null); var generatedRandomNumbers = new List <int>(); AssertPreEvaluationBlocksEqual(stateRootBlock, noStateRootBlock); for (int i = 0; i < repeatCount; ++i) { var actionEvaluations = actionEvaluator.Evaluate( noStateRootBlock, StateCompleterSet <RandomAction> .Reject); generatedRandomNumbers.Add( (Integer)actionEvaluations[0].OutputStates.GetState(txAddress)); actionEvaluations = actionEvaluator.Evaluate( stateRootBlock, StateCompleterSet <RandomAction> .Reject); generatedRandomNumbers.Add( (Integer)actionEvaluations[0].OutputStates.GetState(txAddress)); } for (int i = 1; i < generatedRandomNumbers.Count; ++i) { Assert.Equal(generatedRandomNumbers[0], generatedRandomNumbers[i]); } }
public void Evaluate() { 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()) { Block <Arithmetic> genesis = preEvalGenesis.Evaluate(_contents.GenesisKey, blockAction, fx.StateStore); AssertPreEvaluationBlocksEqual(preEvalGenesis, genesis); _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(genesis.StateRootHash, 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)); Block <Arithmetic> block1 = preEval1.Evaluate(_contents.Block1Key, blockChain); AssertPreEvaluationBlocksEqual(preEval1, block1); _output.WriteLine("#1: {0}", block1); HashDigest <SHA256> identicalBlock1StateRootHash = preEval1.DetermineStateRootHash(blockChain); AssertBytesEqual(block1.StateRootHash, identicalBlock1StateRootHash); blockChain.Append(block1); AssertBencodexEqual((Bencodex.Types.Integer) 158, blockChain.GetState(address)); } }
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); }