| 4905 | } |
| 4906 | |
| 4907 | std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBlockIndex* pindexPrev, const Consensus::Params& consensusParams, bool fProofOfStake) |
| 4908 | { |
| 4909 | std::vector<unsigned char> commitment; |
| 4910 | int commitpos = GetWitnessCommitmentIndex(block); |
| 4911 | bool fHaveWitness = false; |
| 4912 | for (size_t t = 1; t < block.vtx.size(); t++) { |
| 4913 | if (!block.vtx[t].wit.IsNull()) { |
| 4914 | fHaveWitness = true; |
| 4915 | break; |
| 4916 | } |
| 4917 | } |
| 4918 | std::vector<unsigned char> ret(32, 0x00); |
| 4919 | if (fHaveWitness && IsWitnessEnabled(pindexPrev, consensusParams)) { |
| 4920 | if (commitpos == -1) { |
| 4921 | uint256 witnessroot = BlockWitnessMerkleRoot(block, NULL, &fProofOfStake); |
| 4922 | CHash256().Write(witnessroot.begin(), 32).Write(ret.data(), 32).Finalize(witnessroot.begin()); |
| 4923 | CTxOut out; |
| 4924 | out.nValue = 0; |
| 4925 | out.scriptPubKey.resize(38); |
| 4926 | out.scriptPubKey[0] = OP_RETURN; |
| 4927 | out.scriptPubKey[1] = 0x24; |
| 4928 | out.scriptPubKey[2] = 0xaa; |
| 4929 | out.scriptPubKey[3] = 0x21; |
| 4930 | out.scriptPubKey[4] = 0xa9; |
| 4931 | out.scriptPubKey[5] = 0xed; |
| 4932 | memcpy(&out.scriptPubKey[6], witnessroot.begin(), 32); |
| 4933 | commitment = std::vector<unsigned char>(out.scriptPubKey.begin(), out.scriptPubKey.end()); |
| 4934 | const_cast<std::vector<CTxOut>*>(&block.vtx[0].vout)->push_back(out); |
| 4935 | block.vtx[0].UpdateHash(); |
| 4936 | } |
| 4937 | } |
| 4938 | UpdateUncommittedBlockStructures(block, pindexPrev, consensusParams); |
| 4939 | return commitment; |
| 4940 | } |
| 4941 | |
| 4942 | /** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ |
| 4943 | int static inline InvertLowestOne(int n) { return n & (n - 1); } |
no test coverage detected