Esempio n. 1
0
        protected void stepDown(IConsensus model, int term)
        {
            if (_state == ServerState.Leader || _state == ServerState.Candidate)
                _state = ServerState.Follower;

            _persistedState.UpdateState(term, null);
            if (isElectionTimeout(model))
                updateElectionAlarm(model);
        }
Esempio n. 2
0
        /// <inheritdoc />
        public override void Initialize()
        {
            this.Logger.LogTrace("()");

            base.Initialize();

            this.consensus = this.Parent.Network.Consensus;
            this.smartContractPosParent = (SmartContractPosConsensusRuleEngine)this.Parent;
            this.stakeChain             = this.smartContractPosParent.StakeChain;
            this.stakeValidator         = this.smartContractPosParent.StakeValidator;

            this.Logger.LogTrace("(-)");
        }
Esempio n. 3
0
        public void MineGenesisAndPremineBlocks()
        {
            int premineBlockCount = 2;

            var addressUsed = TestHelper.MineBlocks(this.PremineNodeWithCoins, this.PremineWallet, this.PremineWalletPassword, this.PremineWalletAccount, premineBlockCount).AddressUsed;

            // Since the pre-mine will not be immediately spendable, the transactions have to be counted directly from the address.
            addressUsed.Transactions.Count().Should().Be(premineBlockCount);

            IConsensus consensus = this.PremineNodeWithCoins.FullNode.Network.Consensus;

            addressUsed.Transactions.Sum(s => s.Amount).Should().Be(consensus.PremineReward + consensus.ProofOfWorkReward);
        }
Esempio n. 4
0
        /// <summary>
        /// Initializes a new instance of <see cref="Blockchain"/> using the given parameters.
        /// </summary>
        /// <exception cref="ArgumentNullException"/>
        /// <param name="fileMan">File manager</param>
        /// <param name="blockVerifier">Block verifier</param>
        /// <param name="consensus">Consensus rules</param>
        public Blockchain(IFileManager fileMan, BlockVerifier blockVerifier, IConsensus consensus)
        {
            FileMan   = fileMan ?? throw new ArgumentNullException(nameof(fileMan));
            Consensus = consensus ?? throw new ArgumentNullException(nameof(consensus));
            BlockVer  = blockVerifier ?? throw new ArgumentNullException(nameof(blockVerifier));

            // TODO: find a better initial capacity
            headerList = new List <BlockHeader>(700_000);
            ReadHeaders();
            ReadBlockInfo();

            // TODO: read blocks and others
        }
Esempio n. 5
0
        public void RegisterRules(IConsensus consensus)
        {
            consensus.HeaderValidationRules = new List <IHeaderValidationConsensusRule>()
            {
                new HeaderTimeChecksPoARule(),
                new StratisHeaderVersionRule(),
                new PoAHeaderDifficultyRule(),
                new PoAHeaderSignatureRule()
            };

            consensus.IntegrityValidationRules = new List <IIntegrityValidationConsensusRule>()
            {
                new BlockMerkleRootRule(),
                new PoAIntegritySignatureRule()
            };

            consensus.PartialValidationRules = new List <IPartialValidationConsensusRule>()
            {
                new SetActivationDeploymentsPartialValidationRule(),

                // rules that are inside the method ContextualCheckBlock
                new TransactionLocktimeActivationRule(), // implements BIP113
                new CoinbaseHeightActivationRule(),      // implements BIP34
                new BlockSizeRule(),

                // rules that are inside the method CheckBlock
                new EnsureCoinbaseRule(),
                new CheckPowTransactionRule(),
                new CheckSigOpsRule(),
                new AllowedScriptTypeRule(),
                new ContractTransactionValidationRule(new CallDataSerializer(new ContractPrimitiveSerializer(this.network)), new List <IContractTransactionValidationLogic>
                {
                    new SmartContractFormatLogic()
                })
            };

            consensus.FullValidationRules = new List <IFullValidationConsensusRule>()
            {
                new SetActivationDeploymentsFullValidationRule(),

                // rules that require the store to be loaded (coinview)
                new LoadCoinviewRule(),
                new TransactionDuplicationActivationRule(), // implements BIP30
                new TxOutSmartContractExecRule(),
                new OpSpendRule(),
                new CanGetSenderRule(new SenderRetriever()),
                new P2PKHNotContractRule(),
                new SmartContractPoACoinviewRule(),
                new SaveCoinviewRule()
            };
        }
        public void RegisterRules(IConsensus consensus)
        {
            consensus.HeaderValidationRules = new List <IHeaderValidationConsensusRule>()
            {
                new HeaderTimeChecksRule(),
                new HeaderTimeChecksPosRule(),
                new StratisBigFixPosFutureDriftRule(),
                new CheckDifficultyPosRule(),
                new StratisHeaderVersionRule(),
            };

            consensus.IntegrityValidationRules = new List <IIntegrityValidationConsensusRule>()
            {
                new BlockMerkleRootRule(),
                new SmartContractPosBlockSignatureRule(),
            };

            consensus.PartialValidationRules = new List <IPartialValidationConsensusRule>()
            {
                new SetActivationDeploymentsPartialValidationRule(),

                new CheckDifficultyHybridRule(),
                new PosTimeMaskRule(),

                // rules that are inside the method ContextualCheckBlock
                new TransactionLocktimeActivationRule(), // implements BIP113
                new CoinbaseHeightActivationRule(),      // implements BIP34
                new WitnessCommitmentsRule(),            // BIP141, BIP144
                new BlockSizeRule(),

                new PosBlockContextRule(), // TODO: this rule needs to be implemented

                // rules that are inside the method CheckBlock
                new EnsureCoinbaseRule(),
                new CheckPowTransactionRule(),
                new CheckPosTransactionRule(),
                new CheckSigOpsRule(),
                new PosCoinstakeRule(),
                new P2PKHNotContractRule()
            };

            consensus.FullValidationRules = new List <IFullValidationConsensusRule>()
            {
                new SetActivationDeploymentsFullValidationRule(),

                new SmartContractLoadCoinviewRule(),
                new TransactionDuplicationActivationRule(), // implements BIP30
                new SmartContractPosCoinviewRule(),         // implements BIP68, MaxSigOps and BlockReward calculation
                new SmartContractSaveCoinviewRule()
            };
        }
        protected void RegisterRules(IConsensus consensus)
        {
            consensus.ConsensusRules
            .Register <HeaderTimeChecksRule>()
            .Register <HeaderTimeChecksPosRule>()
            .Register <StratisBugFixPosFutureDriftRule>()
            .Register <CheckDifficultyPosRule>()
            .Register <StratisHeaderVersionRule>()
            .Register <ProvenHeaderSizeRule>()
            .Register <ProvenHeaderCoinstakeRule>();

            consensus.ConsensusRules
            .Register <BlockMerkleRootRule>()
            .Register <PosBlockSignatureRepresentationRule>()
            .Register <PosBlockSignatureRule>();

            consensus.ConsensusRules
            .Register <SetActivationDeploymentsPartialValidationRule>()
            .Register <PosTimeMaskRule>()

            // rules that are inside the method ContextualCheckBlock
            .Register <TransactionLocktimeActivationRule>()
            .Register <CoinbaseHeightActivationRule>()
            .Register <WitnessCommitmentsRule>()
            .Register <BlockSizeRule>()

            // rules that are inside the method CheckBlock
            .Register <EnsureCoinbaseRule>()
            .Register <CheckPowTransactionRule>()
            .Register <CheckPosTransactionRule>()
            .Register <CheckSigOpsRule>()
            .Register <PosCoinstakeRule>();

            consensus.ConsensusRules
            .Register <SetActivationDeploymentsFullValidationRule>()

            .Register <CheckDifficultyHybridRule>()

            // rules that require the store to be loaded (coinview)
#pragma warning disable CS0618                // Type or member is obsolete
            .Register <LoadCoinviewRule>()
#pragma warning restore CS0618                // Type or member is obsolete
            .Register <TransactionDuplicationActivationRule>()
            .Register <CheckPosUtxosetRule>() // implements BIP68, MaxSigOps and BlockReward calculation
                                              // Place the PosColdStakingRule after the PosCoinviewRule to ensure that all input scripts have been evaluated
                                              // and that the "IsColdCoinStake" flag would have been set by the OP_CHECKCOLDSTAKEVERIFY opcode if applicable.
            .Register <PosColdStakingRule>()
#pragma warning disable CS0618                // Type or member is obsolete
            .Register <SaveCoinviewRule>();
#pragma warning restore CS0618                // Type or member is obsolete
        }
