public void ShouldSerializeMerkleNodeCorrectly()
        {
            MerkleNode merkleNode = new MerkleNode
            {
                Size = 8,
                Name = "My Merkle Node",
                Hash = new MultiHash("QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o"),
                Data= Encoding.UTF8.GetBytes("My string"),
                Links = null,
            };

            string actual = _jsonSerializer.Serialize(merkleNode);
            string expected = "{\"Data\":\"TXkgc3RyaW5n\",\"Hash\":\"QmT78zSuBmuS4z925WZfrqQ1qHaJ56DQaTfyMUF7F8ff5o\",\"Links\":null,\"Name\":\"My Merkle Node\",\"Size\":8}";

            Assert.IsTrue(Equals(actual, expected));
        }
Example #2
0
        /// <summary>
        /// Stores input as a DAG object, outputs its key
        /// 'ipfs object put' is a plumbing command for storing DAG nodes.
        /// It reads from stdin, and the output is a base58 encoded multihash.
        /// </summary>
        /// <param name="node">Node to be stored as a DAG object</param>
        /// <returns>The added object key</returns>
        public async Task<MerkleNode> Put(MerkleNode node)
        {
            var flags = new Dictionary<string, string>();

            flags.Add("encoding", GetIpfsEncodingValue(IpfsEncoding.Json));
            flags.Add("datafieldenc", GetIpfsEncodingValue(IpfsEncoding.Base64));

            //Thanks to @slothbag for this snippet
            MultipartFormDataContent content = new MultipartFormDataContent();
            string json = _jsonSerializer.Serialize(node);
            StringContent sc = new StringContent(json);
            sc.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            content.Add(sc, "file", "file");

            HttpContent returnContent = await ExecutePostAsync("put", flags, content);
            string returnJson = await returnContent.ReadAsStringAsync();
            return _jsonSerializer.Deserialize<MerkleNode>(returnJson);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
        {
            MerkleNode merkleNode = new MerkleNode();

            int startingDepth = reader.Depth;
            while (!(reader.TokenType == JsonToken.EndObject && startingDepth == reader.Depth))
            {
                reader.Read();

                if (reader.TokenType == JsonToken.PropertyName)
                {
                    string propertyName = reader.Value.ToString();

                    if (String.Equals(propertyName, "Data"))
                    {
                        reader.Read();
                        merkleNode.Data = serializer.Deserialize<byte[]>(reader);
                    }
                    else if (String.Equals(propertyName, "Hash"))
                    {
                        reader.Read();
                        merkleNode.Hash = serializer.Deserialize<MultiHash>(reader);
                    }
                    else if (String.Equals(propertyName, "Links"))
                    {
                        reader.Read();
                        merkleNode.Links = serializer.Deserialize<IEnumerable<MerkleNode>>(reader);
                    }
                    else if (String.Equals(propertyName, "Name"))
                    {
                        reader.Read();
                        merkleNode.Name = serializer.Deserialize<string>(reader);
                    }
                    else if (String.Equals(propertyName, "Size"))
                    {
                        reader.Read();
                        merkleNode.Size = serializer.Deserialize<long?>(reader);
                    }
                }
            }

            return merkleNode;
        }
Example #4
0
        public override void Init(ZCashBlockTemplate blockTemplate, string jobId,
                                  PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock,
                                  IDestination poolAddressDestination, BitcoinNetworkType networkType,
                                  bool isPoS, double shareMultiplier, decimal?blockrewardMultiplier,
                                  IHashAlgorithm coinbaseHasher, IHashAlgorithm headerHasher, IHashAlgorithm blockHasher)
        {
            Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate));
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination));
            Contract.RequiresNonNull(coinbaseHasher, nameof(coinbaseHasher));
            Contract.RequiresNonNull(headerHasher, nameof(headerHasher));
            Contract.RequiresNonNull(blockHasher, nameof(blockHasher));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            this.poolConfig             = poolConfig;
            this.clusterConfig          = clusterConfig;
            this.clock                  = clock;
            this.poolAddressDestination = poolAddressDestination;
            this.networkType            = networkType;

            if (ZCashConstants.Chains.TryGetValue(poolConfig.Coin.Type, out var coinbaseTx))
            {
                coinbaseTx.TryGetValue(networkType, out chainConfig);
            }

            BlockTemplate = blockTemplate;
            JobId         = jobId;
            Difficulty    = (double)new BigRational(chainConfig.Diff1b, BlockTemplate.Target.HexToByteArray().ReverseArray().ToBigInteger());

            this.isPoS           = isPoS;
            this.shareMultiplier = shareMultiplier;

            this.headerHasher = headerHasher;
            this.blockHasher  = blockHasher;
            this.equihash     = chainConfig.Solver();

            if (!string.IsNullOrEmpty(BlockTemplate.Target))
            {
                blockTargetValue = new uint256(BlockTemplate.Target);
            }
            else
            {
                var tmp = new Target(BlockTemplate.Bits.HexToByteArray());
                blockTargetValue = tmp.ToUInt256();
            }

            previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash
                                           .HexToByteArray()
                                           .ReverseArray()
                                           .ToHexString();

            BuildCoinbase();

            // build tx hashes
            var txHashes = new List <uint256> {
                new uint256(coinbaseInitialHash)
            };

            txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.TxId.HexToByteArray().ReverseArray())));

            // build merkle root
            merkleRoot            = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseArray();
            merkleRootReversed    = merkleRoot.ReverseArray();
            merkleRootReversedHex = merkleRootReversed.ToHexString();

            jobParams = new object[]
            {
                JobId,
                BlockTemplate.Version.ReverseByteOrder().ToStringHex8(),
                previousBlockHashReversedHex,
                merkleRootReversedHex,
                BlockTemplate.Height.ReverseByteOrder().ToStringHex8() + sha256Empty.Take(28).ToHexString(), // height + hashReserved
                BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(),
                BlockTemplate.Bits.HexToByteArray().ReverseArray().ToHexString(),
                false
            };
        }
