private Swarm <DumbAction> CreateSwarm(
            PrivateKey privateKey = null,
            AppProtocolVersion?appProtocolVersion = null,
            string host    = null,
            int?listenPort = null,
            IEnumerable <IceServer> iceServers = null,
            DifferentAppProtocolVersionEncountered differentAppProtocolVersionEncountered = null,
            IEnumerable <PublicKey> trustedAppProtocolVersionSigners = null,
            SwarmOptions options             = null,
            IBlockPolicy <DumbAction> policy = null,
            Block <DumbAction> genesis       = null)
        {
            policy = policy ?? new BlockPolicy <DumbAction>(new MinerReward(1));
            var fx         = new MemoryStoreFixture(policy.BlockAction);
            var blockchain = MakeBlockChain(
                policy,
                fx.Store,
                fx.StateStore,
                genesisBlock: genesis
                );

            return(CreateSwarm(
                       blockchain,
                       privateKey,
                       appProtocolVersion,
                       host,
                       listenPort,
                       iceServers,
                       differentAppProtocolVersionEncountered,
                       trustedAppProtocolVersionSigners,
                       options));
        }
Exemple #2
0
 public BlockPolicyTest(ITestOutputHelper output)
 {
     _fx     = new DefaultStoreFixture();
     _output = output;
     _policy = new BlockPolicy <DumbAction>(
         null,
         TimeSpan.FromHours(3),
         1024,
         128);
     _chain = new BlockChain <DumbAction>(
         _policy,
         _fx.Store,
         _fx.StateStore,
         _fx.GenesisBlock);
     _emptyTransaction = new List <Transaction <DumbAction> >();
     _genesis          = _chain.Genesis;
     _validNext        = Block <DumbAction> .Mine(
         1,
         1024,
         _genesis.TotalDifficulty,
         _genesis.Miner.Value,
         _genesis.Hash,
         _genesis.Timestamp.AddSeconds(1),
         _emptyTransaction);
 }
Exemple #3
0
        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 DevLibplanetNodeService(
            LibplanetNodeServiceProperties <T> properties,
            IBlockPolicy <T> easyPolicy,
            IBlockPolicy <T> hardPolicy,
            IStagePolicy <T> stagePolicy,
            IEnumerable <IRenderer <T> > renderers,
            Func <Swarm <T>, Swarm <T>, PrivateKey, CancellationToken, Task> minerLoopAction,
            Progress <PreloadState> preloadProgress,
            Action <RPCException, string> exceptionHandlerAction,
            Action <bool> preloadStatusHandlerAction,
            bool ignoreBootstrapFailure = false
            ) : base(properties, easyPolicy, stagePolicy, renderers, null, preloadProgress, exceptionHandlerAction, preloadStatusHandlerAction, ignoreBootstrapFailure)
        {
            if (easyPolicy is null)
            {
                throw new ArgumentNullException(nameof(easyPolicy));
            }

            if (hardPolicy is null)
            {
                throw new ArgumentNullException(nameof(hardPolicy));
            }

            Log.Debug("Initializing node service.");

            var genesisBlock = LoadGenesisBlock(properties);

            var iceServers = properties.IceServers;

            (SubStore, SubStateStore) = LoadStore(
                properties.StorePath is null ? null : Path.Combine(properties.StorePath, "sub"),
                properties.StoreType,
                properties.StoreStatesCacheSize);

            SubChain = new BlockChain <T>(
                policy: hardPolicy,
                stagePolicy: stagePolicy,
                store: SubStore,
                stateStore: SubStateStore,
                genesisBlock: genesisBlock
                );

            _minerLoopAction = minerLoopAction;
            var subSwarmPrivateKey = new PrivateKey();

            Log.Debug(
                "Address of sub-swarm is: {address}",
                subSwarmPrivateKey.ToAddress());
            SubSwarm = new Swarm <T>(
                SubChain,
                subSwarmPrivateKey,
                properties.AppProtocolVersion,
                trustedAppProtocolVersionSigners: properties.TrustedAppProtocolVersionSigners,
                host: "localhost",
                listenPort: properties.Port + 1,
                iceServers: iceServers,
                workers: properties.Workers
                );
        }