Esempio n. 8
0
        public void RegisterRules(IConsensus consensus)
        {
            consensus.HeaderValidationRules = new List <IHeaderValidationConsensusRule>()
            {
                new HeaderTimeChecksRule(),
                new HeaderTimeChecksPosRule(),
                new StratisBugFixPosFutureDriftRule(),
                new CheckDifficultyPosRule(),
                new StratisHeaderVersionRule(),
            };

            consensus.IntegrityValidationRules = new List <IIntegrityValidationConsensusRule>()
            {
                new BlockMerkleRootRule(),
                new PosBlockSignatureRepresentationRule(),
                new SmartContractPosBlockSignatureRule(),
            };

            consensus.PartialValidationRules = new List <IPartialValidationConsensusRule>()
            {
                new SetActivationDeploymentsPartialValidationRule(),

                new PosTimeMaskRule(),

                // rules that are inside the method ContextualCheckBlock
                new TransactionLocktimeActivationRule(), // implements BIP113
                new CoinbaseHeightActivationRule(),      // implements BIP34
                new WitnessCommitmentsRule(),            // BIP141, BIP144
                new BlockSizeRule(),

                // rules that are inside the method CheckBlock
                new EnsureCoinbaseRule(),
                new CheckPowTransactionRule(),
                new CheckPosTransactionRule(),
                new CheckSigOpsRule(),
                new PosCoinstakeRule()
            };

            // TODO: When looking to make PoS work again, will need to add several of the smart contract consensus rules below (see PoA and PoW implementations)
            consensus.FullValidationRules = new List <IFullValidationConsensusRule>()
            {
                new SetActivationDeploymentsFullValidationRule(),

                new CheckDifficultyHybridRule(),
                new LoadCoinviewRule(),
                new TransactionDuplicationActivationRule(), // implements BIP30
                new SmartContractPosCoinviewRule(),         // implements BIP68, MaxSigOps and BlockReward calculation
                new SaveCoinviewRule()
            };
        }
        /// <inheritdoc />
        public override void Initialize()
        {
            this.Logger.LogTrace("()");

            base.Initialize();

            this.consensus = this.Parent.Network.Consensus;
            var consensusRules = (PosConsensusRuleEngine)this.Parent;

            this.stakeValidator = consensusRules.StakeValidator;
            this.stakeChain     = consensusRules.StakeChain;

            this.Logger.LogTrace("(-)");
        }
Esempio n. 10
0
        public void VerifyCoinbasePrimaryTest(IConsensus consensus, ITransaction tx, bool expB, string expErr, int expOpCount)
        {
            var verifier = new TransactionVerifier(false, new MockUtxoDatabase(), new MockMempool(null), consensus)
            {
                BlockHeight = MockHeight
            };

            bool actualB = verifier.VerifyCoinbasePrimary(tx, out string error);

            Assert.Equal(expB, actualB);
            Assert.Equal(expErr, error);
            Assert.Equal(expOpCount, verifier.TotalSigOpCount);
            Assert.Equal(0UL, verifier.TotalFee);
        }
