public ThresholdConditionCache(NBitcoin.Consensus consensus)
 {
     if (consensus == null)
     {
         throw new ArgumentNullException("consensus");
     }
     _Consensus = consensus;
 }
        public ContextInformation(ChainedBlock nextBlock, NBitcoin.Consensus consensus)
        {
            Guard.NotNull(nextBlock, nameof(nextBlock));

            BestBlock        = new ContextBlockInformation(nextBlock.Previous, consensus);
            Time             = DateTimeOffset.UtcNow;
            NextWorkRequired = nextBlock.GetWorkRequired(consensus);
        }
 public ConsensusValidator(NBitcoin.Consensus consensusParams)
 {
     if (consensusParams == null)
     {
         throw new ArgumentNullException("consensusParams");
     }
     _ConsensusParams = consensusParams;
 }
        public ContextBlockInformation(ChainedBlock bestBlock, NBitcoin.Consensus consensus)
        {
            Guard.NotNull(bestBlock, nameof(bestBlock));

            this.Header         = bestBlock.Header;
            this.Height         = bestBlock.Height;
            this.MedianTimePast = bestBlock.GetMedianTimePast();
        }
Ejemplo n.º 5
0
        /// <inheritdoc />
        public override void Initialize()
        {
            this.Logger.LogTrace("()");

            this.Consensus           = this.Parent.Network.Consensus;
            this.PowConsensusOptions = this.Parent.Network.Consensus.Option <PowConsensusOptions>();

            this.Logger.LogTrace("(-)");
        }
Ejemplo n.º 6
0
        public PowConsensusValidator(Network network)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(network.Consensus.Option <PowConsensusOptions>(), nameof(network.Consensus.Options));

            this.consensusParams    = network.Consensus;
            this.consensusOptions   = network.Consensus.Option <PowConsensusOptions>();
            this.PerformanceCounter = new ConsensusPerformanceCounter();
        }
Ejemplo n.º 7
0
        /// <inheritdoc />
        public override void Initialize()
        {
            this.Logger.LogTrace("()");

            base.Initialize();

            this.consensusParams = this.Parent.Network.Consensus;

            this.Logger.LogTrace("(-)");
        }
Ejemplo n.º 8
0
 public ContextInformation(ChainedBlock nextBlock, NBitcoin.Consensus consensus)
 {
     if (nextBlock == null)
     {
         throw new ArgumentNullException("nextBlock");
     }
     BestBlock        = new ContextBlockInformation(nextBlock.Previous, consensus);
     Time             = DateTimeOffset.UtcNow;
     NextWorkRequired = nextBlock.GetWorkRequired(consensus);
 }
Ejemplo n.º 9
0
 public ContextBlockInformation(ChainedBlock bestBlock, NBitcoin.Consensus consensus)
 {
     if (bestBlock == null)
     {
         throw new ArgumentNullException("bestBlock");
     }
     Header         = bestBlock.Header;
     Height         = bestBlock.Height;
     MedianTimePast = bestBlock.GetMedianTimePast();
 }
        public PowConsensusValidator(Network network, ICheckpoints checkpoints, ILoggerFactory loggerFactory)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(network.Consensus.Option <PowConsensusOptions>(), nameof(network.Consensus.Options));

            this.logger             = loggerFactory.CreateLogger(this.GetType().FullName);
            this.consensusParams    = network.Consensus;
            this.consensusOptions   = network.Consensus.Option <PowConsensusOptions>();
            this.PerformanceCounter = new ConsensusPerformanceCounter();
            this.checkpoints        = checkpoints;
        }
Ejemplo n.º 11
0
        public RuleContext(ValidationContext validationContext, NBitcoin.Consensus consensus, ChainedHeader consensusTip, DateTimeOffset time) : base()
        {
            Guard.NotNull(validationContext, nameof(validationContext));
            Guard.NotNull(consensus, nameof(consensus));

            this.ValidationContext  = validationContext;
            this.Consensus          = consensus;
            this.ConsensusTip       = consensusTip;
            this.ConsensusTipHeight = consensusTip.Height;
            this.Time       = time;
            this.MinedBlock = false;
        }
Ejemplo n.º 12
0
        /// <inheritdoc />
        public override void Initialize()
        {
            this.Logger.LogTrace("()");

            base.Initialize();

            this.consensusParams      = this.Parent.Network.Consensus;
            this.generatedTransaction = null;
            this.refundCounter        = 1;
            this.smartContractParent  = (SmartContractConsensusRules)this.Parent;

            this.Logger.LogTrace("(-)");
        }
Ejemplo n.º 13
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("(-)");
        }
Ejemplo n.º 14
0
        /// <inheritdoc />
        public override void Initialize()
        {
            this.Logger.LogTrace("()");

            base.Initialize();

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

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

            this.Logger.LogTrace("(-)");
        }