Exemple #5
0
 internal BlockChain(IBlockPolicy <T> policy, IStore store, string @namespace)
     : this(
         policy,
         store,
         @namespace is null ? Guid.NewGuid() : Guid.Parse(@namespace)
         )
 {
 }
Exemple #6
0
 public BlockChain(IBlockPolicy <T> policy, IStore store)
     : this(
         policy,
         store,
         store.GetCanonicalNamespace()
         )
 {
 }
Exemple #7
0
 public BlockChain(IBlockPolicy <T> policy, IStore store)
     : this(
         policy,
         store,
         store.GetCanonicalChainId() ?? Guid.NewGuid()
         )
 {
 }
Exemple #8
0
        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));
        }
Exemple #9
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));
        }
Exemple #10
0
        public BlockChain(IBlockPolicy <T> policy, IStore store, Guid id)
        {
            _id          = id;
            Policy       = policy;
            Store        = store;
            Blocks       = new BlockSet <T>(store, _id.ToString());
            Transactions = new TransactionSet <T>(store, _id.ToString());
            Addresses    = new AddressTransactionSet <T>(store, _id.ToString());

            Store.InitNamespace(_id.ToString());
        }
Exemple #11
0
        internal Block <NullAction> GetGenesisBlock(IBlockPolicy <NullAction> policy)
        {
            var uri = new Uri(GenesisBlockPath);

            using (var client = new WebClient())
            {
                var serialized = client.DownloadData(uri);
                var dict       = (Bencodex.Types.Dictionary)Codec.Decode(serialized);
                return(BlockMarshaler.UnmarshalBlock <NullAction>(policy.GetHashAlgorithm, dict));
            }
        }
Exemple #12
0
        public BlockChain(IBlockPolicy <T> policy, IStore store, Guid id)
        {
            Id           = id;
            Policy       = policy;
            Store        = store;
            Blocks       = new BlockSet <T>(store);
            Transactions = new TransactionSet <T>(store);

            _rwlock = new ReaderWriterLockSlim(
                LockRecursionPolicy.SupportsRecursion);
        }
Exemple #13
0
        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);
        }
Exemple #14
0
        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));
        }
Exemple #15
0
        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();
            }
        }
Exemple #16
0
 public BlockPolicyTest(ITestOutputHelper output)
 {
     _fx     = new MemoryStoreFixture();
     _output = output;
     _policy = new BlockPolicy <DumbAction>(
         blockAction: null,
         blockInterval: TimeSpan.FromMilliseconds(3 * 60 * 60 * 1000));
     _stagePolicy = new VolatileStagePolicy <DumbAction>();
     _chain       = new BlockChain <DumbAction>(
         _policy,
         _stagePolicy,
         _fx.Store,
         _fx.StateStore,
         _fx.GenesisBlock);
 }
Exemple #17
0
 public BlockPolicyTest(ITestOutputHelper output)
 {
     _fx     = new DefaultStoreFixture();
     _output = output;
     _policy = new BlockPolicy <DumbAction>(
         null,
         TimeSpan.FromHours(3),
         1024,
         128);
     _chain = new BlockChain <DumbAction>(
         _policy,
         _fx.Store,
         _fx.StateStore,
         _fx.GenesisBlock);
 }