Example #5
0
        public virtual void Init(EquihashBlockTemplate blockTemplate, string jobId,
                                 PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock,
                                 IDestination poolAddressDestination, Network network,
                                 EquihashSolver solver)
        {
            Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate));
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination));
            Contract.RequiresNonNull(solver, nameof(solver));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            this.clock = clock;
            this.poolAddressDestination = poolAddressDestination;
            coin          = poolConfig.Template.As <EquihashCoinTemplate>();
            networkParams = coin.GetNetwork(network.NetworkType);
            this.network  = network;
            BlockTemplate = blockTemplate;
            JobId         = jobId;
            Difficulty    = (double)new BigRational(networkParams.Diff1BValue, BlockTemplate.Target.HexToReverseByteArray().AsSpan().ToBigInteger());

            // ZCash Sapling & Overwinter support
            isSaplingActive = networkParams.SaplingActivationHeight.HasValue &&
                              networkParams.SaplingTxVersion.HasValue &&
                              networkParams.SaplingTxVersionGroupId.HasValue &&
                              networkParams.SaplingActivationHeight.Value > 0 &&
                              blockTemplate.Height >= networkParams.SaplingActivationHeight.Value;

            isOverwinterActive = isSaplingActive ||
                                 networkParams.OverwinterTxVersion.HasValue &&
                                 networkParams.OverwinterTxVersionGroupId.HasValue &&
                                 networkParams.OverwinterActivationHeight.HasValue &&
                                 networkParams.OverwinterActivationHeight.Value > 0 &&
                                 blockTemplate.Height >= networkParams.OverwinterActivationHeight.Value;

            if (isSaplingActive)
            {
                txVersion        = networkParams.SaplingTxVersion.Value;
                txVersionGroupId = networkParams.SaplingTxVersionGroupId.Value;
            }

            else if (isOverwinterActive)
            {
                txVersion        = networkParams.OverwinterTxVersion.Value;
                txVersionGroupId = networkParams.OverwinterTxVersionGroupId.Value;
            }

            // Misc
            this.solver = solver;

            if (!string.IsNullOrEmpty(BlockTemplate.Target))
            {
                blockTargetValue = new uint256(BlockTemplate.Target);
            }
            else
            {
                var tmp = new Target(BlockTemplate.Bits.HexToByteArray());
                blockTargetValue = tmp.ToUInt256();
            }

            previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash
                                           .HexToByteArray()
                                           .ReverseInPlace()
                                           .ToHexString();

            if (blockTemplate.Subsidy != null)
            {
                blockReward = blockTemplate.Subsidy.Miner * BitcoinConstants.SatoshisPerBitcoin;
            }
            else
            {
                blockReward = BlockTemplate.CoinbaseValue;
            }

            if (networkParams?.vFundingStreams == true)
            {
                decimal fundingstreamTotal = 0;
                fundingstreamTotal = blockTemplate.Subsidy.FundingStreams.Sum(x => x.Value);
                blockReward        = (blockTemplate.Subsidy.Miner + fundingstreamTotal) * BitcoinConstants.SatoshisPerBitcoin;
            }
            else if (networkParams?.PayFoundersReward == true)
            {
                var founders = blockTemplate.Subsidy.Founders ?? blockTemplate.Subsidy.Community;

                if (!founders.HasValue)
                {
                    throw new Exception("Error, founders reward missing for block template");
                }

                blockReward = (blockTemplate.Subsidy.Miner + founders.Value) * BitcoinConstants.SatoshisPerBitcoin;
            }

            rewardFees = blockTemplate.Transactions.Sum(x => x.Fee);

            BuildCoinbase();

            // build tx hashes
            var txHashes = new List <uint256> {
                new uint256(coinbaseInitialHash)
            };

            txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.Hash.HexToReverseByteArray())));

            // build merkle root
            merkleRoot            = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseInPlace();
            merkleRootReversed    = merkleRoot.ReverseInPlace();
            merkleRootReversedHex = merkleRootReversed.ToHexString();

            // misc
            var hashReserved = isSaplingActive && !string.IsNullOrEmpty(blockTemplate.FinalSaplingRootHash) ?
                               blockTemplate.FinalSaplingRootHash.HexToReverseByteArray().ToHexString() :
                               sha256Empty.ToHexString();

            var solutionIn = !string.IsNullOrEmpty(blockTemplate.Solution) ?
                             blockTemplate.Solution.HexToByteArray().ToHexString() :
                             null;

            jobParams = new object[]
            {
                JobId,
                BlockTemplate.Version.ReverseByteOrder().ToStringHex8(),
                previousBlockHashReversedHex,
                merkleRootReversedHex,
                hashReserved,
                BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(),
                BlockTemplate.Bits.HexToReverseByteArray().ToHexString(),
                false,
                solutionIn
            };
        }
 protected override MerkleNode CreateNode(MerkleNode left, MerkleNode right)
 {
     return(new DemoMerkleNode((DemoMerkleNode)left, (DemoMerkleNode)right));
 }