Ejemplo n.º 15
0
        public ContextInformation(BlockValidationContext blockValidationContext, NBitcoin.Consensus consensus)
        {
            Guard.NotNull(blockValidationContext, nameof(blockValidationContext));
            Guard.NotNull(consensus, nameof(consensus));

            this.BlockValidationContext = blockValidationContext;
            this.Consensus = consensus;

            // TODO: adding flags to determine the flow of logic is not ideal
            // a refator is in depbate on moving to a consensus rules engine
            // this will remove hte need for flags as a validation will
            // only use the required rules (i.e if the check pow rule will be ommited form the flow)
            this.CheckPow        = true;
            this.CheckMerkleRoot = true;
        }
        public RuleContext(BlockValidationContext blockValidationContext, NBitcoin.Consensus consensus, ChainedHeader consensusTip)
        {
            Guard.NotNull(blockValidationContext, nameof(blockValidationContext));
            Guard.NotNull(consensus, nameof(consensus));

            this.BlockValidationContext = blockValidationContext;
            this.Consensus    = consensus;
            this.ConsensusTip = consensusTip;

            // TODO: adding flags to determine the flow of logic is not ideal
            // a re-factor is in debate on moving to a consensus rules engine
            // this will remove the need for flags as validation will only use
            // the required rules (i.e if the check pow rule will be omitted form the flow)
            this.CheckPow        = true;
            this.CheckMerkleRoot = true;
        }
Ejemplo n.º 17
0
        private int ComputeBlockVersion(ChainedHeader prevChainedHeader, NBitcoin.Consensus consensus)
        {
            uint version = ThresholdConditionCache.VersionbitsTopBits;
            var  thresholdConditionCache = new ThresholdConditionCache(consensus);

            IEnumerable <BIP9Deployments> deployments = Enum.GetValues(typeof(BIP9Deployments)).OfType <BIP9Deployments>();

            foreach (BIP9Deployments deployment in deployments)
            {
                ThresholdState state = thresholdConditionCache.GetState(prevChainedHeader, deployment);
                if ((state == ThresholdState.LockedIn) || (state == ThresholdState.Started))
                {
                    version |= thresholdConditionCache.Mask(deployment);
                }
            }

            return((int)version);
        }
Ejemplo n.º 18
0
        private int ComputeBlockVersion(ChainedBlock pindexPrev, NBitcoin.Consensus consensus)
        {
            var nVersion = ThresholdConditionCache.VERSIONBITS_TOP_BITS;
            var thresholdConditionCache = new ThresholdConditionCache(consensus);

            var deploymensts = Enum.GetValues(typeof(BIP9Deployments))
                               .OfType <BIP9Deployments>();

            foreach (var deployment in deploymensts)
            {
                var state = thresholdConditionCache.GetState(pindexPrev, deployment);
                if (state == ThresholdState.LockedIn || state == ThresholdState.Started)
                {
                    nVersion |= thresholdConditionCache.Mask(deployment);
                }
            }

            return((int)nVersion);
        }
        private int ComputeBlockVersion(ChainedBlock prevChainedBlock, NBitcoin.Consensus consensus)
        {
            uint nVersion = ThresholdConditionCache.VERSIONBITS_TOP_BITS;
            var  thresholdConditionCache = new ThresholdConditionCache(consensus);

            IEnumerable <BIP9Deployments> deploymensts = Enum.GetValues(typeof(BIP9Deployments))
                                                         .OfType <BIP9Deployments>();

            foreach (BIP9Deployments deployment in deploymensts)
            {
                ThresholdState state = thresholdConditionCache.GetState(prevChainedBlock, deployment);
                if ((state == ThresholdState.LockedIn) || (state == ThresholdState.Started))
                {
                    nVersion |= thresholdConditionCache.Mask(deployment);
                }
            }

            return((int)nVersion);
        }
 public CheckPowTransactionRuleTest()
 {
     this.consensus = this.network.Consensus;
     this.options   = this.consensus.Option <PowConsensusOptions>();
 }