Exemple #18
0
        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 LibplanetNodeService(
            LibplanetNodeServiceProperties <T> properties,
            IBlockPolicy <T> blockPolicy,
            Func <BlockChain <T>, Swarm <T>, PrivateKey, CancellationToken, Task> minerLoopAction,
            Progress <PreloadState> preloadProgress,
            bool ignoreBootstrapFailure = false
            )
        {
            _properties = properties;

            var genesisBlock = LoadGenesisBlock(properties);

            var iceServers = _properties.IceServers;

            Store = LoadStore(
                _properties.StorePath,
                _properties.StoreType,
                _properties.StoreStatesCacheSize);

            var chainIds = Store.ListChainIds().ToList();

            Log.Debug($"Number of chain ids: {chainIds.Count()}");

            foreach (var chainId in chainIds)
            {
                Log.Debug($"chainId: {chainId}");
            }

            BlockChain       = new BlockChain <T>(blockPolicy, Store, genesisBlock, _properties.Render);
            _minerLoopAction = minerLoopAction;
            Swarm            = new Swarm <T>(
                BlockChain,
                _properties.PrivateKey,
                _properties.AppProtocolVersion,
                trustedAppProtocolVersionSigners: _properties.TrustedAppProtocolVersionSigners,
                host: _properties.Host,
                listenPort: _properties.Port,
                iceServers: iceServers,
                workers: 50,
                differentAppProtocolVersionEncountered: _properties.DifferentAppProtocolVersionEncountered
                );

            PreloadEnded   = new AsyncManualResetEvent();
            BootstrapEnded = new AsyncManualResetEvent();

            _preloadProgress        = preloadProgress;
            _ignoreBootstrapFailure = ignoreBootstrapFailure;
        }
Exemple #20
0
        internal BlockChain(IBlockPolicy <T> policy, IStore store, Guid id)
        {
            Id           = id;
            Policy       = policy;
            Store        = store;
            Blocks       = new BlockSet <T>(store);
            Transactions = new TransactionSet <T>(store);

            _rwlock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
            _txLock = new object();

            if (Store.GetCanonicalChainId() is null)
            {
                Store.SetCanonicalChainId(Id);
            }
        }
Exemple #21
0
        public static BlockChain <T> MakeBlockChain <T>(
            IBlockPolicy <T> policy,
            IStore store,
            IEnumerable <T> actions  = null,
            PrivateKey privateKey    = null,
            DateTimeOffset?timestamp = null,
            IEnumerable <IRenderer <T> > renderers = null,
            IStateStore stateStore = null,
            Block <T> genesisBlock = null
            )
            where T : IAction, new()
        {
            actions    = actions ?? ImmutableArray <T> .Empty;
            privateKey = privateKey ?? new PrivateKey(
                new byte[]
            {
                0xcf, 0x36, 0xec, 0xf9, 0xe4, 0x7c, 0x87, 0x9a, 0x0d, 0xbf,
                0x46, 0xb2, 0xec, 0xd8, 0x3f, 0xd2, 0x76, 0x18, 0x2a, 0xde,
                0x02, 0x65, 0x82, 0x5e, 0x3b, 0x8c, 0x6b, 0xa2, 0x14, 0x46,
                0x7b, 0x76,
            }
                );

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

            genesisBlock = genesisBlock ?? new Block <T>(
                0,
                0,
                0,
                new Nonce(new byte[] { 0x01, 0x00, 0x00, 0x00 }),
                GenesisMinerAddress,
                null,
                timestamp ?? DateTimeOffset.MinValue,
                new[] { tx, });
            return(new BlockChain <T>(
                       policy,
                       store,
                       stateStore ?? store as IStateStore,
                       genesisBlock,
                       renderers: renderers ?? new[] { new ValidatingActionRenderer <T>() }
                       ));
        }
Exemple #22
0
        public static BlockChain <NCAction> MakeBlockChain(
            BlockRenderer[] blockRenderers,
            IBlockPolicy <NCAction> policy      = null,
            IStagePolicy <NCAction> stagePolicy = null,
            IStore store           = null,
            IStateStore stateStore = null)
        {
            PrivateKey adminPrivateKey = new PrivateKey();

            policy ??= new BlockPolicy <NCAction>();
            stagePolicy ??= new VolatileStagePolicy <NCAction>();
            store ??= new DefaultStore(null);
            stateStore ??= new TrieStateStore(new DefaultKeyValueStore(null));
            Block <NCAction> genesis = MakeGenesisBlock(adminPrivateKey.ToAddress(), ImmutableHashSet <Address> .Empty);

            return(new BlockChain <NCAction>(policy, stagePolicy, store, stateStore, genesis, renderers: blockRenderers));
        }
