diff --git a/blockchain/blockindex.go b/blockchain/blockindex.go index 2ff2fa27..1531e6b1 100644 --- a/blockchain/blockindex.go +++ b/blockchain/blockindex.go @@ -93,6 +93,7 @@ type blockNode struct { nonce uint32 timestamp int64 merkleRoot chainhash.Hash + claimTrie chainhash.Hash // status is a bitfield representing the validation state of the block. The // status field, unlike the other fields, may be written to and so should @@ -114,6 +115,7 @@ func initBlockNode(node *blockNode, blockHeader *wire.BlockHeader, parent *block nonce: blockHeader.Nonce, timestamp: blockHeader.Timestamp.Unix(), merkleRoot: blockHeader.MerkleRoot, + claimTrie: blockHeader.ClaimTrie, } if parent != nil { node.parent = parent @@ -144,6 +146,7 @@ func (node *blockNode) Header() wire.BlockHeader { Version: node.version, PrevBlock: *prevHash, MerkleRoot: node.merkleRoot, + ClaimTrie: node.claimTrie, Timestamp: time.Unix(node.timestamp, 0), Bits: node.bits, Nonce: node.nonce, diff --git a/blockchain/error.go b/blockchain/error.go index 1e7c879b..f18648f3 100644 --- a/blockchain/error.go +++ b/blockchain/error.go @@ -220,6 +220,10 @@ const ( // current chain tip. This is not a block validation rule, but is required // for block proposals submitted via getblocktemplate RPC. ErrPrevBlockNotBest + + // ErrBadClaimTrie indicates the calculated ClaimTrie root does not match + // the expected value. + ErrBadClaimTrie ) // Map of ErrorCode values back to their constant names for pretty printing. @@ -267,6 +271,7 @@ var errorCodeStrings = map[ErrorCode]string{ ErrPreviousBlockUnknown: "ErrPreviousBlockUnknown", ErrInvalidAncestorBlock: "ErrInvalidAncestorBlock", ErrPrevBlockNotBest: "ErrPrevBlockNotBest", + ErrBadClaimTrie: "ErrBadClaimTrie", } // String returns the ErrorCode as a human-readable name. diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 59f18c74..405fd867 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -25,6 +25,7 @@ type GetBlockHeaderVerboseResult struct { Version int32 `json:"version"` VersionHex string `json:"versionHex"` MerkleRoot string `json:"merkleroot"` + ClaimTrie string `json:"claimtrie"` Time int64 `json:"time"` Nonce uint64 `json:"nonce"` Bits string `json:"bits"` @@ -81,6 +82,7 @@ type GetBlockVerboseResult struct { Version int32 `json:"version"` VersionHex string `json:"versionHex"` MerkleRoot string `json:"merkleroot"` + ClaimTrie string `json:"claimTrie"` Tx []string `json:"tx,omitempty"` RawTx []TxRawResult `json:"rawtx,omitempty"` // Note: this field is always empty when verbose != 2. Time int64 `json:"time"` diff --git a/wire/blockheader.go b/wire/blockheader.go index 9c9c2237..b4d0531e 100644 --- a/wire/blockheader.go +++ b/wire/blockheader.go @@ -15,7 +15,7 @@ import ( // MaxBlockHeaderPayload is the maximum number of bytes a block header can be. // Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes + // PrevBlock and MerkleRoot hashes. -const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 2) +const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 3) // BlockHeader defines information about a block and is used in the bitcoin // block (MsgBlock) and headers (MsgHeaders) messages. @@ -29,6 +29,9 @@ type BlockHeader struct { // Merkle tree reference to hash of all transactions for the block. MerkleRoot chainhash.Hash + // ClaimTrie reference to hash of ClaimTrie. + ClaimTrie chainhash.Hash + // Time the block was created. This is, unfortunately, encoded as a // uint32 on the wire and therefore is limited to 2106. Timestamp time.Time @@ -96,7 +99,7 @@ func (h *BlockHeader) Serialize(w io.Writer) error { // block hash, merkle root hash, difficulty bits, and nonce used to generate the // block with defaults for the remaining fields. func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, - bits uint32, nonce uint32) *BlockHeader { + claimTrieHash *chainhash.Hash, bits uint32, nonce uint32) *BlockHeader { // Limit the timestamp to one second precision since the protocol // doesn't support better. @@ -104,6 +107,7 @@ func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, Version: version, PrevBlock: *prevHash, MerkleRoot: *merkleRootHash, + ClaimTrie: *claimTrieHash, Timestamp: time.Unix(time.Now().Unix(), 0), Bits: bits, Nonce: nonce, @@ -115,7 +119,7 @@ func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash, // decoding from the wire. func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error { return readElements(r, &bh.Version, &bh.PrevBlock, &bh.MerkleRoot, - (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce) + &bh.ClaimTrie, (*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce) } // writeBlockHeader writes a bitcoin block header to w. See Serialize for @@ -124,5 +128,5 @@ func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error { func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error { sec := uint32(bh.Timestamp.Unix()) return writeElements(w, bh.Version, &bh.PrevBlock, &bh.MerkleRoot, - sec, bh.Bits, bh.Nonce) + &bh.ClaimTrie, sec, bh.Bits, bh.Nonce) }