Ejemplo n.º 21
0
        public ConsensusFlags(ChainedBlock nextBlock, ThresholdState[] prevBlockStates, NBitcoin.Consensus chainparams)
        {
            // Do not allow blocks that contain transactions which 'overwrite' older transactions,
            // unless those are already completely spent.
            // If such overwrites are allowed, coinbases and transactions depending upon those
            // can be duplicated to remove the ability to spend the first instance -- even after
            // being sent to another address.
            // See BIP30 and http://r6.ca/blog/20120206T005236Z.html for more information.
            // This logic is not necessary for memory pool transactions, as AcceptToMemoryPool
            // already refuses previously-known transaction ids entirely.
            // This rule was originally applied to all blocks with a timestamp after March 15, 2012, 0:00 UTC.
            // Now that the whole chain is irreversibly beyond that time it is applied to all blocks except the
            // two in the chain that violate it. This prevents exploiting the issue against nodes during their
            // initial block download.
            this.EnforceBIP30 = (nextBlock.HashBlock == null) ||             // Enforce on CreateNewBlock invocations which don't have a hash.
                                !((nextBlock.Height == 91842 && nextBlock.HashBlock == new uint256("00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec")) ||
                                  (nextBlock.Height == 91880 && nextBlock.HashBlock == new uint256("00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721")));

            // Once BIP34 activated it was not possible to create new duplicate coinbases and thus other than starting
            // with the 2 existing duplicate coinbase pairs, not possible to create overwriting txs.  But by the
            // time BIP34 activated, in each of the existing pairs the duplicate coinbase had overwritten the first
            // before the first had been spent.  Since those coinbases are sufficiently buried its no longer possible to create further
            // duplicate transactions descending from the known pairs either.
            // If we're on the known chain at height greater than where BIP34 activated, we can save the db accesses needed for the BIP30 check.
            var pindexBIP34height = nextBlock.GetAncestor(chainparams.BuriedDeployments[BuriedDeployments.BIP34]);

            //Only continue to enforce if we're below BIP34 activation height or the block hash at that height doesn't correspond.
            this.EnforceBIP30 = this.EnforceBIP30 && (pindexBIP34height == null || !(pindexBIP34height.HashBlock == chainparams.BIP34Hash));

            // BIP16 didn't become active until Apr 1 2012
            var  nBIP16SwitchTime       = Utils.UnixTimeToDateTime(1333238400);
            bool fStrictPayToScriptHash = (nextBlock.Header.BlockTime >= nBIP16SwitchTime);

            this.ScriptFlags = fStrictPayToScriptHash ? ScriptVerify.P2SH : ScriptVerify.None;

            // Start enforcing the DERSIG (BIP66) rule
            if (nextBlock.Height >= chainparams.BuriedDeployments[BuriedDeployments.BIP66])
            {
                this.ScriptFlags |= ScriptVerify.DerSig;
            }

            // Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4
            // blocks, when 75% of the network has upgraded:
            if (nextBlock.Height >= chainparams.BuriedDeployments[BuriedDeployments.BIP65])
            {
                this.ScriptFlags |= ScriptVerify.CheckLockTimeVerify;
            }

            // Start enforcing BIP68 (sequence locks), BIP112 (CHECKSEQUENCEVERIFY) and BIP113 (Median Time Past) using versionbits logic.
            if (prevBlockStates[(int)NBitcoin.BIP9Deployments.CSV] == ThresholdState.Active)
            {
                this.ScriptFlags   |= ScriptVerify.CheckSequenceVerify;
                this.LockTimeFlags |= Transaction.LockTimeFlags.VerifySequence;
                this.LockTimeFlags |= Transaction.LockTimeFlags.MedianTimePast;
            }

            // Start enforcing WITNESS rules using versionbits logic.
            if (prevBlockStates[(int)NBitcoin.BIP9Deployments.Segwit] == ThresholdState.Active)
            {
                this.ScriptFlags |= ScriptVerify.Witness;
            }

            // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
            if (nextBlock.Height >= chainparams.BuriedDeployments[BuriedDeployments.BIP34])
            {
                this.EnforceBIP34 = true;
            }
        }
Ejemplo n.º 22
0
 private static BigInteger GetProofOfStakeLimit(NBitcoin.Consensus consensus, int height)
 {
     return(IsProtocolV2(height) ? consensus.ProofOfStakeLimitV2 : consensus.ProofOfStakeLimit);
 }