Example #7
0
        private void ComputeMerkleTree(MerkleNode root)
        {
            var merkle = new Stack <byte[]>();

            ComputeMerkleTree(root, merkle);
        }
Example #8
0
        public override void Init(ZCashBlockTemplate blockTemplate, string jobId,
                                  PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock,
                                  IDestination poolAddressDestination, BitcoinNetworkType networkType,
                                  bool isPoS, double shareMultiplier, decimal?blockrewardMultiplier,
                                  IHashAlgorithm coinbaseHasher, IHashAlgorithm headerHasher, IHashAlgorithm blockHasher)
        {
            Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate));
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination));
            Contract.RequiresNonNull(coinbaseHasher, nameof(coinbaseHasher));
            Contract.RequiresNonNull(headerHasher, nameof(headerHasher));
            Contract.RequiresNonNull(blockHasher, nameof(blockHasher));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            this.poolConfig             = poolConfig;
            this.clusterConfig          = clusterConfig;
            this.clock                  = clock;
            this.poolAddressDestination = poolAddressDestination;
            this.networkType            = networkType;

            if (ZCashConstants.Chains.TryGetValue(poolConfig.Coin.Type, out var chain))
            {
                chain.TryGetValue(networkType, out chainConfig);
            }

            BlockTemplate  = blockTemplate;
            JobId          = jobId;
            Difficulty     = (double)new BigRational(chainConfig.Diff1b, BlockTemplate.Target.HexToByteArray().ReverseArray().AsSpan().ToBigInteger());
            txExpiryHeight = blockTemplate.Height + 100;

            // ZCash Sapling & Overwinter support
            isSaplingActive = chainConfig.SaplingActivationHeight.HasValue &&
                              chainConfig.SaplingTxVersion.HasValue &&
                              chainConfig.SaplingTxVersionGroupId.HasValue &&
                              chainConfig.SaplingActivationHeight.Value > 0 &&
                              blockTemplate.Height >= chainConfig.SaplingActivationHeight.Value;

            isOverwinterActive = isSaplingActive ||
                                 chainConfig.OverwinterTxVersion.HasValue &&
                                 chainConfig.OverwinterTxVersionGroupId.HasValue &&
                                 chainConfig.OverwinterActivationHeight.HasValue &&
                                 chainConfig.OverwinterActivationHeight.Value > 0 &&
                                 blockTemplate.Height >= chainConfig.OverwinterActivationHeight.Value;

            if (isSaplingActive)
            {
                txVersion        = chainConfig.SaplingTxVersion.Value;
                txVersionGroupId = chainConfig.SaplingTxVersionGroupId.Value;
            }

            else if (isOverwinterActive)
            {
                txVersion        = chainConfig.OverwinterTxVersion.Value;
                txVersionGroupId = chainConfig.OverwinterTxVersionGroupId.Value;
            }

            // Misc
            this.isPoS           = isPoS;
            this.shareMultiplier = shareMultiplier;

            this.headerHasher = headerHasher;
            this.blockHasher  = blockHasher;
            this.equihash     = chainConfig.Solver();

            if (!string.IsNullOrEmpty(BlockTemplate.Target))
            {
                blockTargetValue = new uint256(BlockTemplate.Target);
            }
            else
            {
                var tmp = new Target(BlockTemplate.Bits.HexToByteArray());
                blockTargetValue = tmp.ToUInt256();
            }

            previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash
                                           .HexToByteArray()
                                           .ReverseArray()
                                           .ToHexString();

            blockReward = blockTemplate.Subsidy.Miner * BitcoinConstants.SatoshisPerBitcoin;

            if (chainConfig?.PayFoundersReward == true)
            {
                var founders = blockTemplate.Subsidy.Founders ?? blockTemplate.Subsidy.Community;

                if (!founders.HasValue)
                {
                    throw new Exception("Error, founders reward missing for block template");
                }

                blockReward = (blockTemplate.Subsidy.Miner + founders.Value) * BitcoinConstants.SatoshisPerBitcoin;
            }

            rewardFees = blockTemplate.Transactions.Sum(x => x.Fee);

            BuildCoinbase();

            // build tx hashes
            var txHashes = new List <uint256> {
                new uint256(coinbaseInitialHash)
            };

            txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.Hash.HexToByteArray().ReverseArray())));

            // build merkle root
            merkleRoot            = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseArray();
            merkleRootReversed    = merkleRoot.ReverseArray();
            merkleRootReversedHex = merkleRootReversed.ToHexString();

            // misc
            var hashReserved = isSaplingActive && !string.IsNullOrEmpty(blockTemplate.FinalSaplingRootHash) ? blockTemplate.FinalSaplingRootHash.HexToByteArray().ReverseArray().ToHexString() : sha256Empty.ToHexString();

            jobParams = new object[]
            {
                JobId,
                BlockTemplate.Version.ReverseByteOrder().ToStringHex8(),
                previousBlockHashReversedHex,
                merkleRootReversedHex,
                hashReserved,
                BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(),
                BlockTemplate.Bits.HexToByteArray().ReverseArray().ToHexString(),
                false
            };
        }
