public SwarmTest(ITestOutputHelper output) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .Enrich.WithThreadId() .WriteTo.TestOutput(output, outputTemplate: "{Timestamp:HH:mm:ss}[@{SwarmId}][{ThreadId}] - {Message}") .CreateLogger() .ForContext <SwarmTest>(); var policy = new BlockPolicy <BaseAction>(); _fx1 = new FileStoreFixture(); _fx2 = new FileStoreFixture(); _fx3 = new FileStoreFixture(); _blockchains = new List <BlockChain <BaseAction> > { new BlockChain <BaseAction>(policy, _fx1.Store), new BlockChain <BaseAction>(policy, _fx2.Store), new BlockChain <BaseAction>(policy, _fx3.Store), }; _swarms = new List <Swarm> { new Swarm( new PrivateKey(), ipAddress: IPAddress.Loopback), new Swarm( new PrivateKey(), ipAddress: IPAddress.Loopback), new Swarm( new PrivateKey(), ipAddress: IPAddress.Loopback), }; }
public void Constructors() { var tenMilliSec = new TimeSpan(0, 0, 10000); var a = new BlockPolicy <BaseAction>(tenMilliSec); Assert.Equal(tenMilliSec, a.BlockInterval); var b = new BlockPolicy <BaseAction>(65); Assert.Equal( new TimeSpan(0, 1000, 5000), b.BlockInterval ); var c = new BlockPolicy <BaseAction>(); Assert.Equal( new TimeSpan(0, 0, 5000), c.BlockInterval ); Assert.Throws <ArgumentOutOfRangeException>( () => new BlockPolicy <BaseAction>(tenSec.Negate()) ); Assert.Throws <ArgumentOutOfRangeException>( () => new BlockPolicy <BaseAction>(-5000) ); }
public void ValidateNextBlockTx() { var validKey = new PrivateKey(); TxPolicyViolationException IsSignerValid( BlockChain <DumbAction> chain, Transaction <DumbAction> tx) { var validAddress = validKey.PublicKey.ToAddress(); return(tx.Signer.Equals(validAddress) ? null : new TxPolicyViolationException(tx.Id, "invalid signer")); } var policy = new BlockPolicy <DumbAction>(validateNextBlockTx: IsSignerValid); // Valid Transaction var validTx = _chain.MakeTransaction(validKey, new DumbAction[] { }); var expected = policy.ValidateNextBlockTx(_chain, validTx); Assert.Null(expected); // Invalid Transaction var invalidKey = new PrivateKey(); var invalidTx = _chain.MakeTransaction(invalidKey, new DumbAction[] { }); expected = policy.ValidateNextBlockTx(_chain, invalidTx); Assert.NotNull(expected); }
public void Constructors() { var tenSec = new TimeSpan(0, 0, 10); var a = new BlockPolicy <DumbAction>(tenSec, 1024, 128); Assert.Equal(tenSec, a.BlockInterval); var b = new BlockPolicy <DumbAction>(65000); Assert.Equal( new TimeSpan(0, 1, 5), b.BlockInterval); var c = new BlockPolicy <DumbAction>(); Assert.Equal( new TimeSpan(0, 0, 5), c.BlockInterval); Assert.Throws <ArgumentOutOfRangeException>( () => new BlockPolicy <DumbAction>(tenSec.Negate(), 1024, 128)); Assert.Throws <ArgumentOutOfRangeException>( () => new BlockPolicy <DumbAction>(-5)); Assert.Throws <ArgumentOutOfRangeException>(() => new BlockPolicy <DumbAction>(tenSec, 0, 128)); Assert.Throws <ArgumentOutOfRangeException>(() => new BlockPolicy <DumbAction>(tenSec, 1024, 1024)); }
public void DoesTransactionFollowPolicy() { var validKey = new PrivateKey(); bool IsSignerValid(Transaction <DumbAction> tx) { var validAddress = validKey.PublicKey.ToAddress(); return(tx.Signer.Equals(validAddress)); } var policy = new BlockPolicy <DumbAction>(doesTransactionFollowPolicy: IsSignerValid); // Valid Transaction var validTx = _chain.MakeTransaction(validKey, new DumbAction[] { }); var expected = policy.DoesTransactionFollowsPolicy(validTx); Assert.True(expected); // Invalid Transaction var invalidKey = new PrivateKey(); var invalidTx = _chain.MakeTransaction(invalidKey, new DumbAction[] { }); expected = policy.DoesTransactionFollowsPolicy(invalidTx); Assert.False(expected); }
private Swarm <DumbAction> CreateSwarm( PrivateKey privateKey = null, AppProtocolVersion?appProtocolVersion = null, int tableSize = Kademlia.TableSize, int bucketSize = Kademlia.BucketSize, string host = null, int?listenPort = null, DateTimeOffset?createdAt = null, IEnumerable <IceServer> iceServers = null, DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered = null, IEnumerable <PublicKey> trustedAppProtocolVersionSigners = null, SwarmOptions options = null) { var policy = new BlockPolicy <DumbAction>(new MinerReward(1)); var fx = new DefaultStoreFixture(memory: true, blockAction: policy.BlockAction); var blockchain = TestUtils.MakeBlockChain(policy, fx.Store, fx.StateStore); return(CreateSwarm( blockchain, privateKey, appProtocolVersion, tableSize, bucketSize, host, listenPort, createdAt, iceServers, differentAppProtocolVersionEncountered, trustedAppProtocolVersionSigners, options)); }
public GraphQLTestBase(ITestOutputHelper output) { Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console().CreateLogger(); _output = output; var store = new DefaultStore(null); var genesisBlock = BlockChain <PolymorphicAction <ActionBase> > .MakeGenesisBlock(); var blockPolicy = new BlockPolicy <PolymorphicAction <ActionBase> >(blockAction: new RewardGold()); var blockChain = new BlockChain <PolymorphicAction <ActionBase> >( blockPolicy, store, store, 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(); }
public async Task PullBlocksByDifficulty() { var policy = new BlockPolicy <DumbAction>(new MinerReward(1)); var chain1 = MakeBlockChain( policy, new MemoryStore(), new TrieStateStore(new MemoryKeyValueStore())); var chain2 = MakeBlockChain( policy, new MemoryStore(), new TrieStateStore(new MemoryKeyValueStore())); var key1 = new PrivateKey(); var key2 = new PrivateKey(); var miner1 = CreateSwarm(chain1, key1); var miner2 = CreateSwarm(chain2, key2); await chain1.MineBlock(key1); await chain1.MineBlock(key2); long nextDifficulty = (long)chain1.Tip.TotalDifficulty + policy.GetNextBlockDifficulty(chain2); Block <DumbAction> block = MineNext( chain2.Tip, policy.GetHashAlgorithm, miner: ChainPrivateKey.PublicKey, difficulty: nextDifficulty, blockInterval: TimeSpan.FromMilliseconds(1) ).Evaluate(ChainPrivateKey, chain2); chain2.Append(block); Assert.True(chain1.Tip.Index > chain2.Tip.Index); Assert.True(chain1.Tip.TotalDifficulty < chain2.Tip.TotalDifficulty); try { await StartAsync(miner1); await StartAsync(miner2); await BootstrapAsync(miner2, miner1.AsPeer); await miner1.PullBlocksAsync(TimeSpan.FromSeconds(5), int.MaxValue, default); await miner1.BlockAppended.WaitAsync(); Assert.Equal(miner2.BlockChain.Count, miner1.BlockChain.Count); Assert.Equal(miner2.BlockChain.Tip, miner1.BlockChain.Tip); } finally { await StopAsync(miner1); await StopAsync(miner2); miner1.Dispose(); miner2.Dispose(); } }
public async Task PreloadWithFailedActions() { var policy = new BlockPolicy <ThrowException>(); var fx1 = new DefaultStoreFixture(memory: true); var fx2 = new DefaultStoreFixture(memory: true); var minerChain = TestUtils.MakeBlockChain(policy, fx1.Store, fx1.StateStore); var receiverChain = TestUtils.MakeBlockChain(policy, fx2.Store, fx2.StateStore); var minerKey = new PrivateKey(); Swarm <ThrowException> minerSwarm = CreateSwarm(minerChain, minerKey); Swarm <ThrowException> receiverSwarm = CreateSwarm(receiverChain); foreach (var unused in Enumerable.Range(0, 10)) { await minerSwarm.BlockChain.MineBlock(minerKey); } try { await StartAsync(minerSwarm); await receiverSwarm.AddPeersAsync(new[] { minerSwarm.AsPeer }, null); await receiverSwarm.PreloadAsync(TimeSpan.FromSeconds(1)); var action = new ThrowException { ThrowOnExecution = true }; var chainId = receiverChain.Id; Transaction <ThrowException> tx = Transaction <ThrowException> .Create( 0, new PrivateKey(), minerSwarm.BlockChain.Genesis.Hash, new[] { action }, ImmutableHashSet <Address> .Empty, DateTimeOffset.UtcNow ); Block <ThrowException> block = TestUtils.MineNext( minerChain.Tip, minerChain.Policy.GetHashAlgorithm, new[] { tx }, miner: TestUtils.ChainPrivateKey.PublicKey, difficulty: policy.GetNextBlockDifficulty(minerChain), blockInterval: TimeSpan.FromSeconds(1) ).Evaluate(TestUtils.ChainPrivateKey, minerChain); minerSwarm.BlockChain.Append(block, false, true, false); await receiverSwarm.PreloadAsync(TimeSpan.FromSeconds(1)); // Preloading should succeed even if action throws exception. Assert.Equal(minerChain.Tip, receiverChain.Tip); } finally { await StopAsync(minerSwarm); } }
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 async Task DoesTransactionFollowsPolicy() { var adminPrivateKey = new PrivateKey(); var adminAddress = adminPrivateKey.ToAddress(); var activatedPrivateKey = new PrivateKey(); var activatedAddress = activatedPrivateKey.ToAddress(); IBlockPolicy <PolymorphicAction <ActionBase> > policy = BlockPolicy.GetPolicy(10000); IRenderer <PolymorphicAction <ActionBase> > renderer = BlockPolicy.GetRenderer(); Block <PolymorphicAction <ActionBase> > genesis = MakeGenesisBlock( adminAddress, ImmutableHashSet.Create(activatedAddress).Add(adminAddress) ); using var store = new DefaultStore(null); var blockChain = new BlockChain <PolymorphicAction <ActionBase> >( policy, store, store, genesis, renderers: new[] { renderer } ); Transaction <PolymorphicAction <ActionBase> > txByStranger = Transaction <PolymorphicAction <ActionBase> > .Create( 0, new PrivateKey(), genesis.Hash, new PolymorphicAction <ActionBase>[] { } ); // 새로 만든 키는 활성화 유저 리스트에 없기 때문에 차단됩니다. Assert.False(policy.DoesTransactionFollowsPolicy(txByStranger)); var newActivatedPrivateKey = new PrivateKey(); var newActivatedAddress = newActivatedPrivateKey.ToAddress(); // 관리자 계정으로 활성화 시킵니다. Transaction <PolymorphicAction <ActionBase> > invitationTx = blockChain.MakeTransaction( adminPrivateKey, new PolymorphicAction <ActionBase>[] { new AddActivatedAccount(newActivatedAddress) } ); blockChain.StageTransaction(invitationTx); await blockChain.MineBlock(adminAddress); Transaction <PolymorphicAction <ActionBase> > txByNewActivated = Transaction <PolymorphicAction <ActionBase> > .Create( 0, newActivatedPrivateKey, genesis.Hash, new PolymorphicAction <ActionBase>[] { } ); // 활성화 된 계정이기 때문에 테스트에 성공합니다. Assert.True(policy.DoesTransactionFollowsPolicy(txByNewActivated)); }
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)); } }
/// <summary> /// Gets the hash code /// </summary> /// <returns>Hash code</returns> public override int GetHashCode() { unchecked // Overflow is fine, just wrap { var hashCode = 41; // Suitable nullity checks etc, of course :) if (Name != null) { hashCode = hashCode * 59 + Name.GetHashCode(); } if (MinPoolSize != null) { hashCode = hashCode * 59 + MinPoolSize.GetHashCode(); } if (MaxPoolSize != null) { hashCode = hashCode * 59 + MaxPoolSize.GetHashCode(); } if (QueueSize != null) { hashCode = hashCode * 59 + QueueSize.GetHashCode(); } if (MaxThreadAge != null) { hashCode = hashCode * 59 + MaxThreadAge.GetHashCode(); } if (KeepAliveTime != null) { hashCode = hashCode * 59 + KeepAliveTime.GetHashCode(); } if (BlockPolicy != null) { hashCode = hashCode * 59 + BlockPolicy.GetHashCode(); } if (ShutdownGraceful != null) { hashCode = hashCode * 59 + ShutdownGraceful.GetHashCode(); } if (Daemon != null) { hashCode = hashCode * 59 + Daemon.GetHashCode(); } if (ShutdownWaitTime != null) { hashCode = hashCode * 59 + ShutdownWaitTime.GetHashCode(); } if (Priority != null) { hashCode = hashCode * 59 + Priority.GetHashCode(); } return(hashCode); } }
private void Init( PrivateKey privateKey, string path, IEnumerable <Peer> peers, IEnumerable <IceServer> iceServers, string host, int?port, AppProtocolVersion appProtocolVersion, IEnumerable <PublicKey> trustedAppProtocolVersionSigners, IEnumerable <IRenderer <PolymorphicAction <ActionBase> > > renderers) { var policy = new BlockPolicy <PolymorphicAction <ActionBase> >( null, BlockInterval, 100000, 2048); PrivateKey = privateKey; Address = privateKey.PublicKey.ToAddress(); _store = new DefaultStore(path, flush: false); Block <PolymorphicAction <ActionBase> > genesis = Block <PolymorphicAction <ActionBase> > .Deserialize( File.ReadAllBytes(GenesisBlockPath) ); _blocks = new BlockChain <PolymorphicAction <ActionBase> >( policy, _store, _store, genesis, renderers ); if (!(host is null) || iceServers.Any()) { _swarm = new Swarm <PolymorphicAction <ActionBase> >( _blocks, privateKey, appProtocolVersion: appProtocolVersion, host: host, listenPort: port, iceServers: iceServers, differentAppProtocolVersionEncountered: DifferentAppProtocolVersionEncountered, trustedAppProtocolVersionSigners: trustedAppProtocolVersionSigners); _seedPeers = peers.Where(peer => peer.PublicKey != privateKey.PublicKey).ToImmutableList(); _trustedPeers = _seedPeers.Select(peer => peer.Address).ToImmutableHashSet(); } _cancellationTokenSource = new CancellationTokenSource(); }
public ActionEvaluatorTest(ITestOutputHelper output) { Log.Logger = _logger = new LoggerConfiguration() .MinimumLevel.Verbose() .Enrich.WithThreadId() .WriteTo.TestOutput(output) .CreateLogger() .ForContext <ActionEvaluatorTest>(); _policy = new BlockPolicy <DumbAction>( blockAction: new MinerReward(1), getMaxBlockBytes: _ => 50 * 1024); _storeFx = new DefaultStoreFixture(memory: true, blockAction: _policy.BlockAction); _txFx = new TxFixture(null); }
public SwarmTest(ITestOutputHelper output) { const string outputTemplate = "{Timestamp:HH:mm:ss}[@{SwarmId}][{ThreadId}] - {Message}"; Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .Enrich.WithThreadId() .WriteTo.TestOutput(output, outputTemplate: outputTemplate) .CreateLogger() .ForContext <SwarmTest>(); _output = output; var policy = new BlockPolicy <DumbAction>(new MinerReward(1)); _fx1 = new LiteDBStoreFixture(); _fx2 = new LiteDBStoreFixture(); _fx3 = new LiteDBStoreFixture(); _blockchains = new List <BlockChain <DumbAction> > { new BlockChain <DumbAction>(policy, _fx1.Store), new BlockChain <DumbAction>(policy, _fx2.Store), new BlockChain <DumbAction>(policy, _fx3.Store), }; _swarms = new List <Swarm <DumbAction> > { new Swarm <DumbAction>( _blockchains[0], new PrivateKey(), appProtocolVersion: 1, host: IPAddress.Loopback.ToString()), new Swarm <DumbAction>( _blockchains[1], new PrivateKey(), appProtocolVersion: 1, host: IPAddress.Loopback.ToString()), new Swarm <DumbAction>( _blockchains[2], new PrivateKey(), appProtocolVersion: 1, host: IPAddress.Loopback.ToString()), }; }
public void GetHashAlgorithm() { Assert.Equal(HashAlgorithmType.Of <SHA256>(), _policy.GetHashAlgorithm(0)); Assert.Equal(HashAlgorithmType.Of <SHA256>(), _policy.GetHashAlgorithm(1)); Assert.Equal(HashAlgorithmType.Of <SHA256>(), _policy.GetHashAlgorithm(2)); Assert.Equal(HashAlgorithmType.Of <SHA256>(), _policy.GetHashAlgorithm(10)); Assert.Equal(HashAlgorithmType.Of <SHA256>(), _policy.GetHashAlgorithm(15)); var p = new BlockPolicy <DumbAction>(hashAlgorithmGetter: i => i % 2 == 0 ? HashAlgorithmType.Of <MD5>() : HashAlgorithmType.Of <SHA1>() ); Assert.Equal(HashAlgorithmType.Of <MD5>(), p.GetHashAlgorithm(0)); Assert.Equal(HashAlgorithmType.Of <SHA1>(), p.GetHashAlgorithm(1)); Assert.Equal(HashAlgorithmType.Of <MD5>(), p.GetHashAlgorithm(2)); Assert.Equal(HashAlgorithmType.Of <MD5>(), p.GetHashAlgorithm(10)); Assert.Equal(HashAlgorithmType.Of <SHA1>(), p.GetHashAlgorithm(15)); }
MakeFixtureBlocksForPreloadAsyncCancellationTest() { Block <DumbAction>[] blocks = _fixtureBlocksForPreloadAsyncCancellationTest; if (blocks is null) { var policy = new BlockPolicy <DumbAction>(new MinerReward(1)); using (var storeFx = new DefaultStoreFixture(memory: true)) { var chain = TestUtils.MakeBlockChain(policy, storeFx.Store, storeFx.StateStore); Address miner = new PrivateKey().ToAddress(); var signer = new PrivateKey(); Address address = signer.ToAddress(); Log.Logger.Information("Fixture blocks:"); for (int i = 0; i < 20; i++) { for (int j = 0; j < 5; j++) { chain.MakeTransaction( signer, new[] { new DumbAction(address, $"Item{i}.{j}", idempotent: true) } ); } Block <DumbAction> block = await chain.MineBlock(miner); Log.Logger.Information(" #{0,2} {1}", block.Index, block.Hash); } var blockList = new List <Block <DumbAction> >(); for (var i = 1; i < chain.Count; i++) { Block <DumbAction> block = chain[i]; blockList.Add(block); } blocks = blockList.ToArray(); _fixtureBlocksForPreloadAsyncCancellationTest = blocks; } } return(blocks[1].Transactions.First().Actions.First().TargetAddress, blocks); }
protected StagePolicyTest() { _policy = new BlockPolicy <DumbAction>(); _fx = new DefaultStoreFixture(memory: true); _chain = new BlockChain <DumbAction>( _policy, StagePolicy, _fx.Store, _fx.StateStore, _fx.GenesisBlock ); _key = new PrivateKey(); _txs = Enumerable.Range(0, 5).Select(i => Transaction <DumbAction> .Create( i, _key, _fx.GenesisBlock.Hash, Enumerable.Empty <DumbAction>() ) ).ToArray(); }
public void DoesTransactionFollowsPolicyWithEmpty() { var adminPrivateKey = new PrivateKey(); var adminAddress = new Address(adminPrivateKey.PublicKey); IBlockPolicy <PolymorphicAction <ActionBase> > policy = BlockPolicy.GetPolicy(10000); Block <PolymorphicAction <ActionBase> > genesis = MakeGenesisBlock(adminAddress, ImmutableHashSet <Address> .Empty); using var store = new DefaultStore(null); _ = new BlockChain <PolymorphicAction <ActionBase> >( policy, store, genesis ); Transaction <PolymorphicAction <ActionBase> > tx = Transaction <PolymorphicAction <ActionBase> > .Create( 0, new PrivateKey(), genesis.Hash, new PolymorphicAction <ActionBase>[] { }); Assert.True(policy.DoesTransactionFollowsPolicy(tx)); }
public SwarmTest(ITestOutputHelper output) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() .Enrich.WithThreadId() .WriteTo.TestOutput(output, outputTemplate: "{Timestamp:HH:mm:ss}[@{Swarm_listenUrl}][{ThreadId}] - {Message}") .CreateLogger() .ForContext <SwarmTest>(); var policy = new BlockPolicy <BaseAction>(); _fx1 = new FileStoreFixture(); _fx2 = new FileStoreFixture(); _fx3 = new FileStoreFixture(); _blockchains = new List <BlockChain <BaseAction> > { new BlockChain <BaseAction>(policy, _fx1.Store), new BlockChain <BaseAction>(policy, _fx2.Store), new BlockChain <BaseAction>(policy, _fx3.Store), }; _swarms = new List <Swarm> { new Swarm( new PrivateKey(), new Uri($"inproc://swarmtest.a"), 3000), new Swarm( new PrivateKey(), new Uri($"inproc://swarmtest.b"), 3000), new Swarm( new PrivateKey(), new Uri($"inproc://swarmtest.c"), 3000), }; }
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 Task QueryAppProtocolVersion() { var fx = new DefaultStoreFixture(); var policy = new BlockPolicy <DumbAction>(); var blockchain = TestUtils.MakeBlockChain(policy, fx.Store, fx.StateStore); var apvKey = new PrivateKey(); var swarmKey = new PrivateKey(); AppProtocolVersion apv = AppProtocolVersion.Sign(apvKey, 1); string host = IPAddress.Loopback.ToString(); int port = FreeTcpPort(); using (var swarm = new Swarm <DumbAction>( blockchain, swarmKey, apv, host: host, listenPort: port)) { var peer = new BoundPeer(swarmKey.PublicKey, new DnsEndPoint(host, port)); // Before swarm starting... Assert.Throws <TimeoutException>(() => { peer.QueryAppProtocolVersion(timeout: TimeSpan.FromSeconds(1)); }); _ = swarm.StartAsync(); try { AppProtocolVersion receivedAPV = peer.QueryAppProtocolVersion(); Assert.Equal(apv, receivedAPV); } finally { await swarm.StopAsync(); } } }
public void Constructors() { var tenSec = new TimeSpan(0, 0, 10); var a = new BlockPolicy <DumbAction>( blockAction: null, blockInterval: tenSec, difficultyStability: 128, minimumDifficulty: 1024L); Assert.Equal(tenSec, a.BlockInterval); var b = new BlockPolicy <DumbAction>( blockInterval: TimeSpan.FromMilliseconds(65000)); Assert.Equal( new TimeSpan(0, 1, 5), b.BlockInterval); var c = new BlockPolicy <DumbAction>(); Assert.Equal( new TimeSpan(0, 0, 5), c.BlockInterval); }
public async Task DetermineCanonicalChain(short canonComparerType) { IComparer <IBlockExcerpt> canonComparer; switch (canonComparerType) { default: canonComparer = new TotalDifficultyComparer(); break; case 1: canonComparer = new AnonymousComparer <IBlockExcerpt>((a, b) => string.Compare( a.Hash.ToString(), b.Hash.ToString(), StringComparison.Ordinal ) ); break; } var policy = new BlockPolicy <DumbAction>( new MinerReward(1), canonicalChainComparer: canonComparer ); BlockChain <DumbAction> chain1 = TestUtils.MakeBlockChain( policy, new DefaultStore(null), new TrieStateStore(new MemoryKeyValueStore()) ); BlockChain <DumbAction> chain2 = TestUtils.MakeBlockChain( policy, new DefaultStore(null), new TrieStateStore(new MemoryKeyValueStore()) ); var key1 = new PrivateKey(); var key2 = new PrivateKey(); Swarm <DumbAction> miner1 = CreateSwarm(chain1, key1); Swarm <DumbAction> miner2 = CreateSwarm(chain2, key2); await chain1.MineBlock(key1); await chain1.MineBlock(key2); Block <DumbAction> bestBlock; switch (canonComparerType) { default: long nextDifficulty = (long)chain1.Tip.TotalDifficulty + policy.GetNextBlockDifficulty(chain2); bestBlock = TestUtils.MineNext( chain2.Tip, policy.GetHashAlgorithm, difficulty: nextDifficulty, blockInterval: TimeSpan.FromMilliseconds(1), miner: TestUtils.ChainPrivateKey.PublicKey ).Evaluate(TestUtils.ChainPrivateKey, chain2); _output.WriteLine("chain1's total difficulty: {0}", chain1.Tip.TotalDifficulty); _output.WriteLine("chain2's total difficulty: {0}", bestBlock.TotalDifficulty); break; case 1: string chain1TipHash = chain1.Tip.Hash.ToString(); string hashStr; do { bestBlock = TestUtils.MineNext( chain2.Tip, policy.GetHashAlgorithm, difficulty: policy.GetNextBlockDifficulty(chain2), blockInterval: TimeSpan.FromMilliseconds(1), miner: TestUtils.ChainPrivateKey.PublicKey ).Evaluate(TestUtils.ChainPrivateKey, chain2); hashStr = bestBlock.Hash.ToString(); _output.WriteLine("chain1's tip hash: {0}", chain1.Tip.Hash); _output.WriteLine("chain2's tip hash: {0}", bestBlock.Hash); _output.WriteLine(string.Empty); }while (string.Compare(chain1TipHash, hashStr, StringComparison.Ordinal) >= 0); break; } Assert.True( canonComparer.Compare( new BlockPerception(bestBlock), chain1.PerceiveBlock(chain1.Tip) ) > 0 ); chain2.Append(bestBlock); try { await StartAsync(miner1); await StartAsync(miner2); await BootstrapAsync(miner2, miner1.AsPeer); miner2.BroadcastBlock(bestBlock); _output.WriteLine("miner1 is waiting for a new block..."); await miner1.BlockReceived.WaitAsync(); Assert.Equal(miner1.BlockChain.Tip, bestBlock); Assert.Equal(miner2.BlockChain.Tip, bestBlock); } finally { await StopAsync(miner1); await StopAsync(miner2); miner1.Dispose(); miner2.Dispose(); } }
public async Task PreloadFromNominer() { Swarm <DumbAction> minerSwarm = _swarms[0]; Swarm <DumbAction> receiverSwarm = _swarms[1]; var fxForNominers = new StoreFixture[2]; fxForNominers[0] = new DefaultStoreFixture(memory: true); fxForNominers[1] = new DefaultStoreFixture(memory: true); var policy = new BlockPolicy <DumbAction>(); var blockChainsForNominers = new[] { TestUtils.MakeBlockChain(policy, fxForNominers[0].Store), TestUtils.MakeBlockChain(policy, fxForNominers[1].Store), }; var nominerSwarm0 = CreateSwarm(blockChainsForNominers[0]); var nominerSwarm1 = CreateSwarm(blockChainsForNominers[1]); BlockChain <DumbAction> minerChain = _blockchains[0]; BlockChain <DumbAction> receiverChain = _blockchains[1]; foreach (int i in Enumerable.Range(0, 10)) { await minerChain.MineBlock(_fx1.Address1); } var actualStates = new List <PreloadState>(); var progress = new Progress <PreloadState>(state => { lock (actualStates) { actualStates.Add(state); } }); try { await StartAsync(minerSwarm); await StartAsync(nominerSwarm0); await StartAsync(nominerSwarm1); minerSwarm.FindNextHashesChunkSize = 2; nominerSwarm0.FindNextHashesChunkSize = 2; nominerSwarm1.FindNextHashesChunkSize = 2; await nominerSwarm0.AddPeersAsync(new[] { minerSwarm.AsPeer }, null); await nominerSwarm0.PreloadAsync(); await nominerSwarm1.AddPeersAsync(new[] { nominerSwarm0.AsPeer }, null); await nominerSwarm1.PreloadAsync(); await receiverSwarm.AddPeersAsync(new[] { nominerSwarm1.AsPeer }, null); await receiverSwarm.PreloadAsync(TimeSpan.FromSeconds(15), progress); // Await 1 second to make sure all progresses is reported. await Task.Delay(1000); Assert.Equal(minerChain.BlockHashes, receiverChain.BlockHashes); var expectedStates = new List <PreloadState>(); for (var i = 1; i < minerChain.Count; i++) { var state = new BlockHashDownloadState { EstimatedTotalBlockHashCount = 10, ReceivedBlockHashCount = i, SourcePeer = nominerSwarm1.AsPeer as BoundPeer, }; expectedStates.Add(state); } for (var i = 1; i < minerChain.Count; i++) { var state = new BlockDownloadState { ReceivedBlockHash = minerChain[i].Hash, TotalBlockCount = 10, ReceivedBlockCount = i, SourcePeer = nominerSwarm1.AsPeer as BoundPeer, }; expectedStates.Add(state); } for (var i = 1; i < minerChain.Count; i++) { var state = new BlockVerificationState { VerifiedBlockHash = minerChain[i].Hash, TotalBlockCount = 10, VerifiedBlockCount = i, }; expectedStates.Add(state); } for (var i = 1; i < minerChain.Count; i++) { var state = new ActionExecutionState { ExecutedBlockHash = minerChain[i].Hash, TotalBlockCount = 10, ExecutedBlockCount = i, }; expectedStates.Add(state); } // FIXME: this test does not ensures block download in order Assert.Equal( expectedStates.ToHashSet(), actualStates.ToHashSet() ); } finally { await StopAsync(minerSwarm); await StopAsync(nominerSwarm0); await StopAsync(nominerSwarm1); await StopAsync(receiverSwarm); nominerSwarm0.Dispose(); nominerSwarm1.Dispose(); fxForNominers[0].Dispose(); fxForNominers[1].Dispose(); } }
public void GetNextBlockDifficulty() { var policy = new BlockPolicy <DumbAction>(new TimeSpan(3, 0, 0), 1024, 128); Block <DumbAction>[] blocks = MineBlocks( new[] { (0, 0), (1, 1024), (3, 1032), (7, 1040), (9, 1040), (13, 1048) }
public void GetNextBlockDifficulty() { var policy = new BlockPolicy <BaseAction>(new TimeSpan(3, 0, 0)); Block <BaseAction>[] blocks = MineBlocks( new[] { (0, 0), (1, 1), (3, 2), (7, 3), (9, 2), (13, 3) }
public async Task BroadcastBlockWithSkip() { var policy = new BlockPolicy <DumbAction>(new MinerReward(1)); var fx1 = new DefaultStoreFixture(memory: true); var blockChain = TestUtils.MakeBlockChain(policy, fx1.Store, fx1.StateStore); var privateKey = new PrivateKey(); var minerSwarm = CreateSwarm(blockChain, privateKey); var fx2 = new DefaultStoreFixture(memory: true); var receiverRenderer = new RecordingActionRenderer <DumbAction>(); var loggedRenderer = new LoggedActionRenderer <DumbAction>( receiverRenderer, _logger); var receiverChain = TestUtils.MakeBlockChain( policy, fx2.Store, fx2.StateStore, renderers: new[] { loggedRenderer }); Swarm <DumbAction> receiverSwarm = CreateSwarm(receiverChain); int renderCount = 0; receiverRenderer.RenderEventHandler += (_, a) => renderCount += a is DumbAction ? 1 : 0; Transaction <DumbAction>[] transactions = { fx1.MakeTransaction( new[] { new DumbAction(fx1.Address2, "foo"), new DumbAction(fx1.Address2, "bar"), }, timestamp: DateTimeOffset.MinValue, nonce: 0, privateKey: privateKey), fx1.MakeTransaction( new[] { new DumbAction(fx1.Address2, "baz"), new DumbAction(fx1.Address2, "qux"), }, timestamp: DateTimeOffset.MinValue.AddSeconds(5), nonce: 1, privateKey: privateKey), }; try { await StartAsync(minerSwarm); await StartAsync(receiverSwarm); await BootstrapAsync(receiverSwarm, minerSwarm.AsPeer); Block <DumbAction> block1 = TestUtils.MineNext( blockChain.Genesis, policy.GetHashAlgorithm, new[] { transactions[0] }, null, policy.GetNextBlockDifficulty(blockChain), miner: TestUtils.GenesisMiner.PublicKey ).Evaluate(TestUtils.GenesisMiner, blockChain); blockChain.Append(block1, true, true, false); Block <DumbAction> block2 = TestUtils.MineNext( block1, policy.GetHashAlgorithm, new[] { transactions[1] }, null, policy.GetNextBlockDifficulty(blockChain), miner: TestUtils.GenesisMiner.PublicKey ).Evaluate(TestUtils.GenesisMiner, blockChain); blockChain.Append(block2, true, true, false); Log.Debug("Ready to broadcast blocks."); minerSwarm.BroadcastBlock(block2); await receiverSwarm.BlockAppended.WaitAsync(); Assert.Equal(3, receiverChain.Count); Assert.Equal(4, renderCount); } finally { await StopAsync(minerSwarm); await StopAsync(receiverSwarm); fx1.Dispose(); minerSwarm.Dispose(); } }
public async Task QueryAppProtocolVersion(SwarmOptions.TransportType transportType) { var fx = new MemoryStoreFixture(); var policy = new BlockPolicy <DumbAction>(); var blockchain = MakeBlockChain(policy, fx.Store, fx.StateStore); var apvKey = new PrivateKey(); var swarmKey = new PrivateKey(); AppProtocolVersion apv = AppProtocolVersion.Sign(apvKey, 1); string host = IPAddress.Loopback.ToString(); int port = FreeTcpPort(); var option = new SwarmOptions { Type = transportType, }; using (var swarm = new Swarm <DumbAction>( blockchain, swarmKey, apv, host: host, listenPort: port, options: option)) { var peer = new BoundPeer(swarmKey.PublicKey, new DnsEndPoint(host, port)); // Before swarm starting... await Assert.ThrowsAsync <TimeoutException>(async() => { if (swarm.Transport is NetMQTransport) { peer.QueryAppProtocolVersionNetMQ(timeout: TimeSpan.FromSeconds(1)); } else if (swarm.Transport is TcpTransport) { await peer.QueryAppProtocolVersionTcp(timeout: TimeSpan.FromSeconds(1)); } else { throw new XunitException( "Each type of transport must have corresponding test case."); } }); _ = swarm.StartAsync(); try { AppProtocolVersion receivedAPV = default; if (swarm.Transport is NetMQTransport) { receivedAPV = peer.QueryAppProtocolVersionNetMQ(); } else if (swarm.Transport is TcpTransport) { receivedAPV = await peer.QueryAppProtocolVersionTcp(); } else { throw new XunitException( "Each type of transport must have corresponding test case."); } Assert.Equal(apv, receivedAPV); } finally { await swarm.StopAsync(); } } if (transportType == SwarmOptions.TransportType.NetMQTransport) { NetMQConfig.Cleanup(false); } }