Ejemplo n.º 23
0
        public static Target GetNextTargetRequired(StakeChain stakeChain, ChainedBlock indexLast, NBitcoin.Consensus consensus, bool proofOfStake)
        {
            // Genesis block
            if (indexLast == null)
            {
                return(consensus.PowLimit);
            }

            // find the last two blocks that correspond to the mining algo
            // (i.e if this is a POS block we need to find the last two POS blocks)
            var targetLimit = proofOfStake
                                ? GetProofOfStakeLimit(consensus, indexLast.Height)
                                : consensus.PowLimit.ToBigInteger();

            // first block
            var pindexPrev = GetLastBlockIndex(stakeChain, indexLast, proofOfStake);

            if (pindexPrev.Previous == null)
            {
                return(new Target(targetLimit));
            }

            // second block
            var pindexPrevPrev = GetLastBlockIndex(stakeChain, pindexPrev.Previous, proofOfStake);

            if (pindexPrevPrev.Previous == null)
            {
                return(new Target(targetLimit));
            }


            int targetSpacing = GetTargetSpacing(indexLast.Height);
            int actualSpacing = (int)(pindexPrev.Header.Time - pindexPrevPrev.Header.Time);

            if (IsProtocolV1RetargetingFixed(indexLast.Height))
            {
                if (actualSpacing < 0)
                {
                    actualSpacing = targetSpacing;
                }
            }
            if (IsProtocolV3((int)indexLast.Header.Time))
            {
                if (actualSpacing > targetSpacing * 10)
                {
                    actualSpacing = targetSpacing * 10;
                }
            }

            // target change every block
            // retarget with exponential moving toward target spacing
            var targetTimespan = 16 * 60;             // 16 mins
            var target         = pindexPrev.Header.Bits.ToBigInteger();

            int interval = targetTimespan / targetSpacing;

            target = target.Multiply(BigInteger.ValueOf(((interval - 1) * targetSpacing + actualSpacing + actualSpacing)));
            target = target.Divide(BigInteger.ValueOf(((interval + 1) * targetSpacing)));

            if (target.CompareTo(BigInteger.Zero) <= 0 || target.CompareTo(targetLimit) >= 1)
            {
                //if (target <= 0 || target > targetLimit)
                target = targetLimit;
            }

            return(new Target(target));
        }