Esempio n. 11
0
        public void RegisterRules(IConsensus consensus)
        {
            consensus.HeaderValidationRules = new List <IHeaderValidationConsensusRule>()
            {
                new HeaderTimeChecksRule(),
                new CheckDifficultyPowRule(),
                new BitcoinActivationRule(),
                new BitcoinHeaderVersionRule()
            };

            consensus.IntegrityValidationRules = new List <IIntegrityValidationConsensusRule>()
            {
                new BlockMerkleRootRule()
            };

            consensus.PartialValidationRules = new List <IPartialValidationConsensusRule>()
            {
                new SetActivationDeploymentsPartialValidationRule(),

                new TransactionLocktimeActivationRule(), // implements BIP113
                new CoinbaseHeightActivationRule(),      // implements BIP34
                new WitnessCommitmentsRule(),            // BIP141, BIP144
                new BlockSizeRule(),

                // rules that are inside the method CheckBlock
                new EnsureCoinbaseRule(),
                new CheckPowTransactionRule(),
                new CheckSigOpsRule(),
                new AllowedScriptTypeRule(),
                new ContractTransactionValidationRule(new CallDataSerializer(new ContractPrimitiveSerializer(this.network)), new List <IContractTransactionValidationLogic>
                {
                    new SmartContractFormatLogic()
                })
            };

            consensus.FullValidationRules = new List <IFullValidationConsensusRule>()
            {
                new SetActivationDeploymentsFullValidationRule(),

                new LoadCoinviewRule(),
                new TransactionDuplicationActivationRule(), // implements BIP30
                new TxOutSmartContractExecRule(),
                new OpSpendRule(),
                new CanGetSenderRule(new SenderRetriever()),
                new P2PKHNotContractRule(),
                new SmartContractPowCoinviewRule(), // implements BIP68, MaxSigOps and BlockReward
                new SaveCoinviewRule()
            };
        }
 protected void RegisterMempoolRules(IConsensus consensus)
 {
     consensus.MempoolRules = new List <Type>()
     {
         typeof(CheckConflictsMempoolRule),
         typeof(CheckCoinViewMempoolRule),
         typeof(CreateMempoolEntryMempoolRule),
         typeof(CheckSigOpsMempoolRule),
         typeof(CheckFeeMempoolRule),
         typeof(CheckRateLimitMempoolRule),
         typeof(CheckAncestorsMempoolRule),
         typeof(CheckReplacementMempoolRule),
         typeof(CheckAllInputsMempoolRule)
     };
 }
Esempio n. 13
0
        public void VerifyCoinbaseOutputTest(IConsensus c, ITransaction tx, ulong fee, bool expB, string expErr)
        {
            var verifier = new TransactionVerifier(false, new MockUtxoDatabase(), new MockMempool(null), c)
            {
                TotalFee        = fee,
                TotalSigOpCount = 987
            };

            bool actualB = verifier.VerifyCoinbaseOutput(tx, out string error);

            Assert.Equal(expB, actualB);
            Assert.Equal(expErr, error);
            Assert.Equal(987, verifier.TotalSigOpCount); // SigOps aren't counted/changed here anymore
            Assert.Equal(fee, verifier.TotalFee);        // Fee shouldn't change
        }
Esempio n. 14
0
        protected virtual void RegisterRules(IConsensus consensus)
        {
            // IHeaderValidationConsensusRule
            consensus.ConsensusRules
            .Register <HeaderTimeChecksPoARule>()
            .Register <PoAHeaderDifficultyRule>()
            .Register <PoAHeaderSignatureRule>();
            // ------------------------------------------------------

            // IIntegrityValidationConsensusRule
            consensus.ConsensusRules
            .Register <BlockMerkleRootRule>()
            .Register <PoAIntegritySignatureRule>();
            // ------------------------------------------------------

            // IPartialValidationConsensusRule
            consensus.ConsensusRules
            .Register <SetActivationDeploymentsPartialValidationRule>()

            // Rules that are inside the method ContextualCheckBlock
            .Register <TransactionLocktimeActivationRule>()
            .Register <CoinbaseHeightActivationRule>()
            .Register <BlockSizeRule>()

            // Rules that are inside the method CheckBlock
            .Register <EnsureCoinbaseRule>()
            .Register <CheckPowTransactionRule>()
            .Register <CheckSigOpsRule>()

            .Register <PoAVotingCoinbaseOutputFormatRule>();
            // ------------------------------------------------------

            // IFullValidationConsensusRule
            consensus.ConsensusRules
            .Register <SetActivationDeploymentsFullValidationRule>()

            // Rules that require the store to be loaded (coinview)
#pragma warning disable CS0618                                 // Type or member is obsolete
            .Register <LoadCoinviewRule>()
#pragma warning restore CS0618                                 // Type or member is obsolete
            .Register <TransactionDuplicationActivationRule>() // implements BIP30

            .Register <PoACoinviewRule>()
#pragma warning disable CS0618 // Type or member is obsolete
            .Register <SaveCoinviewRule>();
#pragma warning restore CS0618 // Type or member is obsolete
            // ------------------------------------------------------
        }
 public static void RegisterMempoolRules(IConsensus consensus)
 {
     consensus.MempoolRules = new List <Type>()
     {
         typeof(CheckConflictsMempoolRule),
         typeof(StraxCoinViewMempoolRule),
         typeof(CreateMempoolEntryMempoolRule),
         typeof(CheckSigOpsMempoolRule),
         typeof(StraxTransactionFeeMempoolRule),
         typeof(CheckRateLimitMempoolRule),
         typeof(CheckAncestorsMempoolRule),
         typeof(CheckReplacementMempoolRule),
         typeof(CheckAllInputsMempoolRule),
         typeof(CheckTxOutDustRule)
     };
 }
Esempio n. 16
0
 protected virtual void RegisterMempoolRules(IConsensus consensus)
 {
     // TODO: These are currently the PoW/PoS rules as PoA does not have smart contracts by itself. Are other specialised rules needed?
     consensus.MempoolRules = new List <Type>()
     {
         typeof(CheckConflictsMempoolRule),
         typeof(CheckCoinViewMempoolRule),
         typeof(CreateMempoolEntryMempoolRule),
         typeof(CheckSigOpsMempoolRule),
         typeof(CheckFeeMempoolRule),
         typeof(CheckRateLimitMempoolRule),
         typeof(CheckAncestorsMempoolRule),
         typeof(CheckReplacementMempoolRule),
         typeof(CheckAllInputsMempoolRule)
     };
 }
Esempio n. 17
0
        protected void startNewElection(IConsensus model)
        {
            if ((_state == ServerState.Follower || _state == ServerState.Candidate) &&
                isElectionTimeout(model))
            {
                updateElectionAlarm(model);
                _persistedState.UpdateState(_persistedState.Term + 1, _id);
                _state = ServerState.Candidate;

                //only request from peers that are allowed to vote
                foreach (var peer in _peers)
                    peer.Reset();

                Console.WriteLine("{0}: Starting new election for term {1}", _id, _persistedState.Term);
            }
        }