Example #9
0
 public MerkleNode GetMerkleRoot()
 {
     return(MerkleNode.GetRoot(this.Transactions.Select(t => t.GetHash())));
 }
Example #10
0
        public override void Init(ZCashBlockTemplate blockTemplate, string jobId,
            PoolConfig poolConfig, XPoolConfig clusterConfig, IMasterClock clock,
            IDestination poolAddressDestination, BitcoinNetworkType networkType,
            bool isPoS, double shareMultiplier, decimal blockrewardMultiplier,
            IHashAlgorithm coinbaseHasher, IHashAlgorithm headerHasher, IHashAlgorithm blockHasher)
        {
            Assertion.RequiresNonNull(blockTemplate, nameof(blockTemplate));
            Assertion.RequiresNonNull(poolConfig, nameof(poolConfig));
            Assertion.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            Assertion.RequiresNonNull(clock, nameof(clock));
            Assertion.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination));
            Assertion.RequiresNonNull(coinbaseHasher, nameof(coinbaseHasher));
            Assertion.RequiresNonNull(headerHasher, nameof(headerHasher));
            Assertion.RequiresNonNull(blockHasher, nameof(blockHasher));
            Assertion.Requires<ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            this.poolConfig = poolConfig;
            this.clusterConfig = clusterConfig;
            this.clock = clock;
            this.poolAddressDestination = poolAddressDestination;
            this.networkType = networkType;

            if (ZCashConstants.CoinbaseTxConfig.TryGetValue(poolConfig.Coin.Type, out var coinbaseTx))
                coinbaseTx.TryGetValue(networkType, out coinbaseTxConfig);

            BlockTemplate = blockTemplate;
            JobId = jobId;
            Difficulty = (double) new BigRational(coinbaseTxConfig.Diff1b, BlockTemplate.Target.HexToByteArray().ReverseArray().ToBigInteger());

            this.isPoS = isPoS;
            this.shareMultiplier = shareMultiplier;

            this.headerHasher = headerHasher;
            this.blockHasher = blockHasher;

            if (!string.IsNullOrEmpty(BlockTemplate.Target))
                blockTargetValue = new uint256(BlockTemplate.Target);
            else
            {
                var tmp = new Target(BlockTemplate.Bits.HexToByteArray());
                blockTargetValue = tmp.ToUInt256();
            }

            previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash
                .HexToByteArray()
                .ReverseArray()
                .ToHexString();

            blockReward = blockTemplate.Subsidy.Miner * BitcoinConstants.SatoshisPerBitcoin;

            if (coinbaseTxConfig?.PayFoundersReward == true)
            {
                var founders = blockTemplate.Subsidy.Founders ?? blockTemplate.Subsidy.Community;

                if (!founders.HasValue)
                    throw new Exception("Error, founders reward missing for block template");

                blockReward = (blockTemplate.Subsidy.Miner + founders.Value) * BitcoinConstants.SatoshisPerBitcoin;
            }

            rewardFees = blockTemplate.Transactions.Sum(x => x.Fee);

            BuildCoinbase();

                        var txHashes = new List<uint256> { new uint256(coinbaseInitialHash) };
            txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.Hash.HexToByteArray().ReverseArray())));

                        merkleRoot = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseArray();
            merkleRootReversed = merkleRoot.ReverseArray();
            merkleRootReversedHex = merkleRootReversed.ToHexString();

            jobParams = new object[]
            {
                JobId,
                BlockTemplate.Version.ReverseByteOrder().ToStringHex8(),
                previousBlockHashReversedHex,
                merkleRootReversedHex,
                sha256Empty.ToHexString(),                 BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(),
                BlockTemplate.Bits.HexToByteArray().ReverseArray().ToHexString(),
                false
            };
        }