Ejemplo n.º 24
0
        public quoxentMain()
        {
            CoinSetup    setup   = quoxentSetup.Instance.Setup;
            NetworkSetup network = quoxentSetup.Instance.Main;

            NetworkType           = NetworkType.Mainnet;
            DefaultConfigFilename = setup.ConfigFileName; // The default name used for the quoxent configuration file.

            Name           = network.Name;
            CoinTicker     = network.CoinTicker;
            Magic          = ConversionTools.ConvertToUInt32(setup.Magic);
            RootFolderName = network.RootFolderName;
            DefaultPort    = network.DefaultPort;
            DefaultRPCPort = network.DefaultRPCPort;
            DefaultAPIPort = network.DefaultAPIPort;

            DefaultMaxOutboundConnections = 16;
            DefaultMaxInboundConnections  = 109;
            MaxTipAge             = 2 * 60 * 60;
            MinTxFee              = 9333;
            FallbackFee           = 9333;
            MinRelayTxFee         = 9333;
            MaxTimeOffsetSeconds  = 25 * 60;
            DefaultBanTimeSeconds = 16000; // 500 (MaxReorg) * 64 (TargetSpacing) / 2 = 4 hours, 26 minutes and 40 seconds

            var consensusFactory = new PosConsensusFactory();

            // Create the genesis block.
            GenesisTime    = network.GenesisTime;
            GenesisNonce   = network.GenesisNonce;
            GenesisBits    = network.GenesisBits;
            GenesisVersion = network.GenesisVersion;
            GenesisReward  = network.GenesisReward;

            Block genesisBlock = CreateGenesisBlock(consensusFactory,
                                                    GenesisTime,
                                                    GenesisNonce,
                                                    GenesisBits,
                                                    GenesisVersion,
                                                    GenesisReward,
                                                    setup.GenesisText);

            Genesis = genesisBlock;

            var consensusOptions = new PosConsensusOptions(
                maxBlockBaseSize: 1_000_000,
                maxStandardVersion: 2,
                maxStandardTxWeight: 100_000,
                maxBlockSigopsCost: 20_000,
                maxStandardTxSigopsCost: 20_000 / 5,
                witnessScaleFactor: 4
                );

            var buriedDeployments = new BuriedDeploymentsArray
            {
                [BuriedDeployments.BIP34] = 0,
                [BuriedDeployments.BIP65] = 0,
                [BuriedDeployments.BIP66] = 0
            };

            Consensus = new NBitcoin.Consensus(
                consensusFactory: consensusFactory,
                consensusOptions: consensusOptions,
                coinType: setup.CoinType,
                hashGenesisBlock: genesisBlock.GetHash(),
                subsidyHalvingInterval: 29333,
                majorityEnforceBlockUpgrade: 750,
                majorityRejectBlockOutdated: 950,
                majorityWindow: 1000,
                buriedDeployments: buriedDeployments,
                bip9Deployments: new NoBIP9Deployments(),
                bip34Hash: null,
                minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
                maxReorgLength: 500,
                defaultAssumeValid: null,
                maxMoney: long.MaxValue,
                coinbaseMaturity: 50,
                premineHeight: 2,
                premineReward: Money.Coins(setup.PremineReward),
                proofOfWorkReward: Money.Coins(setup.PoWBlockReward),
                targetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
                targetSpacing: setup.TargetSpacing,
                powAllowMinDifficultyBlocks: false,
                posNoRetargeting: false,
                powNoRetargeting: false,
                powLimit: new Target(new uint256("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")),
                minimumChainWork: null,
                isProofOfStake: true,
                lastPowBlock: setup.LastPowBlock,
                proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeReward: Money.Coins(setup.PoSBlockReward),
                proofOfStakeTimestampMask: setup.ProofOfStakeTimestampMask
                );

            Consensus.PosEmptyCoinbase            = quoxentSetup.Instance.IsPoSv3();
            Consensus.PosUseTimeFieldInKernalHash = quoxentSetup.Instance.IsPoSv3();

            // TODO: Set your Base58Prefixes
            Base58Prefixes = new byte[12][];
            Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS] = new byte[] { (byte)network.PubKeyAddress };
            Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS] = new byte[] { (byte)network.ScriptAddress };
            Base58Prefixes[(int)Base58Type.SECRET_KEY]     = new byte[] { (byte)network.SecretAddress };

            Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_NO_EC] = new byte[] { 0x01, 0x42 };
            Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_EC]    = new byte[] { 0x01, 0x43 };
            Base58Prefixes[(int)Base58Type.EXT_PUBLIC_KEY]             = new byte[] { (0x04), (0x88), (0xB2), (0x1E) };
            Base58Prefixes[(int)Base58Type.EXT_SECRET_KEY]             = new byte[] { (0x04), (0x88), (0xAD), (0xE4) };
            Base58Prefixes[(int)Base58Type.PASSPHRASE_CODE]            = new byte[] { 0x2C, 0xE9, 0xB3, 0xE1, 0xFF, 0x39, 0xE2 };
            Base58Prefixes[(int)Base58Type.CONFIRMATION_CODE]          = new byte[] { 0x64, 0x3B, 0xF6, 0xA8, 0x9A };
            Base58Prefixes[(int)Base58Type.STEALTH_ADDRESS]            = new byte[] { 0x2a };
            Base58Prefixes[(int)Base58Type.ASSET_ID]        = new byte[] { 23 };
            Base58Prefixes[(int)Base58Type.COLORED_ADDRESS] = new byte[] { 0x13 };

            Bech32Encoders = new Bech32Encoder[2];
            var encoder = new Bech32Encoder(network.CoinTicker.ToLowerInvariant());

            Bech32Encoders[(int)Bech32Type.WITNESS_PUBKEY_ADDRESS] = encoder;
            Bech32Encoders[(int)Bech32Type.WITNESS_SCRIPT_ADDRESS] = encoder;

            Checkpoints = network.Checkpoints;
            DNSSeeds    = network.DNS.Select(dns => new DNSSeedData(dns, dns)).ToList();
            SeedNodes   = network.Nodes.Select(node => new NBitcoin.Protocol.NetworkAddress(IPAddress.Parse(node), network.DefaultPort)).ToList();

            StandardScriptsRegistry = new quoxentStandardScriptsRegistry();

            // 64 below should be changed to TargetSpacingSeconds when we move that field.
            Assert(DefaultBanTimeSeconds <= Consensus.MaxReorgLength * 64 / 2);

            Assert(Consensus.HashGenesisBlock == uint256.Parse(network.HashGenesisBlock));
            Assert(Genesis.Header.HashMerkleRoot == uint256.Parse(network.HashMerkleRoot));

            RegisterRules(Consensus);
            RegisterMempoolRules(Consensus);
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Set time to consensus acceptable value
 /// </summary>
 /// <param name="consensus">Consensus</param>
 /// <param name="prev">previous block</param>
 public void UpdateTime(Consensus consensus, ChainedBlock prev)
 {
     UpdateTime(DateTimeOffset.UtcNow, consensus, prev);
 }
 public static T Option <T>(this NBitcoin.Consensus item)
     where T : NBitcoin.Consensus.ConsensusOptions
 {
     return(item.Options as T);
 }