Esempio n. 18
0
        /// <inheritdoc/>
        public bool VerifyCoinbase(int height, IConsensus consensus)
        {
            if (Data.Length < Constants.MinCoinbaseScriptLength || Data.Length > Constants.MaxCoinbaseScriptLength)
            {
                return(false);
            }

            if (consensus.IsBip34Enabled(height))
            {
                PushDataOp op = new PushDataOp();
                return(op.TryRead(new FastStreamReader(Data), out _) && op.TryGetNumber(out long h, out _, true, 5) && h == height);
            }
            else
            {
                return(true);
            }
        }
Esempio n. 19
0
        /// <summary>
        /// Set time to consensus acceptable value.
        /// </summary>
        /// <param name="now">The expected date.</param>
        /// <param name="consensus">Consensus.</param>
        /// <param name="prev">Previous block.</param>
        public void UpdateTime(DateTimeOffset now, IConsensus consensus, ChainedHeader prev)
        {
            DateTimeOffset nOldTime = this.BlockTime;
            DateTimeOffset mtp      = prev.GetMedianTimePast() + TimeSpan.FromSeconds(1);
            DateTimeOffset nNewTime = mtp > now ? mtp : now;

            if (nOldTime < nNewTime)
            {
                this.BlockTime = nNewTime;
            }

            // Updating time can change work required on testnet.
            if (consensus.PowAllowMinDifficultyBlocks)
            {
                this.Bits = this.GetWorkRequired(consensus, prev);
            }
        }
Esempio n. 20
0
        protected void RegisterRules(IConsensus consensus)
        {
            consensus.ConsensusRules
            .Register <HeaderTimeChecksRule>()
            .Register <HeaderTimeChecksPosRule>()
            .Register <PosFutureDriftRule>()
            .Register <CheckDifficultyPosRule>()
            .Register <x42HeaderVersionRule>()
            .Register <ProvenHeaderSizeRule>()
            .Register <ProvenHeaderCoinstakeRule>();

            consensus.ConsensusRules
            .Register <BlockMerkleRootRule>()
            .Register <PosBlockSignatureRepresentationRule>()
            .Register <PosBlockSignatureRule>();

            consensus.ConsensusRules
            .Register <SetActivationDeploymentsPartialValidationRule>()
            .Register <PosTimeMaskRule>()

            // rules that are inside the method ContextualCheckBlock
            .Register <TransactionLocktimeActivationRule>()
            .Register <CoinbaseHeightActivationRule>()
            .Register <WitnessCommitmentsRule>()
            .Register <BlockSizeRule>()

            // rules that are inside the method CheckBlock
            .Register <EnsureCoinbaseRule>()
            .Register <CheckPowTransactionRule>()
            .Register <CheckPosTransactionRule>()
            .Register <CheckSigOpsRule>()
            .Register <PosCoinstakeRule>();

            consensus.ConsensusRules
            .Register <SetActivationDeploymentsFullValidationRule>()

            .Register <CheckDifficultyHybridRule>()

            // rules that require the store to be loaded (coinview)
            .Register <LoadCoinviewRule>()
            .Register <TransactionDuplicationActivationRule>()
            .Register <x42PosCoinviewRule>()
            .Register <PosColdStakingRule>()
            .Register <SaveCoinviewRule>();
        }
Esempio n. 21
0
        public void RegisterRules(IConsensus consensus)
        {
            consensus.HeaderValidationRules = new List <IHeaderValidationConsensusRule>()
            {
                new HeaderTimeChecksPoARule(),
                new StratisHeaderVersionRule(),
                new PoAHeaderDifficultyRule(),
                new PoAHeaderSignatureRule()
            };

            consensus.IntegrityValidationRules = new List <IIntegrityValidationConsensusRule>()
            {
                new BlockMerkleRootRule(),
                new PoAIntegritySignatureRule()
            };

            consensus.PartialValidationRules = new List <IPartialValidationConsensusRule>()
            {
                new SetActivationDeploymentsPartialValidationRule(),

                // rules that are inside the method ContextualCheckBlock
                new TransactionLocktimeActivationRule(), // implements BIP113
                new CoinbaseHeightActivationRule(),      // implements BIP34
                new BlockSizeRule(),

                // rules that are inside the method CheckBlock
                new EnsureCoinbaseRule(),
                new CheckPowTransactionRule(),
                new CheckSigOpsRule(),

                new PoAVotingCoinbaseOutputFormatRule(),
            };

            consensus.FullValidationRules = new List <IFullValidationConsensusRule>()
            {
                new SetActivationDeploymentsFullValidationRule(),

                // rules that require the store to be loaded (coinview)
                new LoadCoinviewRule(),
                new TransactionDuplicationActivationRule(), // implements BIP30
                new PoACoinviewRule(),
                new SaveCoinviewRule()
            };
        }
Esempio n. 22
0
        private void SetupConsensus()
        {
            if (_consensus != null)
            {
                _logger?.Trace("Consensus has already initialized.");
                return;
            }

            switch (ConsensusConfig.Instance.ConsensusType)
            {
            case ConsensusType.AElfDPoS:
                _consensus = new DPoS(_stateStore, _txHub, _miner, _chainService);
                break;

            case ConsensusType.SingleNode:
                _consensus = new StandaloneNodeConsensusPlaceHolder();
                break;
            }
        }
Esempio n. 23
0
        /// <summary>
        ///     Check PoW against consensus and that the blocks connect correctly.
        /// </summary>
        /// <param name="consensus">The consensus rules being used.</param>
        /// <returns><c>true</c> if the header is a valid block header, <c>false</c> otherwise.</returns>
        public bool Validate(IConsensus consensus)
        {
            if (consensus == null)
            {
                throw new ArgumentNullException("consensus");
            }

            if (this.Height != 0 && this.Previous == null)
            {
                return(false);
            }

            var heightCorrect   = this.Height == 0 || this.Height == this.Previous.Height + 1;
            var hashPrevCorrect = this.Height == 0 || this.Header.HashPrevBlock == this.Previous.HashBlock;
            var hashCorrect     = this.HashBlock == this.Header.GetHash();
            var workCorrect     = CheckProofOfWorkAndTarget(consensus);

            return(heightCorrect && hashPrevCorrect && hashCorrect && workCorrect);
        }
