public void GetStateRoot(bool secure) { var stateStore = new TrieStateStore(_stateKeyValueStore, secure); ITrie empty = stateStore.GetStateRoot(null); Assert.True(empty.Recorded); Assert.Null(empty.Get(new[] { KeyFoo })[0]); Assert.Null(empty.Get(new[] { KeyBar })[0]); Assert.Null(empty.Get(new[] { KeyBaz })[0]); Assert.Null(empty.Get(new[] { KeyQux })[0]); Assert.Null(empty.Get(new[] { KeyQuux })[0]); var values = ImmutableDictionary <string, IValue> .Empty .Add("foo", (Binary)GetRandomBytes(32)) .Add("bar", (Text)ByteUtil.Hex(GetRandomBytes(32))) .Add("baz", (Bencodex.Types.Boolean)false) .Add("qux", Bencodex.Types.Dictionary.Empty); HashDigest <SHA256> hash = stateStore.Commit(null, values).Hash; ITrie found = stateStore.GetStateRoot(hash); Assert.True(found.Recorded); AssertBencodexEqual(values["foo"], found.Get(new[] { KeyFoo })[0]); AssertBencodexEqual(values["bar"], found.Get(new[] { KeyBar })[0]); AssertBencodexEqual(values["baz"], found.Get(new[] { KeyBaz })[0]); AssertBencodexEqual(values["qux"], found.Get(new[] { KeyQux })[0]); Assert.Null(found.Get(new[] { KeyQuux })[0]); }
public void PruneStates(bool secure) { var values = ImmutableDictionary <string, IValue> .Empty .Add("foo", (Binary)GetRandomBytes(4096)) .Add("bar", (Text)ByteUtil.Hex(GetRandomBytes(2048))) .Add("baz", (Bencodex.Types.Boolean)false) .Add("qux", Bencodex.Types.Dictionary.Empty) .Add( "zzz", Bencodex.Types.Dictionary.Empty .Add("binary", GetRandomBytes(4096)) .Add("text", ByteUtil.Hex(GetRandomBytes(2048)))); var stateStore = new TrieStateStore(_stateKeyValueStore, secure); ITrie first = stateStore.Commit(null, values); int prevStatesCount = _stateKeyValueStore.ListKeys().Count(); ImmutableDictionary <string, IValue> nextStates = values.SetItem("foo", (Binary)GetRandomBytes(4096)); ITrie second = stateStore.Commit(first.Hash, nextStates); // foo = 0x666f6f // updated branch node (0x6, aka root) + updated branch node (0x66) + // updated short node + new value nodes Assert.Equal(prevStatesCount + 4, _stateKeyValueStore.ListKeys().Count()); stateStore.PruneStates(ImmutableHashSet <HashDigest <SHA256> > .Empty.Add(second.Hash)); // It will stay at the same count of nodes. // FIXME: Bencodex fingerprints also should be tracked. // https://github.com/planetarium/libplanet/issues/1653 Assert.Equal(prevStatesCount, _stateKeyValueStore.ListKeys().Count()); }
public void DoesTransactionFollowsPolicyWithEmpty() { var adminPrivateKey = new PrivateKey(); var adminAddress = new Address(adminPrivateKey.PublicKey); var blockPolicySource = new BlockPolicySource(Logger.None); IBlockPolicy<PolymorphicAction<ActionBase>> policy = blockPolicySource.GetPolicy(10000, 100); Block<PolymorphicAction<ActionBase>> genesis = MakeGenesisBlock(adminAddress, ImmutableHashSet<Address>.Empty); using var store = new DefaultStore(null); using var stateStore = new TrieStateStore(new DefaultKeyValueStore(null), new DefaultKeyValueStore(null)); var blockChain = new BlockChain<PolymorphicAction<ActionBase>>( policy, store, stateStore, genesis, renderers: new[] { blockPolicySource.BlockRenderer } ); Transaction<PolymorphicAction<ActionBase>> tx = Transaction<PolymorphicAction<ActionBase>>.Create( 0, new PrivateKey(), genesis.Hash, new PolymorphicAction<ActionBase>[] { }); Assert.True(policy.DoesTransactionFollowsPolicy(tx, blockChain)); }
public void ReopenStoreAfterDispose() { var path = Path.Combine(Path.GetTempPath(), $"rocksdb_test_{Guid.NewGuid()}"); try { var store = new RocksDBStore(path); var stateStore = new TrieStateStore(new MemoryKeyValueStore(), new MemoryKeyValueStore()); var blocks = new BlockChain <DumbAction>( new NullPolicy <DumbAction>(), new VolatileStagePolicy <DumbAction>(), store, stateStore, Fx.GenesisBlock ); store.Dispose(); store = new RocksDBStore(path); store.Dispose(); } finally { Directory.Delete(path, true); } }
public void Tip( [Argument("STORE-TYPE")] StoreType storeType, [Argument("STORE-PATH")] string storePath) { if (!Directory.Exists(storePath)) { throw new CommandExitedException($"The given STORE-PATH, {storePath} seems not existed.", -1); } IStagePolicy <NCAction> stagePolicy = new VolatileStagePolicy <PolymorphicAction <ActionBase> >(); IBlockPolicy <NCAction> blockPolicy = new BlockPolicySource(Logger.None).GetPolicy(); IStore store = storeType.CreateStore(storePath); var stateStore = new TrieStateStore(new DefaultKeyValueStore(null)); Block <NCAction> genesisBlock = store.GetGenesisBlock <NCAction>(blockPolicy.GetHashAlgorithm); BlockChain <NCAction> chain = new BlockChain <NCAction>( blockPolicy, stagePolicy, store, stateStore, genesisBlock); _console.Out.WriteLine(Utils.SerializeHumanReadable(chain.Tip.Header)); (store as IDisposable)?.Dispose(); }
public void PruneStates(bool secure) { var values = ImmutableDictionary <string, IValue> .Empty .Add("foo", (Binary)GetRandomBytes(32)) .Add("bar", (Text)ByteUtil.Hex(GetRandomBytes(32))) .Add("baz", (Bencodex.Types.Boolean)false) .Add("qux", Bencodex.Types.Dictionary.Empty); var stateStore = new TrieStateStore(_stateKeyValueStore, secure); ITrie first = stateStore.Commit(null, values); int prevStatesCount = _stateKeyValueStore.ListKeys().Count(); ImmutableDictionary <string, IValue> nextStates = values.SetItem("foo", (Binary)GetRandomBytes(32)); ITrie second = stateStore.Commit(first.Hash, nextStates); // foo = 0x666f6f // updated branch node (0x6, aka root) + updated branch node (0x66) + // updated short node + new value node Assert.Equal(prevStatesCount + 4, _stateKeyValueStore.ListKeys().Count()); stateStore.PruneStates(ImmutableHashSet <HashDigest <SHA256> > .Empty.Add(second.Hash)); // It will stay at the same count of nodes. Assert.Equal(prevStatesCount, _stateKeyValueStore.ListKeys().Count()); }
public GraphQLControllerTest() { var store = new DefaultStore(null); var stateStore = new TrieStateStore( new DefaultKeyValueStore(null), new DefaultKeyValueStore(null)); var genesisBlock = BlockChain <PolymorphicAction <ActionBase> > .MakeGenesisBlock(); var blockchain = new BlockChain <PolymorphicAction <ActionBase> >( new BlockPolicy <PolymorphicAction <ActionBase> >(), new VolatileStagePolicy <PolymorphicAction <ActionBase> >(), store, stateStore, genesisBlock); _standaloneContext = new StandaloneContext { BlockChain = blockchain, Store = store, }; _configuration = new ConfigurationBuilder().AddInMemoryCollection().Build(); _httpContextAccessor = new HttpContextAccessor(); _httpContextAccessor.HttpContext = new DefaultHttpContext(); _controller = new GraphQLController(_standaloneContext, _httpContextAccessor, _configuration); }
private TrieStateStore MakeTrieStateStoreFixture(bool secure) { var stateStore = new TrieStateStore( _stateKeyValueStore, _stateHashKeyValueStore, secure); stateStore.SetStates(_fx.GenesisBlock, _prestoredValues); return(stateStore); }
public void ValidateNextBlockTxWithAuthorizedMiners() { var adminPrivateKey = new PrivateKey(); var adminAddress = adminPrivateKey.ToAddress(); var authorizedMinerPrivateKey = new PrivateKey(); (ActivationKey ak, PendingActivationState ps) = ActivationKey.Create( new PrivateKey(), new byte[] { 0x00, 0x01 } ); var blockPolicySource = new BlockPolicySource(Logger.None); IBlockPolicy <PolymorphicAction <ActionBase> > policy = blockPolicySource.GetPolicy( minimumDifficulty: 10_000, hashAlgorithmTypePolicy: null, maxBlockBytesPolicy: null, minTransactionsPerBlockPolicy: null, maxTransactionsPerBlockPolicy: null, maxTransactionsPerSignerPerBlockPolicy: null, authorizedMinersPolicy: AuthorizedMinersPolicy .Default .Add(new SpannedSubPolicy <ImmutableHashSet <Address> >( startIndex: 0, endIndex: 10, filter: index => index % 5 == 0, value: new Address[] { authorizedMinerPrivateKey.ToAddress() } .ToImmutableHashSet())), permissionedMinersPolicy: null); IStagePolicy <PolymorphicAction <ActionBase> > stagePolicy = new VolatileStagePolicy <PolymorphicAction <ActionBase> >(); Block <PolymorphicAction <ActionBase> > genesis = MakeGenesisBlock( adminAddress, ImmutableHashSet.Create(adminAddress), pendingActivations: new[] { ps } ); using var store = new DefaultStore(null); using var stateStore = new TrieStateStore(new DefaultKeyValueStore(null)); var blockChain = new BlockChain <PolymorphicAction <ActionBase> >( policy, stagePolicy, store, stateStore, genesis, renderers: new[] { blockPolicySource.BlockRenderer } ); Transaction <PolymorphicAction <ActionBase> > txFromAuthorizedMiner = Transaction <PolymorphicAction <ActionBase> > .Create( 0, authorizedMinerPrivateKey, genesis.Hash, new PolymorphicAction <ActionBase>[] { ak.CreateActivateAccount(new byte[] { 0x00, 0x01 }) } ); // Deny tx even if contains valid activation key. Assert.NotNull(policy.ValidateNextBlockTx(blockChain, txFromAuthorizedMiner)); }
private void ValidateNextBlockInvalidStateRootHash() { IKeyValueStore stateKeyValueStore = new MemoryKeyValueStore(), stateHashKeyValueStore = new MemoryKeyValueStore(); var policy = new BlockPolicy <DumbAction>( null, TimeSpan.FromHours(3), 1024, 128); var stateStore = new TrieStateStore(stateKeyValueStore, stateHashKeyValueStore); // FIXME: It assumes that _fx.GenesisBlock doesn't update any states with transactions. // Actually, it depends on BlockChain<T> to update states and it makes hard to // calculate state root hash. To resolve this problem, // it should be moved into StateStore. var genesisBlock = TestUtils.MineGenesis <DumbAction>( blockAction: policy.BlockAction, checkStateRootHash: true); var store = new DefaultStore(null); var chain = new BlockChain <DumbAction>( policy, store, stateStore, genesisBlock); var validNext = Block <DumbAction> .Mine( 1, 1024, genesisBlock.TotalDifficulty, genesisBlock.Miner.Value, genesisBlock.Hash, genesisBlock.Timestamp.AddSeconds(1), _emptyTransaction); chain.ExecuteActions(validNext); validNext = new Block <DumbAction>(validNext, stateStore.GetRootHash(validNext.Hash)); chain.Append(validNext); var invalidStateRootHash = Block <DumbAction> .Mine( 2, 1032, validNext.TotalDifficulty, genesisBlock.Miner.Value, validNext.Hash, validNext.Timestamp.AddSeconds(1), _emptyTransaction); var actionEvaluations = _blockChain.BlockEvaluator.EvaluateActions( invalidStateRootHash, StateCompleterSet <DumbAction> .Recalculate); chain.SetStates(invalidStateRootHash, actionEvaluations, false); invalidStateRootHash = new Block <DumbAction>( invalidStateRootHash, new HashDigest <SHA256>(TestUtils.GetRandomBytes(HashDigest <SHA256> .Size))); Assert.Throws <InvalidBlockStateRootHashException>(() => chain.Append(invalidStateRootHash)); }
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]); } }
#pragma warning disable S2699 // Tests should include assertions public void IdempotentDispose() #pragma warning restore S2699 // Tests should include assertions { var stateStore = new TrieStateStore(_stateKeyValueStore); stateStore.Dispose(); #pragma warning disable S3966 // Objects should not be disposed more than once stateStore.Dispose(); #pragma warning restore S3966 // Objects should not be disposed more than once }
protected (IStore, IStateStore) LoadStore(string path, string type, int statesCacheSize) { IStore store = null; if (type == "rocksdb") { try { store = new RocksDBStore.RocksDBStore( path, maxTotalWalSize: 16 * 1024 * 1024, maxLogFileSize: 16 * 1024 * 1024, keepLogFileNum: 1 ); Log.Debug("RocksDB is initialized."); } catch (TypeInitializationException e) { Log.Error("RocksDB is not available. DefaultStore will be used. {0}", e); } } else if (type == "monorocksdb") { try { store = new RocksDBStore.MonoRocksDBStore( path, maxTotalWalSize: 16 * 1024 * 1024, maxLogFileSize: 16 * 1024 * 1024, keepLogFileNum: 1 ); Log.Debug("MonoRocksDB is initialized."); } catch (TypeInitializationException e) { Log.Error("MonoRocksDB is not available. DefaultStore will be used. {0}", e); } } else { var message = type is null ? "Storage Type is not specified" : $"Storage Type {type} is not supported"; Log.Debug($"{message}. DefaultStore will be used."); } store ??= new DefaultStore(path, flush: false); store = new ReducedStore(store); IKeyValueStore stateKeyValueStore = new RocksDBKeyValueStore(Path.Combine(path, "states")), stateHashKeyValueStore = new RocksDBKeyValueStore(Path.Combine(path, "state_hashes")); IStateStore stateStore = new TrieStateStore(stateKeyValueStore, stateHashKeyValueStore); return(store, stateStore); }
public static (BlockChain <NCAction> Chain, IStore Store) GetBlockChain( ILogger logger, string storePath, bool monorocksdb = false, Guid?chainId = null ) { var policySource = new BlockPolicySource(logger); IBlockPolicy <NCAction> policy = policySource.GetPolicy(); IStagePolicy <NCAction> stagePolicy = new VolatileStagePolicy <NCAction>(); IStore store = monorocksdb ? (IStore) new MonoRocksDBStore(storePath) : new RocksDBStore(storePath); IKeyValueStore stateKeyValueStore = new RocksDBKeyValueStore(Path.Combine(storePath, "states")); IStateStore stateStore = new TrieStateStore(stateKeyValueStore); Guid chainIdValue = chainId ?? store.GetCanonicalChainId() ?? throw new CommandExitedException( "No canonical chain ID. Available chain IDs:\n " + string.Join("\n ", store.ListChainIds()), 1); BlockHash genesisBlockHash; try { genesisBlockHash = store.IterateIndexes(chainIdValue).First(); } catch (InvalidOperationException) { throw new CommandExitedException( $"The chain {chainIdValue} seems empty; try with another chain ID:\n " + string.Join("\n ", store.ListChainIds()), 1 ); } Block <NCAction> genesis = store.GetBlock <NCAction>( policy.GetHashAlgorithm, genesisBlockHash ); BlockChain <NCAction> chain = new BlockChain <NCAction>( policy, stagePolicy, store, stateStore, genesis ); return(chain, store); }
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(); Address address = signer.ToAddress(); var timestamp = DateTimeOffset.UtcNow; var txs = new[] { Transaction <RandomAction> .Create( 0, signer, null, new[] { new RandomAction(address), }), }; var stateStore = new TrieStateStore(new MemoryKeyValueStore(), new MemoryKeyValueStore()); Block <RandomAction> noStateRootBlock = TestUtils.MineGenesis( timestamp: timestamp, transactions: txs); Block <RandomAction> stateRootBlock = TestUtils.MineGenesis( timestamp: timestamp, transactions: txs).AttachStateRootHash(stateStore, null); var blockEvaluator = new BlockEvaluator <RandomAction>(null, NullStateGetter, NullBalanceGetter, null); var generatedRandomNumbers = new List <int>(); Assert.NotEqual(stateRootBlock.Hash, noStateRootBlock.Hash); Assert.Equal(stateRootBlock.PreEvaluationHash, noStateRootBlock.PreEvaluationHash); for (int i = 0; i < repeatCount; ++i) { var actionEvaluations = blockEvaluator.EvaluateActions( noStateRootBlock, StateCompleterSet <RandomAction> .Reject); generatedRandomNumbers.Add( (Integer)actionEvaluations[0].OutputStates.GetState(address)); actionEvaluations = blockEvaluator.EvaluateActions( stateRootBlock, StateCompleterSet <RandomAction> .Reject); generatedRandomNumbers.Add( (Integer)actionEvaluations[0].OutputStates.GetState(address)); } for (int i = 1; i < generatedRandomNumbers.Count; ++i) { Assert.Equal(generatedRandomNumbers[0], generatedRandomNumbers[i]); } }
public async void EarnMiningGoldWhenSuccessMining() { var adminPrivateKey = new PrivateKey(); var adminAddress = adminPrivateKey.ToAddress(); var authorizedMinerPrivateKey = new PrivateKey(); (ActivationKey ak, PendingActivationState ps) = ActivationKey.Create( new PrivateKey(), new byte[] { 0x00, 0x01 } ); var blockPolicySource = new BlockPolicySource(Logger.None); IBlockPolicy <PolymorphicAction <ActionBase> > policy = blockPolicySource.GetPolicy( 10_000, null, null, null, null, null, null, null); IStagePolicy <PolymorphicAction <ActionBase> > stagePolicy = new VolatileStagePolicy <PolymorphicAction <ActionBase> >(); Block <PolymorphicAction <ActionBase> > genesis = MakeGenesisBlock( adminAddress, ImmutableHashSet.Create(adminAddress), new AuthorizedMinersState( new[] { authorizedMinerPrivateKey.ToAddress() }, 5, 10 ), pendingActivations: new[] { ps } ); using var store = new DefaultStore(null); using var stateStore = new TrieStateStore(new DefaultKeyValueStore(null)); var blockChain = new BlockChain <PolymorphicAction <ActionBase> >( policy, stagePolicy, store, stateStore, genesis, renderers: new[] { blockPolicySource.BlockRenderer } ); blockChain.MakeTransaction( adminPrivateKey, new PolymorphicAction <ActionBase>[] { new DailyReward(), } ); await blockChain.MineBlock(adminPrivateKey); FungibleAssetValue actualBalance = blockChain.GetBalance(adminAddress, _currency); FungibleAssetValue expectedBalance = new FungibleAssetValue(_currency, 10, 0); Assert.True(expectedBalance.Equals(actualBalance)); }
public async Task BroadcastIgnoreFromDifferentGenesisHash() { var receiverKey = new PrivateKey(); Swarm <DumbAction> receiverSwarm = CreateSwarm(receiverKey); BlockChain <DumbAction> receiverChain = receiverSwarm.BlockChain; var seedStateStore = new TrieStateStore(new MemoryKeyValueStore()); IBlockPolicy <DumbAction> policy = receiverChain.Policy; Block <DumbAction> mismatchedGenesis = new BlockContent <DumbAction> { PublicKey = receiverKey.PublicKey, Timestamp = DateTimeOffset.MinValue, } .Mine(policy.GetHashAlgorithm(0)) .Evaluate(receiverKey, policy.BlockAction, seedStateStore); BlockChain <DumbAction> seedChain = TestUtils.MakeBlockChain( policy, new DefaultStore(path: null), seedStateStore, genesisBlock: mismatchedGenesis); var seedMiner = new PrivateKey(); Swarm <DumbAction> seedSwarm = CreateSwarm(seedChain, seedMiner); try { await StartAsync(receiverSwarm); await StartAsync(seedSwarm); await receiverSwarm.AddPeersAsync(new[] { seedSwarm.AsPeer }, null); Block <DumbAction> block = await seedChain.MineBlock(seedMiner); seedSwarm.BroadcastBlock(block); while (!((NetMQTransport)receiverSwarm.Transport).MessageHistory .Any(msg => msg is BlockHeaderMessage)) { await Task.Delay(100); } await Task.Delay(100); Assert.NotEqual(seedChain.Tip, receiverChain.Tip); } finally { await StopAsync(seedSwarm); await StopAsync(receiverSwarm); seedSwarm.Dispose(); } }
public async Task GetNextBlockDifficulty() { var store = new DefaultStore(null); var stateStore = new TrieStateStore(new MemoryKeyValueStore(), new MemoryKeyValueStore()); var dateTimeOffset = FixtureEpoch; var chain = TestUtils.MakeBlockChain(_policy, store, stateStore, timestamp: dateTimeOffset); var address = _fx.Address1; Assert.Equal( 1024, _policy.GetNextBlockDifficulty(chain) ); dateTimeOffset = FixtureEpoch + TimeSpan.FromHours(1); await chain.MineBlock(address, dateTimeOffset); Assert.Equal( 1032, _policy.GetNextBlockDifficulty(chain) ); dateTimeOffset = FixtureEpoch + TimeSpan.FromHours(3); await chain.MineBlock(address, dateTimeOffset); Assert.Equal( 1040, _policy.GetNextBlockDifficulty(chain) ); dateTimeOffset = FixtureEpoch + TimeSpan.FromHours(7); await chain.MineBlock(address, dateTimeOffset); Assert.Equal( 1040, _policy.GetNextBlockDifficulty(chain) ); dateTimeOffset = FixtureEpoch + TimeSpan.FromHours(9); await chain.MineBlock(address, dateTimeOffset); Assert.Equal( 1048, _policy.GetNextBlockDifficulty(chain) ); dateTimeOffset = FixtureEpoch + TimeSpan.FromHours(13); await chain.MineBlock(address, dateTimeOffset); Assert.Equal( 1048, _policy.GetNextBlockDifficulty(chain) ); }
public async Task Inspect(StoreType storeType) { Block <NCAction> genesisBlock = BlockChain <NCAction> .MakeGenesisBlock( HashAlgorithmType.Of <SHA256>() ); IStore store = storeType.CreateStore(_storePath2); Guid chainId = Guid.NewGuid(); store.SetCanonicalChainId(chainId); store.PutBlock(genesisBlock); store.AppendIndex(chainId, genesisBlock.Hash); var stateStore = new TrieStateStore(new DefaultKeyValueStore(null)); IStagePolicy <NCAction> stagePolicy = new VolatileStagePolicy <PolymorphicAction <ActionBase> >(); IBlockPolicy <NCAction> blockPolicy = new BlockPolicySource(Logger.None).GetPolicy(); BlockChain <NCAction> chain = new BlockChain <NCAction>( blockPolicy, stagePolicy, store, stateStore, genesisBlock); var action = new HackAndSlash { costumes = new List <Guid>(), equipments = new List <Guid>(), foods = new List <Guid>(), worldId = 1, stageId = 1, avatarAddress = default }; var minerKey = new PrivateKey(); chain.MakeTransaction(minerKey, new PolymorphicAction <ActionBase>[] { action }); await chain.MineBlock(minerKey, DateTimeOffset.Now); store.Dispose(); _command.Inspect(storeType, _storePath2); List <double> output = _console.Out.ToString().Split("\n")[1] .Split(',').Select(double.Parse).ToList(); var totalTxCount = Convert.ToInt32(output[2]); var hackandslashCount = Convert.ToInt32(output[3]); Assert.Equal(1, totalTxCount); Assert.Equal(1, hackandslashCount); }
public void DoesTransactionFollowsPolicyWithAuthorizedMiners() { var adminPrivateKey = new PrivateKey(); var adminAddress = adminPrivateKey.ToAddress(); var authorizedMinerPrivateKey = new PrivateKey(); (ActivationKey ak, PendingActivationState ps) = ActivationKey.Create( new PrivateKey(), new byte[] { 0x00, 0x01 } ); var blockPolicySource = new BlockPolicySource(Logger.None); IBlockPolicy <PolymorphicAction <ActionBase> > policy = blockPolicySource.GetPolicy(10000, 100); IStagePolicy <PolymorphicAction <ActionBase> > stagePolicy = new VolatileStagePolicy <PolymorphicAction <ActionBase> >(); Block <PolymorphicAction <ActionBase> > genesis = MakeGenesisBlock( adminAddress, ImmutableHashSet.Create(adminAddress), new AuthorizedMinersState( new[] { authorizedMinerPrivateKey.ToAddress() }, 5, 10 ), pendingActivations: new[] { ps } ); using var store = new DefaultStore(null); using var stateStore = new TrieStateStore(new DefaultKeyValueStore(null), new DefaultKeyValueStore(null)); var blockChain = new BlockChain <PolymorphicAction <ActionBase> >( policy, stagePolicy, store, stateStore, genesis, renderers: new[] { blockPolicySource.BlockRenderer } ); Transaction <PolymorphicAction <ActionBase> > txFromAuthorizedMiner = Transaction <PolymorphicAction <ActionBase> > .Create( 0, authorizedMinerPrivateKey, genesis.Hash, new PolymorphicAction <ActionBase>[] { ak.CreateActivateAccount(new byte[] { 0x00, 0x01 }) } ); // Deny tx even if contains valid activation key. Assert.False(policy.DoesTransactionFollowsPolicy(txFromAuthorizedMiner, blockChain)); }
public TrieStateStoreTest() { _fx = new DefaultStoreFixture(); _stateKeyValueStore = new DefaultKeyValueStore(null); _stateHashKeyValueStore = new DefaultKeyValueStore(null); _prestoredValues = ImmutableDictionary <string, IValue> .Empty .Add("foo", (Binary)TestUtils.GetRandomBytes(32)) .Add("bar", (Text)ByteUtil.Hex(TestUtils.GetRandomBytes(32))) .Add("baz", (Bencodex.Types.Boolean)false) .Add("qux", Bencodex.Types.Dictionary.Empty); _stateStore = new TrieStateStore(_stateKeyValueStore, _stateHashKeyValueStore); _stateStore.SetStates(_fx.GenesisBlock, _prestoredValues); }
public void MustNotIncludeBlockActionAtTransaction() { var adminPrivateKey = new PrivateKey(); var adminAddress = adminPrivateKey.ToAddress(); var authorizedMinerPrivateKey = new PrivateKey(); (ActivationKey ak, PendingActivationState ps) = ActivationKey.Create( new PrivateKey(), new byte[] { 0x00, 0x01 } ); var blockPolicySource = new BlockPolicySource(Logger.None); IBlockPolicy <PolymorphicAction <ActionBase> > policy = blockPolicySource.GetPolicy( 10_000, null, null, null, null, null, null, null); IStagePolicy <PolymorphicAction <ActionBase> > stagePolicy = new VolatileStagePolicy <PolymorphicAction <ActionBase> >(); Block <PolymorphicAction <ActionBase> > genesis = MakeGenesisBlock( adminAddress, ImmutableHashSet.Create(adminAddress), new AuthorizedMinersState( new[] { authorizedMinerPrivateKey.ToAddress() }, 5, 10 ), pendingActivations: new[] { ps } ); using var store = new DefaultStore(null); using var stateStore = new TrieStateStore(new DefaultKeyValueStore(null)); var blockChain = new BlockChain <PolymorphicAction <ActionBase> >( policy, stagePolicy, store, stateStore, genesis, renderers: new[] { blockPolicySource.BlockRenderer } ); Assert.Throws <MissingActionTypeException>(() => { blockChain.MakeTransaction( adminPrivateKey, new PolymorphicAction <ActionBase>[] { new RewardGold() } ); }); }
public async Task Proof() { using var store = new DefaultStore(null); using var stateStore = new TrieStateStore(new DefaultKeyValueStore(null)); var blockPolicySource = new BlockPolicySource(Logger.None); var genesis = BlockChain <NCAction> .MakeGenesisBlock(HashAlgorithmType.Of <SHA256>()); var blockChain = new BlockChain <NCAction>( blockPolicySource.GetPolicy(10_000, null, null, null, null, null, null), new VolatileStagePolicy <NCAction>(), store, stateStore, genesis, renderers: new[] { blockPolicySource.BlockRenderer } ); var minerKey = new PrivateKey(); var miner = new Miner(blockChain, null, minerKey, false); Block <NCAction> mined = await miner.MineBlockAsync(default);
public IntegerSet( IReadOnlyList <BigInteger?> initialStates, IBlockPolicy <Arithmetic> policy = null, IEnumerable <IRenderer <Arithmetic> > renderers = null ) { PrivateKeys = initialStates.Select(_ => new PrivateKey()).ToImmutableArray(); Addresses = PrivateKeys.Select(AddressExtensions.ToAddress).ToImmutableArray(); Txs = initialStates .Select((state, index) => new { State = state, Key = PrivateKeys[index] }) .Where(pair => !(pair.State is null)) .Select(pair => new { State = (BigInteger)pair.State, pair.Key }) .Select(pair => new { Action = Arithmetic.Add(pair.State), pair.Key }) .Select(pair => Transaction <Arithmetic> .Create( 0, pair.Key, null, new[] { pair.Action }, ImmutableHashSet <Address> .Empty.Add(pair.Key.ToAddress()) ) ) .ToImmutableArray(); Miner = new PrivateKey(); policy = policy ?? new NullBlockPolicy <Arithmetic>(); Store = new MemoryStore(); KVStore = new MemoryKeyValueStore(); StateStore = new TrieStateStore(KVStore); Genesis = new BlockContent <Arithmetic> { PublicKey = Miner.PublicKey, Timestamp = DateTimeOffset.UtcNow, Transactions = Txs, }.Mine(policy.GetHashAlgorithm(0)).Evaluate(Miner, policy.BlockAction, StateStore); Chain = new BlockChain <Arithmetic>( policy, new VolatileStagePolicy <Arithmetic>(), Store, StateStore, Genesis, renderers ); }
public void GetStateRoot(bool secure) { var stateStore = new TrieStateStore(_stateKeyValueStore, secure); ITrie empty = stateStore.GetStateRoot(null); Assert.True(empty.Recorded); Assert.False(empty.TryGet(KeyFoo, out _)); Assert.False(empty.TryGet(KeyBar, out _)); Assert.False(empty.TryGet(KeyBaz, out _)); Assert.False(empty.TryGet(KeyQux, out _)); Assert.False(empty.TryGet(KeyQuux, out _)); var values = ImmutableDictionary <string, IValue> .Empty .Add("foo", (Binary)GetRandomBytes(32)) .Add("bar", (Text)ByteUtil.Hex(GetRandomBytes(32))) .Add("baz", (Bencodex.Types.Boolean)false) .Add("qux", Bencodex.Types.Dictionary.Empty); HashDigest <SHA256> hash = stateStore.Commit(null, values, rehearsal: true).Hash; ITrie notFound = stateStore.GetStateRoot(hash); Assert.False(notFound.Recorded); IValue value; stateStore.Commit(null, values, rehearsal: false); ITrie found = stateStore.GetStateRoot(hash); Assert.True(found.Recorded); Assert.True(found.TryGet(KeyFoo, out value)); AssertBencodexEqual(values["foo"], value); Assert.True(found.TryGet(KeyBar, out value)); AssertBencodexEqual(values["bar"], value); Assert.True(found.TryGet(KeyBaz, out value)); AssertBencodexEqual(values["baz"], value); Assert.True(found.TryGet(KeyQux, out value)); AssertBencodexEqual(values["qux"], value); Assert.False(empty.TryGet(KeyQuux, out _)); }
public void CopyStates(bool secure) { var values = ImmutableDictionary <string, IValue> .Empty .Add("foo", (Binary)GetRandomBytes(4096)) .Add("bar", (Text)ByteUtil.Hex(GetRandomBytes(2048))) .Add("baz", (Bencodex.Types.Boolean)false) .Add("qux", Bencodex.Types.Dictionary.Empty) .Add( "zzz", Bencodex.Types.Dictionary.Empty .Add("binary", GetRandomBytes(4096)) .Add("text", ByteUtil.Hex(GetRandomBytes(2048)))); var stateStore = new TrieStateStore(_stateKeyValueStore, secure); IKeyValueStore targetStateKeyValueStore = new MemoryKeyValueStore(); var targetStateStore = new TrieStateStore(targetStateKeyValueStore, secure); ITrie trie = stateStore.Commit(null, values); int prevStatesCount = _stateKeyValueStore.ListKeys().Count(); _stateKeyValueStore.Set( new KeyBytes("alpha", Encoding.UTF8), ByteUtil.ParseHex("00")); _stateKeyValueStore.Set( new KeyBytes("beta", Encoding.UTF8), ByteUtil.ParseHex("00")); Assert.Equal(prevStatesCount + 2, _stateKeyValueStore.ListKeys().Count()); Assert.Empty(targetStateKeyValueStore.ListKeys()); stateStore.CopyStates( ImmutableHashSet <HashDigest <SHA256> > .Empty.Add(trie.Hash), targetStateStore); // It will stay at the same count of nodes. // FIXME: Bencodex fingerprints also should be tracked. // https://github.com/planetarium/libplanet/issues/1653 Assert.Equal(prevStatesCount, targetStateKeyValueStore.ListKeys().Count()); }
public async void Evaluate() { var privateKey = new PrivateKey(); var address = privateKey.ToAddress(); long blockIndex = 1; var action = new EvaluateTestAction(); var store = new DefaultStore(null); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var chain = TestUtils.MakeBlockChain <EvaluateTestAction>( policy: new BlockPolicy <EvaluateTestAction>(), store: store, stateStore: stateStore); var tx = Transaction <EvaluateTestAction> .Create( nonce : 0, privateKey : privateKey, genesisHash : chain.Genesis.Hash, actions : new[] { action }); chain.StageTransaction(tx); var miner = new PrivateKey(); await chain.MineBlock(miner); var evaluations = chain.ActionEvaluator.Evaluate( chain.Tip, StateCompleterSet <EvaluateTestAction> .Recalculate); Assert.False(evaluations[0].InputContext.BlockAction); Assert.Single(evaluations); Assert.Null(evaluations.Single().Exception); Assert.Equal(chain.GetState(action.SignerKey), (Text)address.ToHex()); Assert.Equal(chain.GetState(action.MinerKey), (Text)miner.ToAddress().ToHex()); var state = chain.GetState(action.BlockIndexKey); Assert.Equal((long)(Integer)state, blockIndex); }
private void ValidateNextBlockInvalidStateRootHash() { IKeyValueStore stateKeyValueStore = new MemoryKeyValueStore(); var policy = new BlockPolicy <DumbAction>( blockInterval: TimeSpan.FromMilliseconds(3 * 60 * 60 * 1000) ); var stateStore = new TrieStateStore(stateKeyValueStore); IStore store = new MemoryStore(); var genesisBlock = TestUtils.MineGenesis <DumbAction>( policy.GetHashAlgorithm, TestUtils.GenesisMiner.PublicKey ).Evaluate(TestUtils.GenesisMiner, policy.BlockAction, stateStore); store.PutBlock(genesisBlock); Assert.NotNull(store.GetStateRootHash(genesisBlock.Hash)); var chain1 = new BlockChain <DumbAction>( policy, new VolatileStagePolicy <DumbAction>(), store, stateStore, genesisBlock ); Block <DumbAction> block1 = new BlockContent <DumbAction> { Index = 1, Difficulty = 1024L, TotalDifficulty = genesisBlock.TotalDifficulty + 1024, PublicKey = TestUtils.GenesisMiner.PublicKey, PreviousHash = genesisBlock.Hash, Timestamp = genesisBlock.Timestamp.AddSeconds(1), Transactions = _emptyTransaction, }.Mine(policy.GetHashAlgorithm(1)).Evaluate(TestUtils.GenesisMiner, chain1); var policyWithBlockAction = new BlockPolicy <DumbAction>( new SetStatesAtBlock(default, (Text)"foo", 1),
public async void EvaluateWithException() { var privateKey = new PrivateKey(); var address = privateKey.ToAddress(); var action = new ThrowException { ThrowOnRehearsal = false, ThrowOnExecution = true }; var store = new DefaultStore(null); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var chain = TestUtils.MakeBlockChain <ThrowException>( policy: new BlockPolicy <ThrowException>(), store: store, stateStore: stateStore); var tx = Transaction <ThrowException> .Create( nonce : 0, privateKey : privateKey, genesisHash : chain.Genesis.Hash, actions : new[] { action }); chain.StageTransaction(tx); await chain.MineBlock(new PrivateKey()); var evaluations = chain.ActionEvaluator.Evaluate( chain.Tip, StateCompleterSet <ThrowException> .Recalculate); Assert.False(evaluations[0].InputContext.BlockAction); Assert.Single(evaluations); Assert.NotNull(evaluations.Single().Exception); Assert.IsType <UnexpectedlyTerminatedActionException>( evaluations.Single().Exception); Assert.IsType <ThrowException.SomeException>( evaluations.Single().Exception.InnerException); }
public GraphQLTestBase(ITestOutputHelper output) { Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console().CreateLogger(); _output = output; var store = new DefaultStore(null); var stateStore = new TrieStateStore( new DefaultKeyValueStore(null), new DefaultKeyValueStore(null) ); var genesisBlock = BlockChain <PolymorphicAction <ActionBase> > .MakeGenesisBlock(blockAction : new RewardGold()); var blockPolicy = new BlockPolicy <PolymorphicAction <ActionBase> >(blockAction: new RewardGold()); var blockChain = new BlockChain <PolymorphicAction <ActionBase> >( blockPolicy, store, stateStore, genesisBlock, renderers: new IRenderer <PolymorphicAction <ActionBase> >[] { new BlockRenderer(), new ActionRenderer() } ); var tempKeyStorePath = Path.Join(Path.GetTempPath(), Path.GetRandomFileName()); var keyStore = new Web3KeyStore(tempKeyStorePath); StandaloneContextFx = new StandaloneContext { BlockChain = blockChain, KeyStore = keyStore, }; Schema = new StandaloneSchema(new TestServiceProvider(StandaloneContextFx)); Schema.Subscription.As <StandaloneSubscription>().RegisterTipChangedSubscription(); DocumentExecutor = new DocumentExecuter(); }