Exemple #23
0
        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 BlockPolicyTest(ITestOutputHelper output)
 {
     _output = output;
     _blocks = new List <Block <DumbAction> >();
     _policy = new BlockPolicy <DumbAction>(
         TimeSpan.FromMilliseconds(5000),
         1024,
         128);
     _emptyTransaction = new List <Transaction <DumbAction> >();
     _genesis          = TestUtils.MineGenesis <DumbAction>();
     _validNext        = Block <DumbAction> .Mine(
         1,
         1024,
         _genesis.Miner.Value,
         _genesis.Hash,
         _genesis.Timestamp.AddSeconds(1),
         _emptyTransaction);
 }
Exemple #25
0
 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
         );
 }
Exemple #26
0
        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));
        }
        /// <summary>
        /// Checks if <paramref name="blocks"/> are invalid, and if that
        /// returns the reason.
        /// <para>Note that it returns <c>null</c> when blocks are
        /// <em>valid</em>.</para>
        /// </summary>
        /// <param name="policy"><see cref="IBlockPolicy{T}"/> to used for
        /// validation <paramref name="blocks"/>.</param>
        /// <param name="blocks">Consecutive <see cref="Block{T}"/>s to
        /// validate.</param>
        /// <param name="currentTime">The current time to be used to validate
        /// of <see cref="Block{T}.Timestamp"/>s.
        /// Usually <see cref="DateTimeOffset.UtcNow"/> is used.</param>
        /// <returns>The reason why the given <paramref name="blocks"/> are
        /// <em>invalid</em>, or <c>null</c> if <paramref name="blocks"/> are
        /// <em>valid</em>.</returns>
        /// <typeparam name="T">An <see cref="IAction"/> type.  It should match
        /// to <see cref="Block{T}"/>'s type parameter.</typeparam>
        /// <seealso cref="IBlockPolicy{T}"/>
        /// <seealso cref="IBlockPolicy{T}.ValidateNextBlock"/>
        public static InvalidBlockException ValidateBlocks <T>(
            this IBlockPolicy <T> policy,
            IReadOnlyList <Block <T> > blocks,
            DateTimeOffset currentTime)
            where T : IAction, new()
        {
            var tempBlocks = new List <Block <T> >();

            foreach (Block <T> block in blocks)
            {
                InvalidBlockException exception =
                    policy.ValidateNextBlock(tempBlocks, block);
                if (!(exception is null))
                {
                    return(exception);
                }

                tempBlocks.Add(block);
            }

            return(null);
        }
        public NineChroniclesNodeService(
            PrivateKey?minerPrivateKey,
            LibplanetNodeServiceProperties <NCAction> properties,
            Progress <PreloadState>?preloadProgress = null,
            bool ignoreBootstrapFailure             = false,
            bool ignorePreloadFailure = false,
            bool strictRendering      = false,
            bool authorizedMiner      = false,
            bool isDev          = false,
            int blockInterval   = 10000,
            int reorgInterval   = 0,
            TimeSpan txLifeTime = default,
            int minerCount      = 1
            )
        {
            MinerPrivateKey = minerPrivateKey;
            Properties      = properties;

            LogEventLevel logLevel          = LogEventLevel.Debug;
            var           blockPolicySource = new BlockPolicySource(Log.Logger, logLevel);
            // BlockPolicy shared through Lib9c.
            IBlockPolicy <NCAction>?blockPolicy = null;
            // Policies for dev mode.
            IBlockPolicy <NCAction>?easyPolicy  = null;
            IBlockPolicy <NCAction>?hardPolicy  = null;
            IStagePolicy <NCAction> stagePolicy =
                txLifeTime == default
                    ? new VolatileStagePolicy <NCAction>()
                    : new VolatileStagePolicy <NCAction>(txLifeTime);

            if (isDev)
            {
                easyPolicy = new ReorgPolicy(new RewardGold(), 1);
                hardPolicy = new ReorgPolicy(new RewardGold(), 2);
            }
            else
            {
                blockPolicy = blockPolicySource.GetPolicy(properties.MinimumDifficulty, properties.MaximumTransactions);
            }

            BlockRenderer      = blockPolicySource.BlockRenderer;
            ActionRenderer     = blockPolicySource.ActionRenderer;
            ExceptionRenderer  = new ExceptionRenderer();
            NodeStatusRenderer = new NodeStatusRenderer();
            var renderers      = new List <IRenderer <NCAction> >();
            var strictRenderer = new StrictRenderer(onError: exc =>
                                                    ExceptionRenderer.RenderException(
                                                        RPCException.InvalidRenderException,
                                                        exc.Message.Split("\n")[0]
                                                        )
                                                    );

            if (Properties.Render)
            {
                renderers.Add(blockPolicySource.BlockRenderer);
                renderers.Add(blockPolicySource.LoggedActionRenderer);
            }
            else if (Properties.LogActionRenders)
            {
                renderers.Add(blockPolicySource.BlockRenderer);
                // The following "nullRenderer" does nothing.  It's just for filling
                // the LoggedActionRenderer<T>() constructor's parameter:
                IActionRenderer <NCAction> nullRenderer =
                    new AnonymousActionRenderer <NCAction>();
                renderers.Add(
                    new LoggedActionRenderer <NCAction>(
                        nullRenderer,
                        Log.Logger,
                        logLevel
                        )
                    );
            }
            else
            {
                renderers.Add(blockPolicySource.LoggedBlockRenderer);
            }

            if (strictRendering)
            {
                Log.Debug(
                    $"Strict rendering is on. Add {nameof(StrictRenderer)}.");
                renderers.Add(strictRenderer);
            }

            async Task minerLoopAction(
                BlockChain <NCAction> chain,
                Swarm <NCAction> swarm,
                PrivateKey privateKey,
                CancellationToken cancellationToken)
            {
                var miner = new Miner(chain, swarm, privateKey, authorizedMiner);

                Log.Debug("Miner called.");
                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        long nextBlockIndex = chain.Tip.Index + 1;
                        bool authBlock      = blockPolicy is BlockPolicy bp
                                              // Copied from https://git.io/JLxNd
                                              && nextBlockIndex > 0 &&
                                              nextBlockIndex <= bp.AuthorizedMinersState?.ValidUntil &&
                                              nextBlockIndex % bp.AuthorizedMinersState?.Interval == 0;
                        if (swarm.Running && ((authorizedMiner && authBlock) || (!authorizedMiner && !authBlock)))
                        {
                            Log.Debug("Start mining.");

                            IEnumerable <Task <Block <NCAction> > > miners = Enumerable
                                                                             .Range(0, minerCount)
                                                                             .Select(_ => miner.MineBlockAsync(properties.MaximumTransactions, cancellationToken));
                            await Task.WhenAll(miners);
                        }
                        else
                        {
                            await Task.Delay(1000, cancellationToken);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Exception occurred.");
                    }
                }
            }

            async Task devMinerLoopAction(
                Swarm <NCAction> mainSwarm,
                Swarm <NCAction> subSwarm,
                PrivateKey privateKey,
                CancellationToken cancellationToken)
            {
                var miner = new ReorgMiner(mainSwarm, subSwarm, privateKey, reorgInterval);

                Log.Debug("Miner called.");
                while (!cancellationToken.IsCancellationRequested)
                {
                    try
                    {
                        if (mainSwarm.Running)
                        {
                            Log.Debug("Start mining.");
                            await miner.MineBlockAsync(properties.MaximumTransactions, cancellationToken);

                            await Task.Delay(blockInterval, cancellationToken);
                        }
                        else
                        {
                            await Task.Delay(1000, cancellationToken);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex, "Exception occurred.");
                    }
                }
            }

            if (isDev)
            {
                NodeService = new DevLibplanetNodeService <NCAction>(
                    Properties,
                    easyPolicy,
                    hardPolicy,
                    stagePolicy,
                    renderers,
                    devMinerLoopAction,
                    preloadProgress,
                    (code, msg) =>
                {
                    ExceptionRenderer.RenderException(code, msg);
                    Log.Error(msg);
                },
                    isPreloadStarted => { NodeStatusRenderer.PreloadStatus(isPreloadStarted); },
                    ignoreBootstrapFailure
                    );
            }
            else
            {
                NodeService = new LibplanetNodeService <NCAction>(
                    Properties,
                    blockPolicy,
                    stagePolicy,
                    renderers,
                    minerLoopAction,
                    preloadProgress,
                    (code, msg) =>
                {
                    ExceptionRenderer.RenderException(code, msg);
                    Log.Error(msg);
                },
                    isPreloadStarted =>
                {
                    NodeStatusRenderer.PreloadStatus(isPreloadStarted);
                },
                    ignoreBootstrapFailure,
                    ignorePreloadFailure
                    );
            }

            strictRenderer.BlockChain = NodeService.BlockChain ?? throw new Exception("BlockChain is null.");
            if (NodeService.BlockChain?.GetState(AuthorizedMinersState.Address) is Dictionary ams &&
                blockPolicy is BlockPolicy bp)
            {
                bp.AuthorizedMinersState = new AuthorizedMinersState(ams);
            }

            if (authorizedMiner && blockPolicy is BlockPolicy {
                AuthorizedMinersState : null
            })