Esempio n. 24
0
        /// <summary>
        /// Check PoW against consensus and that the blocks connect correctly.
        /// </summary>
        /// <param name="consensus">The consensus rules being used.</param>
        /// <returns><c>true</c> if the header is a valid block header, <c>false</c> otherwise.</returns>
        public bool Validate(IConsensus consensus)
        {
            if (consensus == null)
            {
                throw new ArgumentNullException("consensus");
            }

            if ((this.Height != 0) && (this.Previous == null))
            {
                return(false);
            }

            bool heightCorrect   = (this.Height == 0) || (this.Height == this.Previous.Height + 1);
            bool hashPrevCorrect = (this.Height == 0) || (this.Header.HashPrevBlock == this.Previous.HashBlock);
            bool hashCorrect     = this.HashBlock == this.Header.GetHash();
            bool workCorrect     = this.CheckProofOfWorkAndTarget(consensus);

            return(heightCorrect && hashPrevCorrect && hashCorrect && workCorrect);
        }
Esempio n. 25
0
        /// <inheritdoc/>
        public bool VerifyCoinbase(int height, IConsensus consensus)
        {
            if (Data.Length < Constants.MinCoinbaseScriptLength || Data.Length > Constants.MaxCoinbaseScriptLength)
            {
                return(false);
            }

            if (consensus.IsBip34Enabled(height))
            {
                var stream = new FastStream(4);
                new PushDataOp(height).WriteToStream(stream);
                ReadOnlySpan <byte> expected = stream.ToByteArray();

                return(Data.Length >= expected.Length && ((ReadOnlySpan <byte>)Data).Slice(0, expected.Length).SequenceEqual(expected));
            }
            else
            {
                return(true);
            }
        }
Esempio n. 26
0
        public void MineGenesisAndPremineBlocks()
        {
            int premineBlockCount = 2;

            var addressUsed = TestHelper.MineBlocks(this.PremineNodeWithCoins, premineBlockCount).AddressUsed;

            var wallet = this.PremineNodeWithCoins.FullNode.WalletManager().Wallets.Single(w => w.Name == "mywallet");
            var allTrx = wallet.walletStore.GetForAddress(addressUsed.Address);

            // Since the pre-mine will not be immediately spendable, the transactions have to be counted directly from the address.
            allTrx.Count().Should().Be(premineBlockCount);

            IConsensus consensus = this.PremineNodeWithCoins.FullNode.Network.Consensus;

            allTrx.Sum(s => s.Amount).Should().Be(consensus.PremineReward + consensus.ProofOfWorkReward);

            var balance = this.PremineNodeWithCoins.FullNode.WalletManager().GetAddressBalance(addressUsed.Address);

            balance.AmountConfirmed.Should().Be(consensus.PremineReward + consensus.ProofOfWorkReward);
        }
            public void RegisterRules(IConsensus consensus)
            {
                consensus.HeaderValidationRules = new List <IHeaderValidationConsensusRule>()
                {
                    new HeaderTimeChecksRule(),
                    new CheckDifficultyPowRule(),
                    new BitcoinActivationRule(),
                    new BitcoinHeaderVersionRule()
                };

                consensus.IntegrityValidationRules = new List <IIntegrityValidationConsensusRule>()
                {
                    new BlockMerkleRootRule()
                };

                consensus.PartialValidationRules = new List <IPartialValidationConsensusRule>()
                {
                    new SetActivationDeploymentsPartialValidationRule(),

                    new TransactionLocktimeActivationRule(), // implements BIP113
                    new CoinbaseHeightActivationRule(),      // implements BIP34
                    new WitnessCommitmentsRule(),            // BIP141, BIP144
                    new BlockSizeRule(),

                    // rules that are inside the method CheckBlock
                    new EnsureCoinbaseRule(),
                    new CheckPowTransactionRule(),
                    new CheckSigOpsRule(),
                };

                consensus.FullValidationRules = new List <IFullValidationConsensusRule>()
                {
                    new SetActivationDeploymentsFullValidationRule(),

                    // rules that require the store to be loaded (coinview)
                    new LoadCoinviewRule(),
                    new TransactionDuplicationActivationRule(), // implements BIP30
                    new PowCoinviewRule(),                      // implements BIP68, MaxSigOps and BlockReward calculation
                    new SaveCoinviewRule()
                };
            }
Esempio n. 28
0
        private void RegisterRules(IConsensus consensus)
        {
            // IHeaderValidationRule
            consensus.ConsensusRules
            .Register <HeaderTimeChecksRule>()
            .Register <HeaderTimeChecksPosRule>()
            .Register <StratisBugFixPosFutureDriftRule>()
            .Register <CheckDifficultyPosRule>()
            .Register <StratisHeaderVersionRule>();

            // IIntegrityValidationConsensusRule
            consensus.ConsensusRules
            .Register <BlockMerkleRootRule>()
            .Register <PosBlockSignatureRepresentationRule>()
            .Register <SmartContractPosBlockSignatureRule>();

            // IPartialValidationConsensusRule
            consensus.ConsensusRules
            .Register <SetActivationDeploymentsPartialValidationRule>()
            .Register <PosTimeMaskRule>()
            .Register <TransactionLocktimeActivationRule>()
            .Register <CoinbaseHeightActivationRule>()
            .Register <WitnessCommitmentsRule>()
            .Register <BlockSizeRule>()
            .Register <EnsureCoinbaseRule>()
            .Register <CheckPowTransactionRule>()
            .Register <CheckPosTransactionRule>()
            .Register <CheckSigOpsRule>()
            .Register <PosCoinstakeRule>();

            // IFullValidationConsensusRule
            // TODO: When looking to make PoS work again, will need to add several of the smart contract consensus rules below (see PoA and PoW implementations)
            consensus.ConsensusRules
            .Register <SetActivationDeploymentsFullValidationRule>()
            .Register <CheckDifficultyHybridRule>()
            .Register <LoadCoinviewRule>()
            .Register <TransactionDuplicationActivationRule>()
            .Register <SmartContractPosCoinviewRule>()
            .Register <SaveCoinviewRule>();
        }
