/// 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()); }
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); }
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); }