Exemple #29
0
        public void ValidateNextBlockWithManyTransactionsPerSigner()
        {
            var adminPrivateKey   = new PrivateKey();
            var adminPublicKey    = adminPrivateKey.PublicKey;
            var blockPolicySource = new BlockPolicySource(Logger.None);
            IBlockPolicy <PolymorphicAction <ActionBase> > policy = blockPolicySource.GetPolicy(
                minimumDifficulty: 10_000,
                hashAlgorithmTypePolicy: null,
                maxBlockBytesPolicy: null,
                minTransactionsPerBlockPolicy: null,
                maxTransactionsPerBlockPolicy: MaxTransactionsPerBlockPolicy
                .Default
                .Add(new SpannedSubPolicy <int>(0, null, null, 10)),
                maxTransactionsPerSignerPerBlockPolicy: MaxTransactionsPerSignerPerBlockPolicy
                .Default
                .Add(new SpannedSubPolicy <int>(2, null, null, 5)),
                authorizedMinersPolicy: null,
                permissionedMinersPolicy: null);
            IStagePolicy <PolymorphicAction <ActionBase> > stagePolicy =
                new VolatileStagePolicy <PolymorphicAction <ActionBase> >();
            Block <PolymorphicAction <ActionBase> > genesis =
                MakeGenesisBlock(adminPublicKey.ToAddress(), ImmutableHashSet <Address> .Empty);

            using var store = new DefaultStore(null);
            var stateStore = new TrieStateStore(new MemoryKeyValueStore());
            var blockChain = new BlockChain <PolymorphicAction <ActionBase> >(
                policy,
                stagePolicy,
                store,
                stateStore,
                genesis
                );

            int nonce = 0;

            List <Transaction <PolymorphicAction <ActionBase> > > GenerateTransactions(int count)
            {
                var list = new List <Transaction <PolymorphicAction <ActionBase> > >();

                for (int i = 0; i < count; i++)
                {
                    list.Add(Transaction <PolymorphicAction <ActionBase> > .Create(
                                 nonce++,
                                 adminPrivateKey,
                                 genesis.Hash,
                                 new PolymorphicAction <ActionBase>[] { }
                                 ));
                }

                return(list);
            }

            Assert.Equal(1, blockChain.Count);
            Block <PolymorphicAction <ActionBase> > block1 = new BlockContent <PolymorphicAction <ActionBase> >
            {
                Index           = 1,
                Difficulty      = policy.GetNextBlockDifficulty(blockChain),
                TotalDifficulty = blockChain.Tip.Difficulty + policy.GetNextBlockDifficulty(blockChain),
                PublicKey       = adminPublicKey,
                PreviousHash    = blockChain.Tip.Hash,
                Timestamp       = DateTimeOffset.MinValue,
                Transactions    = GenerateTransactions(10),
            }.Mine(policy.GetHashAlgorithm(1)).Evaluate(adminPrivateKey, blockChain);

            // Should be fine since policy hasn't kicked in yet.
            blockChain.Append(block1);
            Assert.Equal(2, blockChain.Count);
            Assert.True(blockChain.ContainsBlock(block1.Hash));

            Block <PolymorphicAction <ActionBase> > block2 = new BlockContent <PolymorphicAction <ActionBase> >
            {
                Index           = 2,
                Difficulty      = policy.GetNextBlockDifficulty(blockChain),
                TotalDifficulty = blockChain.Tip.Difficulty + policy.GetNextBlockDifficulty(blockChain),
                PublicKey       = adminPublicKey,
                PreviousHash    = blockChain.Tip.Hash,
                Timestamp       = DateTimeOffset.MinValue,
                Transactions    = GenerateTransactions(10),
            }.Mine(policy.GetHashAlgorithm(2)).Evaluate(adminPrivateKey, blockChain);

            // Subpolicy kicks in.
            Assert.Throws <InvalidBlockTxCountPerSignerException>(() => blockChain.Append(block2));
            Assert.Equal(2, blockChain.Count);
            Assert.False(blockChain.ContainsBlock(block2.Hash));
            // Since failed, roll back nonce.
            nonce -= 10;

            // Limit should also pass.
            Block <PolymorphicAction <ActionBase> > block3 = new BlockContent <PolymorphicAction <ActionBase> >
            {
                Index           = 2,
                Difficulty      = policy.GetNextBlockDifficulty(blockChain),
                TotalDifficulty = blockChain.Tip.Difficulty + policy.GetNextBlockDifficulty(blockChain),
                PublicKey       = adminPublicKey,
                PreviousHash    = blockChain.Tip.Hash,
                Timestamp       = DateTimeOffset.MinValue,
                Transactions    = GenerateTransactions(5),
            }.Mine(policy.GetHashAlgorithm(2)).Evaluate(adminPrivateKey, blockChain);

            blockChain.Append(block3);
            Assert.Equal(3, blockChain.Count);
            Assert.True(blockChain.ContainsBlock(block3.Hash));
        }