Esempio n. 29
0
        public void VerifyTest(IUtxoDatabase utxoDB, IMemoryPool memPool, IConsensus c, ITransaction tx, bool expB, string expErr,
                               int expSigOp, ulong expFee, bool expSeg)
        {
            // An initial amount is set for both TotalFee and TotalSigOpCount to make sure Verify()
            // method always adds to previous values instead of setting them
            ulong initialFee   = 10;
            int   initialSigOp = 50;

            var verifier = new TransactionVerifier(false, utxoDB, memPool, c)
            {
                TotalFee        = initialFee,
                TotalSigOpCount = initialSigOp
            };

            bool actualB = verifier.Verify(tx, out string error);

            Assert.Equal(expB, actualB);
            Assert.Equal(expErr, error);
            Assert.Equal(expSigOp + initialSigOp, verifier.TotalSigOpCount);
            Assert.Equal(expFee + initialFee, verifier.TotalFee);
            Assert.Equal(expSeg, verifier.AnySegWit);
        }
        public virtual void RegisterRules(IConsensus consensus)
        {
            this.baseRuleRegistration.RegisterRules(consensus);

            // Add SC-Specific partial rules
            var txValidationRules = new List <IContractTransactionPartialValidationRule>(this.partialTxValidationRules)
            {
                new SmartContractFormatLogic()
            };

            consensus.PartialValidationRules.Add(new AllowedScriptTypeRule(this.network));
            consensus.PartialValidationRules.Add(new ContractTransactionPartialValidationRule(this.callDataSerializer, txValidationRules));

            int existingCoinViewRule = consensus.FullValidationRules
                                       .FindIndex(c => c is CoinViewRule);

            // Replace coinview rule
            consensus.FullValidationRules[existingCoinViewRule] =
                new SmartContractPoACoinviewRule(this.stateRepositoryRoot, this.executorFactory,
                                                 this.callDataSerializer, this.senderRetriever, this.receiptRepository, this.coinView);

            // Add SC-specific full rules BEFORE the coinviewrule
            var scRules = new List <IFullValidationConsensusRule>
            {
                new TxOutSmartContractExecRule(),
                new OpSpendRule(),
                new CanGetSenderRule(this.senderRetriever),
                new P2PKHNotContractRule(this.stateRepositoryRoot)
            };

            consensus.FullValidationRules.InsertRange(existingCoinViewRule, scRules);

            // SaveCoinviewRule must be the last rule executed because actually it calls CachedCoinView.SaveChanges that causes internal CachedCoinView to be updated
            // see https://dev.azure.com/Stratisplatformuk/StratisBitcoinFullNode/_workitems/edit/3770
            // TODO: re-design how rules gets called, which order they have and prevent a rule to change internal service statuses (rules should just check)
            int saveCoinviewRulePosition = consensus.FullValidationRules.FindIndex(c => c is SaveCoinviewRule);

            consensus.FullValidationRules.Insert(saveCoinviewRulePosition, new ContractTransactionFullValidationRule(this.callDataSerializer, this.fullTxValidationRules));
        }
Esempio n. 31
0
        private void RegisterRules(IConsensus consensus)
        {
            // IHeaderValidationRule
            consensus.ConsensusRules
            .Register <HeaderTimeChecksRule>()
            .Register <CheckDifficultyPowRule>()
            .Register <BitcoinActivationRule>()
            .Register <BitcoinHeaderVersionRule>();

            // IIntegrityValidationConsensusRule
            consensus.ConsensusRules
            .Register <BlockMerkleRootRule>();

            // IPartialValidationConsensusRule
            consensus.ConsensusRules
            .Register <SetActivationDeploymentsPartialValidationRule>()
            .Register <TransactionLocktimeActivationRule>()
            .Register <CoinbaseHeightActivationRule>()
            .Register <WitnessCommitmentsRule>()
            .Register <BlockSizeRule>()
            .Register <EnsureCoinbaseRule>()
            .Register <CheckPowTransactionRule>()
            .Register <CheckSigOpsRule>()
            .Register <AllowedScriptTypeRule>()
            .Register <ContractTransactionPartialValidationRule>();

            // IFullValidationConsensusRule
            consensus.ConsensusRules
            .Register <SetActivationDeploymentsFullValidationRule>()
            .Register <LoadCoinviewRule>()
            .Register <TransactionDuplicationActivationRule>()
            .Register <TxOutSmartContractExecRule>()
            .Register <OpSpendRule>()
            .Register <CanGetSenderRule>()
            .Register <P2PKHNotContractRule>()
            .Register <SmartContractPowCoinviewRule>()
            .Register <SaveCoinviewRule>();
        }
        /// <inheritdoc />
        public async Task InitializeAsync(IConsensus consensusParameters, ChainedHeader tip, ICoinView coinView)
        {
            // A temporary hack until tip manage will be introduced.
            var     breezeCoinView = (DBreezeCoinView)((CachedCoinView)coinView).Inner;
            uint256 hash           = await breezeCoinView.GetTipHashAsync().ConfigureAwait(false);

            tip = tip.FindAncestorOrSelf(hash);

            this.numberOfBlocksToKeep = (int)consensusParameters.MaxReorgLength;

            int heightToSyncTo = tip.Height > this.numberOfBlocksToKeep ? tip.Height - this.numberOfBlocksToKeep : 0;

            for (int rewindHeight = tip.Height - 1; rewindHeight >= heightToSyncTo; rewindHeight--)
            {
                RewindData rewindData = await coinView.GetRewindData(rewindHeight).ConfigureAwait(false);

                if (rewindData == null)
                {
                    throw new ConsensusException($"Rewind data of height '{rewindHeight}' was not found!");
                }

                if (rewindData.OutputsToRestore == null || rewindData.OutputsToRestore.Count == 0)
                {
                    continue;
                }

                foreach (UnspentOutputs unspent in rewindData.OutputsToRestore)
                {
                    for (int outputIndex = 0; outputIndex < unspent.Outputs.Length; outputIndex++)
                    {
                        string key = $"{unspent.TransactionId}-{outputIndex}";
                        this.items[key] = rewindHeight;
                    }
                }
            }
        }
Esempio n. 33
0
 public void Stop(IConsensus model)
 {
     _state = ServerState.Stopped;
     _electionAlarm = 0;
 }
Esempio n. 34
0
 public void Resume(IConsensus model)
 {
     _state = ServerState.Follower;
     _commitIndex = 0;
     updateElectionAlarm(model);
 }
Esempio n. 35
0
 public void ClientRequest(IConsensus model)
 {
     if (_state == ServerState.Leader)
         _persistedState.Create(new byte[] { (byte)_id });
 }
