コード例 #1
0
        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),
            };
        }
コード例 #2
0
ファイル: BlockPolicyTest.cs プロジェクト: jlhiskey/libplanet
        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)
                );
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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));
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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));
        }
コード例 #7
0
        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();
        }
コード例 #8
0
        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();
            }
        }
コード例 #9
0
        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);
            }
        }
コード例 #10
0
        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));
        }
コード例 #11
0
        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));
        }
コード例 #12
0
        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);
     }
 }
コード例 #14
0
ファイル: Agent.cs プロジェクト: moreal/planet-clicker-1
        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();
        }
コード例 #15
0
        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);
        }
コード例 #16
0
ファイル: SwarmTest.cs プロジェクト: minhoryang/libplanet
        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()),
            };
        }
コード例 #17
0
        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));
        }
コード例 #18
0
        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);
        }
コード例 #19
0
 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();
 }
コード例 #20
0
ファイル: BlockPolicyTest.cs プロジェクト: rheehot/lib9c
        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));
        }
コード例 #21
0
        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),
            };
        }
コード例 #22
0
        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),
コード例 #23
0
        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();
                }
            }
        }
コード例 #24
0
        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);
        }
コード例 #25
0
        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();
            }
        }
コード例 #26
0
        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();
            }
        }
コード例 #27
0
        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) }
コード例 #28
0
        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) }
コード例 #29
0
        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();
            }
        }
コード例 #30
0
        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);
            }
        }