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); }
/// <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("(-)"); }
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); }
/// <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 }
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 }
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("(-)"); }
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); }
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) }; }
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 }
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) }; }
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) }; }
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); } }
/// <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); } }
/// <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); } }
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>(); }
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() }; }
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; } }
/// <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); }
/// <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); }
/// <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); } }
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() }; }
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>(); }
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)); }
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; } } } }
public void Stop(IConsensus model) { _state = ServerState.Stopped; _electionAlarm = 0; }
public void Resume(IConsensus model) { _state = ServerState.Follower; _commitIndex = 0; updateElectionAlarm(model); }
public void ClientRequest(IConsensus model) { if (_state == ServerState.Leader) _persistedState.Create(new byte[] { (byte)_id }); }
protected void updateElectionAlarm(IConsensus model) { _electionAlarm = model.Tick + _random.Next(ELECTION_TIMEOUT, ELECTION_TIMEOUT * 2); }
public void BecomeLeader(IConsensus model) { becomeLeader(model); }
public bool CheckRpcTimeout(IConsensus model) { return RpcDue < model.Tick; }
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"); }
protected void sendAddServer(IConsensus model, Peer peer) { if (_state == ServerState.Adding) { } }
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); } }
public void Restart(IConsensus model) { Stop(model); Resume(model); }
protected bool isElectionTimeout(IConsensus model) { return _electionAlarm <= model.Tick; }
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)); }
public void HandleMessage(IConsensus model, object message) { handleMessage(model, message); }
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; } }
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) }); } }
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 }); }
//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); } } } }
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); } }
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 }); } }
//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 }); }
public void Add(IConsensus model) { _state = ServerState.Adding; _commitIndex = 0; _electionAlarm = uint.MaxValue; }
public void Timeout(IConsensus model) { _state = ServerState.Follower; _electionAlarm = 0; startNewElection(model); }