Exemple #30
0
        public async Task ValidateNextBlockTx()
        {
            var adminPrivateKey = new PrivateKey();
            var adminAddress    = adminPrivateKey.ToAddress();

            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)
                );

            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> > txByStranger =
                Transaction <PolymorphicAction <ActionBase> > .Create(
                    0,
                    new PrivateKey(),
                    genesis.Hash,
                    new PolymorphicAction <ActionBase>[] { }
                    );

            // New private key which is not in activated addresses list is blocked.
            Assert.NotNull(policy.ValidateNextBlockTx(blockChain, txByStranger));

            var newActivatedPrivateKey = new PrivateKey();
            var newActivatedAddress    = newActivatedPrivateKey.ToAddress();

            // Activate with admin account.
            blockChain.MakeTransaction(
                adminPrivateKey,
                new PolymorphicAction <ActionBase>[] { new AddActivatedAccount(newActivatedAddress) }
                );
            await blockChain.MineBlock(adminPrivateKey);

            Transaction <PolymorphicAction <ActionBase> > txByNewActivated =
                Transaction <PolymorphicAction <ActionBase> > .Create(
                    0,
                    newActivatedPrivateKey,
                    genesis.Hash,
                    new PolymorphicAction <ActionBase>[] { }
                    );

            // Test success because the key is activated.
            Assert.Null(policy.ValidateNextBlockTx(blockChain, txByNewActivated));

            var singleAction = new PolymorphicAction <ActionBase>[]
            {
                new DailyReward(),
            };
            var manyActions = new PolymorphicAction <ActionBase>[]
            {
                new DailyReward(),
                new DailyReward(),
            };
            Transaction <PolymorphicAction <ActionBase> > txWithSingleAction =
                Transaction <PolymorphicAction <ActionBase> > .Create(
                    0,
                    newActivatedPrivateKey,
                    genesis.Hash,
                    singleAction
                    );

            Transaction <PolymorphicAction <ActionBase> > txWithManyActions =
                Transaction <PolymorphicAction <ActionBase> > .Create(
                    0,
                    newActivatedPrivateKey,
                    genesis.Hash,
                    manyActions
                    );

            // Transaction with more than two actions is rejected.
            Assert.Null(policy.ValidateNextBlockTx(blockChain, txWithSingleAction));
            Assert.NotNull(policy.ValidateNextBlockTx(blockChain, txWithManyActions));
        }