Exemple #1
0
        /// Builds a new block ready to mine from the header of the previous block,
        /// a vector of transactions and the reward information. Checks
        /// that all transactions are valid and calculates the Merkle tree.
        public static Block with_reward(BlockHeader prev, Transaction.Transaction[] txs, Output rewardOut,
                                        TxKernel rewardKern)
        {
            // note: the following reads easily but may not be the most efficient due to
            // repeated iterations, revisit if a problem
            var secp = Secp256K1.WithCaps(ContextFlag.Commit);

            // validate each transaction and gather their kernels

            var kernels = txs.Select(tx => tx.verify_sig(secp)).ToList();

            kernels.Add(rewardKern);

            // build vectors with all inputs and all outputs, ordering them by hash
            // needs to be a fold so we don't end up with a vector of vectors and we
            // want to fully own the refs (not just a pointer like flat_map).

            var inputs  = new List <Input>();
            var outputs = new List <Output>();

            foreach (var tx in txs)
            {
                inputs.AddRange(tx.Inputs.Select(i => i.Clone()));

                outputs.AddRange(tx.Outputs.Select(o => o.Clone()));
            }

            outputs.Add(rewardOut);

            // calculate the overall Merkle tree and fees

            var bh = BlockHeader.Default();

            bh.Height    = prev.Height + 1;
            bh.Previous  = prev.Hash();
            bh.Timestamp = DateTime.UtcNow;

            bh.TotalDifficulty =
                Difficulty.From_num(prev.Pow.Clone().To_difficulty().Num + prev.TotalDifficulty.Clone().Num);

            var b = new Block
            {
                Header  = bh,
                Inputs  = inputs.ToArray(),
                Outputs = outputs.ToArray(),
                Kernels = kernels.ToArray()
            };

            return(b.Compact());
        }
Exemple #2
0
        public static (Output, TxKernel) Reward_output(Keychain keychain, Identifier keyId, ulong fees)
        {
            var secp = keychain.Secp;

            var commit           = keychain.Commit(Consensus.Reward(fees), keyId);
            var switchCommit     = keychain.Switch_commit(keyId);
            var switchCommitHash = SwitchCommitHash.From_switch_commit(switchCommit);

            Log.Verbose(
                "Block reward - Pedersen Commit is: {commit}, Switch Commit is: {switch_commit}",
                commit,
                switchCommit
                );

            Log.Verbose(
                "Block reward - Switch Commit Hash is: {  switch_commit_hash}",
                switchCommitHash
                );

            var msg    = ProofMessage.Empty();
            var rproof = keychain.Range_proof(Consensus.Reward(fees), keyId, commit, msg);

            var output = new Output
            {
                Features         = OutputFeatures.CoinbaseOutput,
                Commit           = commit,
                SwitchCommitHash = switchCommitHash,
                Proof            = rproof
            };

            var overCommit = secp.commit_value(Consensus.Reward(fees));
            var outCommit  = output.Commit;
            var excess     = secp.commit_sum(new[] { outCommit }, new[] { overCommit });

            var msg2 = Message.from_slice(new byte[Constants.MessageSize]);
            var sig  = keychain.Sign(msg2, keyId);

            var proof = new TxKernel
            {
                Features   = KernelFeatures.CoinbaseKernel,
                Excess     = excess,
                ExcessSig  = sig.serialize_der(secp),
                Fee        = 0,
                LockHeight = 0
            };

            return(output, proof);
        }
Exemple #3
0
        public void Test_kernel_ser_deser()
        {
            var keychain = Keychain.From_random_seed();
            var keyId    = keychain.Derive_key_id(1);
            var commit   = keychain.Commit(5, keyId);

            // just some bytes for testing ser/deser
            var sig = new byte[] { 1, 0, 0, 0, 0, 0, 0, 1 };

            var kernel = new TxKernel
            {
                Features   = KernelFeatures.DefaultKernel,
                LockHeight = 0,
                Excess     = commit,
                ExcessSig  = sig,
                Fee        = 10
            };

            var stream = new MemoryStream();

            Ser.Serialize(stream, kernel);

            Console.WriteLine("-------");
            Console.WriteLine(stream.ToArray().AsString());
            Console.WriteLine("-------");

            stream.Position = 0;

            var kernel2 = Ser.Deserialize(stream, new TxKernel());

            Assert.Equal(KernelFeatures.DefaultKernel, kernel2.Features);
            Assert.Equal <ulong>(0, kernel2.LockHeight);
            Assert.Equal(commit.Value, kernel2.Excess.Value);
            Assert.Equal(sig, kernel2.ExcessSig);
            Assert.Equal <ulong>(10, kernel2.Fee);

            //// now check a kernel with lock_height serializes/deserializes correctly
            kernel = new TxKernel
            {
                Features   = KernelFeatures.DefaultKernel,
                LockHeight = 100,
                Excess     = commit,
                ExcessSig  = sig,
                Fee        = 10
            };

            stream = new MemoryStream();
            Ser.Serialize(stream, kernel);

            Console.WriteLine("-------");
            Console.WriteLine(stream.ToArray().AsString());
            Console.WriteLine("-------");

            stream.Position = 0;

            kernel2 = Ser.Deserialize(stream, new TxKernel());
            Assert.Equal(KernelFeatures.DefaultKernel, kernel2.Features);
            Assert.Equal <ulong>(100, kernel2.LockHeight);
            Assert.Equal(commit.Value, kernel2.Excess.Value);
            Assert.Equal(sig, kernel2.ExcessSig);
            Assert.Equal <ulong>(10, kernel2.Fee);
        }