Esempio n. 36
0
 protected void updateElectionAlarm(IConsensus model)
 {
     _electionAlarm = model.Tick + _random.Next(ELECTION_TIMEOUT, ELECTION_TIMEOUT * 2);
 }
Esempio n. 37
0
 public void BecomeLeader(IConsensus model)
 {
     becomeLeader(model);
 }
Esempio n. 38
0
 public bool CheckRpcTimeout(IConsensus model)
 {
     return RpcDue < model.Tick;
 }
Esempio n. 39
0
        protected void handleMessage(IConsensus model, object message)
        {
            if (_state == ServerState.Stopped)
                return;

            if (message is VoteRequest)
                handleRequestVote(model, (VoteRequest)message);
            else if (message is VoteReply)
                handleRequestVoteReply(model, (VoteReply)message);
            else if (message is AppendEntriesRequest)
                handleAppendEntriesRequest(model, (AppendEntriesRequest)message);
            else if (message is AppendEntriesReply)
                handleAppendEntriesReply(model, (AppendEntriesReply)message);
            //else if (message is StatusRequest)
            //    handleRequestStatus(model, (StatusRequest)message);
            //else if (message is StatusReply)
            //    handleStatusReply(model, (StatusReply)message);
            else
                throw new Exception("Unhandled message");
        }
Esempio n. 40
0
 protected void sendAddServer(IConsensus model, Peer peer)
 {
     if (_state == ServerState.Adding)
     {
         
     }
 }
Esempio n. 41
0
        public void Update(IConsensus model)
        {
            if (_persistedState == null)
            {
                _persistedState = new MemoryLog();
                _persistedState.Initialize();
            }

            if (_stateMachine == null)
            {
                _stateMachine = new StateMachine(_dataDir);
                _stateMachine.Initialize();
            }

            startNewElection(model);
            becomeLeader(model);
            advanceCommitIndex(model);
            foreach (var peer in _peers)
            {
                sendRequestVote(model, peer);
                sendAppendEntries(model, peer);
            }
        }
Esempio n. 42
0
 public void Restart(IConsensus model)
 {
     Stop(model);
     Resume(model);
 }
Esempio n. 43
0
 protected bool isElectionTimeout(IConsensus model)
 {
     return _electionAlarm <= model.Tick;
 }
Esempio n. 44
0
        protected void advanceCommitIndex(IConsensus model)
        {
            var matchIndexes = new uint[_peers.Count + 1];
            matchIndexes[matchIndexes.Length - 1] = _persistedState.Length;
            for (var i = 0; i < _peers.Count; i++)
                matchIndexes[i] = _peers[i].MatchIndex;

            Array.Sort(matchIndexes);

            var n = matchIndexes[_peers.Count / 2];
            if (_state == ServerState.Leader && _persistedState.GetTerm(n) == _persistedState.Term)
                commitIndex(Math.Max(_commitIndex, n));
        }
Esempio n. 45
0
 public void HandleMessage(IConsensus model, object message)
 {
     handleMessage(model, message);
 }
Esempio n. 46
0
        protected void handleAppendEntriesReply(IConsensus model, AppendEntriesReply reply)
        {
            if (_persistedState.Term < reply.Term)
                stepDown(model, reply.Term);

            if (_state == ServerState.Leader && _persistedState.Term == reply.Term)
            {
                var peer = _peers.First(x => x.ID == reply.From);
                if (reply.Success)
                {
                    peer.MatchIndex = Math.Max(peer.MatchIndex, reply.MatchIndex);
                    peer.NextIndex = reply.MatchIndex + 1;
                }
                else
                {
                    peer.NextIndex = Math.Max(1, peer.NextIndex - 1);
                }
                peer.RpcDue = 0;
            }
        }
Esempio n. 47
0
        protected void sendAppendEntries(IConsensus model, Peer peer)
        {
            if (_state == ServerState.Leader &&
                (peer.HeartBeartDue <= model.Tick ||
                 (peer.NextIndex <= _persistedState.Length && peer.RpcDue <= model.Tick)))
            {
                var prevIndex = peer.NextIndex - 1;
                var lastIndex = Math.Min(prevIndex + BATCH_SIZE, _persistedState.Length);
                if (peer.MatchIndex + 1 < peer.NextIndex)
                    lastIndex = prevIndex;

                var entries = _persistedState.GetEntries(prevIndex, lastIndex);
                if (entries != null && entries.Length > 0)
                    Console.WriteLine("{0}: Send AppendEnties[{1}-{2}] to {3}", _id, prevIndex, lastIndex, peer.ID);

                peer.RpcDue = model.Tick + RPC_TIMEOUT;
                peer.HeartBeartDue = model.Tick + (ELECTION_TIMEOUT / 2);
                model.SendRequest(peer, new AppendEntriesRequest()
                {
                    From = _id,
                    Term = _persistedState.Term,
                    PrevIndex = prevIndex,
                    PrevTerm = _persistedState.GetTerm(prevIndex),
                    Entries = entries,
                    CommitIndex = Math.Min(_commitIndex, lastIndex)
                });
            }
        }
Esempio n. 48
0
        protected void handleAppendEntriesRequest(IConsensus model, AppendEntriesRequest request)
        {
            if (_persistedState.Term < request.Term)
                stepDown(model, request.Term);

            var peer = _peers.First(x => x.ID == request.From);
            var success = false;
            var matchIndex = 0u;

            if (_persistedState.Term == request.Term)
            {
                _state = ServerState.Follower;
                updateElectionAlarm(model);

                if (request.PrevIndex == 0 ||
                    (request.PrevIndex <= _persistedState.Length && _persistedState.GetTerm(request.PrevIndex) == request.PrevTerm))
                {
                    success = true;

                    var index = request.PrevIndex;
                    for (var i = 0; request.Entries != null && i < request.Entries.Length; i++)
                    {
                        index++;
                        if (_persistedState.GetTerm(index) != request.Entries[i].Index.Term)
                        {
                            while (_persistedState.Length > index - 1)
                            {
                                Console.WriteLine("{0}: Rolling back log {1}", _id, _persistedState.Length - 1);
                                _persistedState.Pop();
                            }

                            //Console.WriteLine("{0}: Writing log value {1}", _id, request.Entries[i].Offset);
                            _persistedState.Push(request.Entries[i]);
                        }
                    }

                    matchIndex = index;
                    commitIndex(Math.Max(_commitIndex, request.CommitIndex));
                }
            }

            model.SendReply(peer, new AppendEntriesReply() { From = _id, Term = _persistedState.Term, MatchIndex = matchIndex, Success = success });
        }