Example #11
0
        public void VerifyHash()
        {
            MerkleNode parent = CreateNode("ae", "lf");

            Assert.True(parent.VerifyHash());
        }
Example #12
0
        public void LeftRightHashVerificationTest()
        {
            MerkleNode parentNode = CreateParentNode("abc", "def");

            Assert.True(parentNode.VerifyHash());
        }
Example #13
0
 public BlockInfo(Block block)
 {
     Header         = block.Header;
     MerkleRootNode = block.MerkleRootNode;
 }
Example #14
0
        public override void Init(ZCashBlockTemplate blockTemplate, string jobId,
                                  PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock,
                                  IDestination poolAddressDestination, BitcoinNetworkType networkType,
                                  bool isPoS, double shareMultiplier,
                                  IHashAlgorithm coinbaseHasher, IHashAlgorithm headerHasher, IHashAlgorithm blockHasher)
        {
            Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate));
            Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
            Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
            Contract.RequiresNonNull(clock, nameof(clock));
            Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination));
            Contract.RequiresNonNull(coinbaseHasher, nameof(coinbaseHasher));
            Contract.RequiresNonNull(headerHasher, nameof(headerHasher));
            Contract.RequiresNonNull(blockHasher, nameof(blockHasher));
            Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

            this.poolConfig             = poolConfig;
            this.clusterConfig          = clusterConfig;
            this.clock                  = clock;
            this.poolAddressDestination = poolAddressDestination;
            this.networkType            = networkType;

            if (ZCashConstants.CoinbaseTxConfig.TryGetValue(poolConfig.Coin.Type, out var coinbaseTx))
            {
                coinbaseTx.TryGetValue(networkType, out coinbaseTxConfig);
            }

            BlockTemplate = blockTemplate;
            JobId         = jobId;
            Difficulty    = new Target(new NBitcoin.BouncyCastle.Math.BigInteger(BlockTemplate.Target, 16)).Difficulty;

            this.isPoS           = isPoS;
            this.shareMultiplier = shareMultiplier;

            this.headerHasher = headerHasher;
            this.blockHasher  = blockHasher;

            blockTargetValue = BigInteger.Parse(BlockTemplate.Target, NumberStyles.HexNumber);

            previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash
                                           .HexToByteArray()
                                           .ReverseArray()
                                           .ToHexString();

            blockReward = blockTemplate.Subsidy.Miner * BitcoinConstants.SatoshisPerBitcoin;

            if (coinbaseTxConfig?.PayFoundersReward == true)
            {
                var founders = blockTemplate.Subsidy.Founders ?? blockTemplate.Subsidy.Community;

                if (!founders.HasValue)
                {
                    throw new Exception("Error, founders reward missing for block template");
                }

                blockReward = (blockTemplate.Subsidy.Miner + founders.Value) * BitcoinConstants.SatoshisPerBitcoin;
            }

            rewardFees = blockTemplate.Transactions.Sum(x => x.Fee);

            BuildCoinbase();

            // build tx hashes
            var txHashes = new List <uint256> {
                new uint256(coinbaseInitialHash)
            };

            txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.Hash.HexToByteArray().ReverseArray())));

            // build merkle root
            merkleRoot            = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseArray();
            merkleRootReversed    = merkleRoot.ReverseArray();
            merkleRootReversedHex = merkleRootReversed.ToHexString();
        }