Ejemplo n.º 27
0
        /// <inheritdoc/>
        public Target GetNextTargetRequired(IStakeChain stakeChain, ChainedHeader chainedHeader, NBitcoin.Consensus consensus, bool proofOfStake)
        {
            this.logger.LogTrace("({0}:'{1}',{2}:{3})", nameof(chainedHeader), chainedHeader, nameof(proofOfStake), proofOfStake);

            // Genesis block.
            if (chainedHeader == null)
            {
                this.logger.LogTrace("(-)[GENESIS]:'{0}'", consensus.PowLimit);
                return(consensus.PowLimit);
            }

            // Find the last two blocks that correspond to the mining algo
            // (i.e if this is a POS block we need to find the last two POS blocks).
            BigInteger targetLimit = proofOfStake
                ? consensus.ProofOfStakeLimitV2
                : consensus.PowLimit.ToBigInteger();

            // First block.
            ChainedHeader lastPowPosBlock = this.GetLastPowPosChainedBlock(stakeChain, chainedHeader, proofOfStake);

            if (lastPowPosBlock.Previous == null)
            {
                var res = new Target(targetLimit);
                this.logger.LogTrace("(-)[FIRST_BLOCK]:'{0}'", res);
                return(res);
            }

            // Second block.
            ChainedHeader prevLastPowPosBlock = this.GetLastPowPosChainedBlock(stakeChain, lastPowPosBlock.Previous, proofOfStake);

            if (prevLastPowPosBlock.Previous == null)
            {
                var res = new Target(targetLimit);
                this.logger.LogTrace("(-)[SECOND_BLOCK]:'{0}'", res);
                return(res);
            }

            // This is used in tests to allow quickly mining blocks.
            if (consensus.PowNoRetargeting)
            {
                this.logger.LogTrace("(-)[NO_POW_RETARGET]:'{0}'", lastPowPosBlock.Header.Bits);
                return(lastPowPosBlock.Header.Bits);
            }

            Target finalTarget = this.CalculateRetarget(lastPowPosBlock.Header.Time, lastPowPosBlock.Header.Bits, prevLastPowPosBlock.Header.Time, targetLimit);

            this.logger.LogTrace("(-):'{0}'", finalTarget);
            return(finalTarget);
        }
Ejemplo n.º 28
0
        public static Target GetWorkRequired(NBitcoin.Consensus consensus, ChainedBlock chainedBlock)
        {
            // Genesis block
            if (chainedBlock.Height == 0)
            {
                return(consensus.PowLimit);
            }
            var nProofOfWorkLimit = consensus.PowLimit;
            var pindexLast        = chainedBlock.Previous;
            var height            = chainedBlock.Height;

            if (pindexLast == null)
            {
                return(nProofOfWorkLimit);
            }

            // Only change once per interval
            if ((height) % consensus.DifficultyAdjustmentInterval != 0)
            {
                if (consensus.PowAllowMinDifficultyBlocks)
                {
                    // Special difficulty rule for testnet:
                    // If the new block's timestamp is more than 2* 10 minutes
                    // then allow mining of a min-difficulty block.
                    if (chainedBlock.Header.BlockTime > pindexLast.Header.BlockTime + TimeSpan.FromTicks(consensus.PowTargetSpacing.Ticks * 2))
                    {
                        return(nProofOfWorkLimit);
                    }
                    else
                    {
                        // Return the last non-special-min-difficulty-rules-block
                        ChainedBlock pindex = pindexLast;
                        while (pindex.Previous != null && (pindex.Height % consensus.DifficultyAdjustmentInterval) != 0 && pindex.Header.Bits == nProofOfWorkLimit)
                        {
                            pindex = pindex.Previous;
                        }
                        return(pindex.Header.Bits);
                    }
                }
                return(pindexLast.Header.Bits);
            }

            // Go back by what we want to be 14 days worth of blocks
            var          pastHeight  = pindexLast.Height - (consensus.DifficultyAdjustmentInterval - 1);
            ChainedBlock pindexFirst = chainedBlock.EnumerateToGenesis().FirstOrDefault(o => o.Height == pastHeight);

            Guard.Assert(pindexFirst != null);

            if (consensus.PowNoRetargeting)
            {
                return(pindexLast.Header.Bits);
            }

            // Limit adjustment step
            var nActualTimespan = pindexLast.Header.BlockTime - pindexFirst.Header.BlockTime;

            if (nActualTimespan < TimeSpan.FromTicks(consensus.PowTargetTimespan.Ticks / 4))
            {
                nActualTimespan = TimeSpan.FromTicks(consensus.PowTargetTimespan.Ticks / 4);
            }
            if (nActualTimespan > TimeSpan.FromTicks(consensus.PowTargetTimespan.Ticks * 4))
            {
                nActualTimespan = TimeSpan.FromTicks(consensus.PowTargetTimespan.Ticks * 4);
            }

            // Retarget
            var bnNew = pindexLast.Header.Bits.ToBigInteger();

            bnNew = bnNew.Multiply(BigInteger.ValueOf((long)nActualTimespan.TotalSeconds));
            bnNew = bnNew.Divide(BigInteger.ValueOf((long)consensus.PowTargetTimespan.TotalSeconds));
            var newTarget = new Target(bnNew);

            if (newTarget > nProofOfWorkLimit)
            {
                newTarget = nProofOfWorkLimit;
            }

            return(newTarget);
        }