Esempio n. 49
0
        //protected void sendStatusRequest(IModel model, Peer peer)
        //{
        //    // since we are designed around not knowning what the data is
        //    // it could be large, we don't want to slowly send index after 
        //    // index to a node thats been down for a long time

        //    System.Diagnostics.Debug.Assert(peer.RpcDue == int.MaxValue);

        //    if (_state == ServerState.Leader)
        //    {
        //        peer.RpcDue = model.Tick + Settings.RPC_TIMEOUT;
        //        peer.HeartBeartDue = model.Tick + (Settings.ELECTION_TIMEOUT / 2);
        //        model.SendRequest(peer, new StatusRequest()
        //        {
        //            From = _id,
        //            Term = _persistedState.Term
        //        });
        //    }
        //}

        protected void becomeLeader(IConsensus model)
        {
            if (_state == ServerState.Candidate)
            {
                var voteCount = _peers.Count(x => x.VoteGranted) + 1;
                if (voteCount >= Quorum)
                {
                    Console.WriteLine("{0}: I am now leader of term {2} with {1} votes", _id, voteCount, _persistedState.Term);
                    _state = ServerState.Leader;
                    _electionAlarm = int.MaxValue;
                    foreach (var peer in _peers)
                    {
                        peer.LeadershipChanged(_persistedState.Length + 1);
                        //sendStatusRequest(model, peer);
                    }
                }
            }
        }
Esempio n. 50
0
        protected void handleRequestVoteReply(IConsensus model, VoteReply reply)
        {
            if (_persistedState.Term < reply.Term)
                stepDown(model, reply.Term);

            if (_state == ServerState.Candidate && _persistedState.Term == reply.Term)
            {
                var peer = _peers.First(x => x.ID == reply.From);
                peer.RpcDue = int.MaxValue;
                peer.VoteGranted = reply.Granted;

                //Console.WriteLine("{0}: Peer {1} voted {2}", _id, peer.ID, peer.VotedGranted);
            }
        }
Esempio n. 51
0
        protected void sendRequestVote(IConsensus model, Peer peer)
        {
            if (_state == ServerState.Candidate && peer.CheckRpcTimeout(model))
            {
                //Console.WriteLine("{0}: Requesting vote from {1}", _id, peer.ID);

                LogIndex lastIndex;
                var lastLogIndex = _persistedState.GetLastIndex(out lastIndex);

                peer.RpcDue = model.Tick + RPC_TIMEOUT;
                model.SendRequest(peer, new VoteRequest()
                {
                    From = _id,
                    Term = _persistedState.Term,
                    LastTerm = lastIndex.Term,
                    LogLength = lastLogIndex
                });
            }
        }
Esempio n. 52
0
        //protected void handleRequestStatus(IModel model, StatusRequest request)
        //{
        //    if (_persistedState.Term < request.Term)
        //        stepDown(model, request.Term);

        //    if (_state == ServerState.Follower && _persistedState.Term == request.Term)
        //    {
        //        var peer = _peers.First(x => x.ID == request.From);
        //        _electionAlarm = makeElectionAlarm(model);
        //        model.SendReply(peer, new StatusReply()
        //        {
        //            From = _id, 
        //            CommitIndex = _commitIndex,
        //            Term = _persistedState.Term
        //        });

        //        Console.WriteLine("{0}: Sent status {1} to {2}", _id, _commitIndex, peer.ID);
        //    }
        //}

        //protected void handleStatusReply(IModel model, StatusReply reply)
        //{
        //    if (_persistedState.Term < reply.Term)
        //        stepDown(model, reply.Term);

        //    if (_state == ServerState.Leader && _persistedState.Term == reply.Term)
        //    {
        //        var peer = _peers.First(x => x.ID == reply.From);
        //        peer.RpcDue = int.MaxValue;
        //        peer.MatchIndex = reply.CommitIndex;

        //        //Console.WriteLine("{0}: Peer {1} voted {2}", _id, peer.ID, peer.VotedGranted);
        //    }
        //}

        protected void handleRequestVote(IConsensus model, VoteRequest request)
        {
            if (_persistedState.Term < request.Term)
                stepDown(model, request.Term);

            //a leader would never request a peer vote
            System.Diagnostics.Debug.Assert(_state != ServerState.Adding && _state != ServerState.Removing);

            var peer = _peers.First(x => x.ID == request.From);
            var ourLastLogTerm = _persistedState.GetLastTerm();
            var termCheck = _persistedState.Term == request.Term;
            var canVote = _persistedState.VotedFor == null || _persistedState.VotedFor == request.From;
            var logTermFurther = request.LastTerm > ourLastLogTerm;
            var logIndexLonger = request.LastTerm == ourLastLogTerm && request.LogLength >= _persistedState.Length;
            var granted = termCheck && canVote && (logTermFurther || logIndexLonger);

            if (!termCheck)
                Console.WriteLine("{0}: Can not vote for {1} because term {2}, expected {3}", _id, peer.ID, request.Term, _persistedState.Term);

            if (!canVote)
                Console.WriteLine("{0}: Can not vote for {1} because I already voted for {2}", _id, peer.ID, _persistedState.VotedFor);

            if (!(logTermFurther || logIndexLonger))
                Console.WriteLine("{0}: Can not vote for {1} because my log is more update to date", _id, peer.ID);

            if (granted)
            {
                Console.WriteLine("{0}: Voted for {1}", _id, peer.ID);
                _persistedState.VotedFor = peer.ID;
                updateElectionAlarm(model);
            }

            model.SendReply(peer, new VoteReply() { From = _id, Term = _persistedState.Term, Granted = granted });

        }
Esempio n. 53
0
 public void Add(IConsensus model)
 {
     _state = ServerState.Adding;
     _commitIndex = 0;
     _electionAlarm = uint.MaxValue;
 }
Esempio n. 54
0
 public void Timeout(IConsensus model)
 {
     _state = ServerState.Follower;
     _electionAlarm = 0;
     startNewElection(model);
 }