Example #15
0
        public void LeftRightHashVerificationTest()
        {
            MerkleNode parentNode = CreateParentNode("abc", "def");

            parentNode.VerifyHash().Should().BeTrue();
        }
Example #16
0
    public override void Init(EquihashBlockTemplate blockTemplate, string jobId,
                              PoolConfig poolConfig, ClusterConfig clusterConfig, IMasterClock clock,
                              IDestination poolAddressDestination, Network network,
                              EquihashSolver solver)
    {
        Contract.RequiresNonNull(blockTemplate, nameof(blockTemplate));
        Contract.RequiresNonNull(poolConfig, nameof(poolConfig));
        Contract.RequiresNonNull(clusterConfig, nameof(clusterConfig));
        Contract.RequiresNonNull(clock, nameof(clock));
        Contract.RequiresNonNull(poolAddressDestination, nameof(poolAddressDestination));
        Contract.Requires <ArgumentException>(!string.IsNullOrEmpty(jobId), $"{nameof(jobId)} must not be empty");

        this.clock = clock;
        this.poolAddressDestination = poolAddressDestination;
        coin         = poolConfig.Template.As <EquihashCoinTemplate>();
        this.network = network;
        var equihashTemplate = poolConfig.Template.As <EquihashCoinTemplate>();

        networkParams = coin.GetNetwork(network.ChainName);
        BlockTemplate = blockTemplate;
        JobId         = jobId;
        Difficulty    = (double)new BigRational(networkParams.Diff1BValue, BlockTemplate.Target.HexToReverseByteArray().AsSpan().ToBigInteger());

        this.solver = solver;

        if (!string.IsNullOrEmpty(BlockTemplate.Target))
        {
            blockTargetValue = new uint256(BlockTemplate.Target);
        }
        else
        {
            var tmp = new Target(BlockTemplate.Bits.HexToByteArray());
            blockTargetValue = tmp.ToUInt256();
        }

        previousBlockHashReversedHex = BlockTemplate.PreviousBlockhash
                                       .HexToByteArray()
                                       .ReverseInPlace()
                                       .ToHexString();

        BuildCoinbase();

        // build tx hashes
        var txHashes = new List <uint256> {
            new(coinbaseInitialHash)
        };

        txHashes.AddRange(BlockTemplate.Transactions.Select(tx => new uint256(tx.TxId.HexToReverseByteArray())));

        // build merkle root
        merkleRoot            = MerkleNode.GetRoot(txHashes).Hash.ToBytes().ReverseInPlace();
        merkleRootReversed    = merkleRoot.ReverseInPlace();
        merkleRootReversedHex = merkleRootReversed.ToHexString();

        jobParams = new object[]
        {
            JobId,
            BlockTemplate.Version.ReverseByteOrder().ToStringHex8(),
            previousBlockHashReversedHex,
            merkleRootReversedHex,
            BlockTemplate.Height.ReverseByteOrder().ToStringHex8() + sha256Empty.Take(28).ToHexString(), // height + hashReserved
            BlockTemplate.CurTime.ReverseByteOrder().ToStringHex8(),
            BlockTemplate.Bits.HexToReverseByteArray().ToHexString(),
            false
        };
    }
}
Example #17
0
 public void SetParent(MerkleNode parentNode)
 {
     Parent = parentNode;
 }