Ejemplo n.º 29
0
        public RutanioTest()
        {
            // START MODIFICATIONS OF GENERATED CODE
            var consensusOptions = new RutanioPosConsensusOptions
            {
                MaxBlockBaseSize        = 1_000_000,
                MaxStandardVersion      = 2,
                MaxStandardTxWeight     = 100_000,
                MaxBlockSigopsCost      = 20_000,
                MaxStandardTxSigopsCost = 20_000 / 5,
                WitnessScaleFactor      = 4
            };
            // END MODIFICATIONS

            CoinSetup    setup   = RutanioSetup.Instance.Setup;
            NetworkSetup network = RutanioSetup.Instance.Test;

            NetworkType = NetworkType.Testnet;

            Name           = network.Name;
            CoinTicker     = network.CoinTicker;
            Magic          = ConversionTools.ConvertToUInt32(setup.Magic, true);
            RootFolderName = network.RootFolderName;
            DefaultPort    = network.DefaultPort;
            DefaultRPCPort = network.DefaultRPCPort;
            DefaultAPIPort = network.DefaultAPIPort;

            var consensusFactory = new PosConsensusFactory();

            // Create the genesis block.
            GenesisTime    = network.GenesisTime;
            GenesisNonce   = network.GenesisNonce;
            GenesisBits    = network.GenesisBits;
            GenesisVersion = network.GenesisVersion;
            GenesisReward  = network.GenesisReward;

            Block genesisBlock = CreateGenesisBlock(consensusFactory,
                                                    GenesisTime,
                                                    GenesisNonce,
                                                    GenesisBits,
                                                    GenesisVersion,
                                                    GenesisReward,
                                                    setup.GenesisText);

            Genesis = genesisBlock;

            var buriedDeployments = new BuriedDeploymentsArray
            {
                [BuriedDeployments.BIP34] = 0,
                [BuriedDeployments.BIP65] = 0,
                [BuriedDeployments.BIP66] = 0
            };

            var bip9Deployments = new RutanioBIP9Deployments()
            {
                [RutanioBIP9Deployments.TestDummy] = new BIP9DeploymentsParameters("TestDummy", 28,
                                                                                   new DateTime(2020, 6, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                   new DateTime(2021, 6, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                   BIP9DeploymentsParameters.DefaultTestnetThreshold),

                [RutanioBIP9Deployments.CSV] = new BIP9DeploymentsParameters("CSV", 0,
                                                                             new DateTime(2020, 6, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                             new DateTime(2021, 6, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                             BIP9DeploymentsParameters.DefaultTestnetThreshold),

                [RutanioBIP9Deployments.Segwit] = new BIP9DeploymentsParameters("Segwit", 1,
                                                                                new DateTime(2020, 6, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                new DateTime(2021, 6, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                BIP9DeploymentsParameters.DefaultTestnetThreshold),

                [RutanioBIP9Deployments.ColdStaking] = new BIP9DeploymentsParameters("ColdStaking", 2,
                                                                                     new DateTime(2020, 6, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                     new DateTime(2021, 6, 1, 0, 0, 0, DateTimeKind.Utc),
                                                                                     BIP9DeploymentsParameters.DefaultTestnetThreshold)
            };

            Consensus = new NBitcoin.Consensus(
                consensusFactory: consensusFactory,
                consensusOptions: consensusOptions,
                coinType: setup.CoinType,
                hashGenesisBlock: genesisBlock.GetHash(),
                subsidyHalvingInterval: 210000,
                majorityEnforceBlockUpgrade: 750,
                majorityRejectBlockOutdated: 950,
                majorityWindow: 1000,
                buriedDeployments: buriedDeployments,
                bip9Deployments: new NoBIP9Deployments(),
                bip34Hash: null,
                minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
                maxReorgLength: 500,
                defaultAssumeValid: null,
                maxMoney: long.MaxValue,
                coinbaseMaturity: 10,
                premineHeight: 2,
                premineReward: Money.Coins(setup.PremineReward),
                proofOfWorkReward: Money.Coins(setup.PoWBlockReward),
                targetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
                targetSpacing: setup.TargetSpacing,
                powAllowMinDifficultyBlocks: false,
                posNoRetargeting: false,
                powNoRetargeting: false,
                powLimit: new Target(new uint256("000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")),
                minimumChainWork: null,
                isProofOfStake: true,
                lastPowBlock: setup.LastPowBlock,
                proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
                proofOfStakeReward: Money.Coins(setup.PoSBlockReward),
                proofOfStakeTimestampMask: setup.ProofOfStakeTimestampMask
                );

            Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS] = new byte[] { (byte)network.PubKeyAddress };
            Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS] = new byte[] { (byte)network.ScriptAddress };
            Base58Prefixes[(int)Base58Type.SECRET_KEY]     = new byte[] { (byte)network.SecretAddress };
            Base58Prefixes[(int)Base58Type.EXT_PUBLIC_KEY] = new byte[] { (0x04), (0x35), (0x87), (0xCF) };
            Base58Prefixes[(int)Base58Type.EXT_SECRET_KEY] = new byte[] { (0x04), (0x35), (0x83), (0x94) };

            Bech32Encoders = new Bech32Encoder[2];
            var encoder = new Bech32Encoder(network.CoinTicker.ToLowerInvariant());

            Bech32Encoders[(int)Bech32Type.WITNESS_PUBKEY_ADDRESS] = encoder;
            Bech32Encoders[(int)Bech32Type.WITNESS_SCRIPT_ADDRESS] = encoder;

            Checkpoints = network.Checkpoints;
            DNSSeeds    = network.DNS.Select(dns => new DNSSeedData(dns, dns)).ToList();
            SeedNodes   = network.Nodes.Select(node => new NBitcoin.Protocol.NetworkAddress(IPAddress.Parse(Dns.GetHostAddresses(node).GetValue(0).ToString()), network.DefaultPort)).ToList();

            StandardScriptsRegistry = new RutanioStandardScriptsRegistry();

            // 64 below should be changed to TargetSpacingSeconds when we move that field.
            Assert(DefaultBanTimeSeconds <= Consensus.MaxReorgLength * 64 / 2);

            Assert(Consensus.HashGenesisBlock == uint256.Parse(network.HashGenesisBlock));
            Assert(Genesis.Header.HashMerkleRoot == uint256.Parse(network.HashMerkleRoot));

            RegisterRules(Consensus);
            RegisterMempoolRules(Consensus);
        }
    }
Ejemplo n.º 30
0
        /// <inheritdoc/>
        public Target GetNextTargetRequired(IStakeChain stakeChain, ChainedBlock chainedBlock, NBitcoin.Consensus consensus, bool proofOfStake)
        {
            this.logger.LogTrace("({0}:'{1}',{2}:{3})", nameof(chainedBlock), chainedBlock, nameof(proofOfStake), proofOfStake);

            // Genesis block.
            if (chainedBlock == null)
            {
                this.logger.LogTrace("(-)[GENESIS]:'{0}'", consensus.PowLimit);
                return(consensus.PowLimit);
            }

            // Find the last two blocks that correspond to the mining algo
            // (i.e if this is a POS block we need to find the last two POS blocks).
            BigInteger targetLimit = proofOfStake
                ? consensus.ProofOfStakeLimitV2
                : consensus.PowLimit.ToBigInteger();

            // First block.
            ChainedBlock lastPowPosBlock = GetLastPowPosChainedBlock(stakeChain, chainedBlock, proofOfStake);

            if (lastPowPosBlock.Previous == null)
            {
                var res = new Target(targetLimit);
                this.logger.LogTrace("(-)[FIRST_BLOCK]:'{0}'", res);
                return(res);
            }

            // Second block.
            ChainedBlock prevLastPowPosBlock = GetLastPowPosChainedBlock(stakeChain, lastPowPosBlock.Previous, proofOfStake);

            if (prevLastPowPosBlock.Previous == null)
            {
                var res = new Target(targetLimit);
                this.logger.LogTrace("(-)[SECOND_BLOCK]:'{0}'", res);
                return(res);
            }

            // This is used in tests to allow quickly mining blocks.
            if (consensus.PowNoRetargeting)
            {
                this.logger.LogTrace("(-)[NO_POW_RETARGET]:'{0}'", lastPowPosBlock.Header.Bits);
                return(lastPowPosBlock.Header.Bits);
            }

            int targetSpacing = TargetSpacingSeconds;
            int actualSpacing = (int)(lastPowPosBlock.Header.Time - prevLastPowPosBlock.Header.Time);

            if (actualSpacing < 0)
            {
                actualSpacing = targetSpacing;
            }

            if (actualSpacing > targetSpacing * 10)
            {
                actualSpacing = targetSpacing * 10;
            }

            int targetTimespan = RetargetIntervalMinutes * 60;
            int interval       = targetTimespan / targetSpacing;

            BigInteger target = lastPowPosBlock.Header.Bits.ToBigInteger();

            long multiplyBy = (interval - 1) * targetSpacing + actualSpacing + actualSpacing;

            target = target.Multiply(BigInteger.ValueOf(multiplyBy));

            long divideBy = (interval + 1) * targetSpacing;

            target = target.Divide(BigInteger.ValueOf(divideBy));

            this.logger.LogTrace("The next target difficulty will be {0} times higher (easier to satisfy) than the previous target.", (double)multiplyBy / (double)divideBy);

            if ((target.CompareTo(BigInteger.Zero) <= 0) || (target.CompareTo(targetLimit) >= 1))
            {
                target = targetLimit;
            }

            var finalTarget = new Target(target);

            this.logger.LogTrace("(-):'{0}'", finalTarget);
            return(finalTarget);
        }