[NOD-182] Added AcceptedIDMerkleRoot to GetBlockTemplateResult (#301)

This commit is contained in:
Svarog 2019-05-16 12:44:25 +03:00 committed by Ori Newman
parent b1d3ca0206
commit ac1fd11a42
4 changed files with 65 additions and 57 deletions

View File

@ -135,18 +135,19 @@ type GetBlockTemplateResultAux struct {
type GetBlockTemplateResult struct { type GetBlockTemplateResult struct {
// Base fields from BIP 0022. CoinbaseAux is optional. One of // Base fields from BIP 0022. CoinbaseAux is optional. One of
// CoinbaseTxn or CoinbaseValue must be specified, but not both. // CoinbaseTxn or CoinbaseValue must be specified, but not both.
Bits string `json:"bits"` Bits string `json:"bits"`
CurTime int64 `json:"curTime"` CurTime int64 `json:"curTime"`
Height uint64 `json:"height"` Height uint64 `json:"height"`
ParentHashes []string `json:"parentHashes"` ParentHashes []string `json:"parentHashes"`
SigOpLimit int64 `json:"sigOpLimit,omitempty"` SigOpLimit int64 `json:"sigOpLimit,omitempty"`
SizeLimit int64 `json:"sizeLimit,omitempty"` SizeLimit int64 `json:"sizeLimit,omitempty"`
Transactions []GetBlockTemplateResultTx `json:"transactions"` Transactions []GetBlockTemplateResultTx `json:"transactions"`
Version int32 `json:"version"` AcceptedIDMerkleRoot string `json:"acceptedIdMerkleRoot"`
CoinbaseAux *GetBlockTemplateResultAux `json:"coinbaseAux,omitempty"` Version int32 `json:"version"`
CoinbaseTxn *GetBlockTemplateResultTx `json:"coinbaseTxn,omitempty"` CoinbaseAux *GetBlockTemplateResultAux `json:"coinbaseAux,omitempty"`
CoinbaseValue *uint64 `json:"coinbaseValue,omitempty"` CoinbaseTxn *GetBlockTemplateResultTx `json:"coinbaseTxn,omitempty"`
WorkID string `json:"workId,omitempty"` CoinbaseValue *uint64 `json:"coinbaseValue,omitempty"`
WorkID string `json:"workId,omitempty"`
// Optional long polling from BIP 0022. // Optional long polling from BIP 0022.
LongPollID string `json:"longPollId,omitempty"` LongPollID string `json:"longPollId,omitempty"`

View File

@ -36,8 +36,15 @@ func parseBlock(template *btcjson.GetBlockTemplateResult) (*util.Block, error) {
} }
bits := uint32(bitsInt64) bits := uint32(bitsInt64)
// parseAcceptedIDMerkleRoot
acceptedIDMerkleRoot, err := daghash.NewHashFromStr(template.AcceptedIDMerkleRoot)
if err != nil {
return nil, fmt.Errorf("Error parsing acceptedIDMerkleRoot: %s", err)
}
// parse rest of block // parse rest of block
msgBlock := wire.NewMsgBlock(wire.NewBlockHeader(template.Version, parentHashes, &daghash.Hash{}, &daghash.Hash{}, &daghash.Hash{}, uint32(bits), 0)) msgBlock := wire.NewMsgBlock(
wire.NewBlockHeader(template.Version, parentHashes, &daghash.Hash{},
acceptedIDMerkleRoot, &daghash.Hash{}, uint32(bits), 0))
for i, txResult := range append([]btcjson.GetBlockTemplateResultTx{*template.CoinbaseTxn}, template.Transactions...) { for i, txResult := range append([]btcjson.GetBlockTemplateResultTx{*template.CoinbaseTxn}, template.Transactions...) {
reader := hex.NewDecoder(strings.NewReader(txResult.Data)) reader := hex.NewDecoder(strings.NewReader(txResult.Data))
@ -48,7 +55,9 @@ func parseBlock(template *btcjson.GetBlockTemplateResult) (*util.Block, error) {
msgBlock.AddTransaction(tx) msgBlock.AddTransaction(tx)
} }
return util.NewBlock(msgBlock), nil block := util.NewBlock(msgBlock)
msgBlock.Header.HashMerkleRoot = blockdag.BuildHashMerkleTreeStore(block.Transactions()).Root()
return block, nil
} }
func solveBlock(block *util.Block, stopChan chan struct{}, foundBlock chan *util.Block) { func solveBlock(block *util.Block, stopChan chan struct{}, foundBlock chan *util.Block) {
@ -124,10 +133,6 @@ func solveLoop(newTemplateChan chan *btcjson.GetBlockTemplateResult, foundBlock
return return
} }
msgBlock := block.MsgBlock()
msgBlock.Header.HashMerkleRoot = blockdag.BuildHashMerkleTreeStore(block.Transactions()).Root()
go solveBlock(block, stopOldTemplateSolving, foundBlock) go solveBlock(block, stopOldTemplateSolving, foundBlock)
} }
} }

View File

@ -1780,22 +1780,23 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld
targetDifficulty := fmt.Sprintf("%064x", util.CompactToBig(header.Bits)) targetDifficulty := fmt.Sprintf("%064x", util.CompactToBig(header.Bits))
longPollID := encodeLongPollID(state.tipHashes, state.lastGenerated) longPollID := encodeLongPollID(state.tipHashes, state.lastGenerated)
reply := btcjson.GetBlockTemplateResult{ reply := btcjson.GetBlockTemplateResult{
Bits: strconv.FormatInt(int64(header.Bits), 16), Bits: strconv.FormatInt(int64(header.Bits), 16),
CurTime: header.Timestamp.Unix(), CurTime: header.Timestamp.Unix(),
Height: template.Height, Height: template.Height,
ParentHashes: daghash.Strings(header.ParentHashes), ParentHashes: daghash.Strings(header.ParentHashes),
SigOpLimit: blockdag.MaxSigOpsPerBlock, SigOpLimit: blockdag.MaxSigOpsPerBlock,
SizeLimit: wire.MaxBlockPayload, SizeLimit: wire.MaxBlockPayload,
Transactions: transactions, Transactions: transactions,
Version: header.Version, AcceptedIDMerkleRoot: header.AcceptedIDMerkleRoot.String(),
LongPollID: longPollID, Version: header.Version,
SubmitOld: submitOld, LongPollID: longPollID,
Target: targetDifficulty, SubmitOld: submitOld,
MinTime: state.minTimestamp.Unix(), Target: targetDifficulty,
MaxTime: maxTime.Unix(), MinTime: state.minTimestamp.Unix(),
Mutable: gbtMutableFields, MaxTime: maxTime.Unix(),
NonceRange: gbtNonceRange, Mutable: gbtMutableFields,
Capabilities: gbtCapabilities, NonceRange: gbtNonceRange,
Capabilities: gbtCapabilities,
} }
if useCoinbaseValue { if useCoinbaseValue {

View File

@ -307,29 +307,30 @@ var helpDescsEnUS = map[string]string{
"getBlockTemplateResultAux-flags": "Hex-encoded byte-for-byte data to include in the coinbase signature script", "getBlockTemplateResultAux-flags": "Hex-encoded byte-for-byte data to include in the coinbase signature script",
// GetBlockTemplateResult help. // GetBlockTemplateResult help.
"getBlockTemplateResult-bits": "Hex-encoded compressed difficulty", "getBlockTemplateResult-bits": "Hex-encoded compressed difficulty",
"getBlockTemplateResult-curTime": "Current time as seen by the server (recommended for block time); must fall within mintime/maxtime rules", "getBlockTemplateResult-curTime": "Current time as seen by the server (recommended for block time); must fall within mintime/maxtime rules",
"getBlockTemplateResult-height": "Height of the block to be solved", "getBlockTemplateResult-height": "Height of the block to be solved",
"getBlockTemplateResult-parentHashes": "Hex-encoded big-endian hashes of the parent blocks", "getBlockTemplateResult-parentHashes": "Hex-encoded big-endian hashes of the parent blocks",
"getBlockTemplateResult-sigOpLimit": "Number of sigops allowed in blocks ", "getBlockTemplateResult-sigOpLimit": "Number of sigops allowed in blocks ",
"getBlockTemplateResult-sizeLimit": "Number of bytes allowed in blocks", "getBlockTemplateResult-sizeLimit": "Number of bytes allowed in blocks",
"getBlockTemplateResult-transactions": "Array of transactions as JSON objects", "getBlockTemplateResult-transactions": "Array of transactions as JSON objects",
"getBlockTemplateResult-version": "The block version", "getBlockTemplateResult-acceptedIdMerkleRoot": "The root of the merkle tree of transaction IDs accepted by this block",
"getBlockTemplateResult-coinbaseAux": "Data that should be included in the coinbase signature script", "getBlockTemplateResult-version": "The block version",
"getBlockTemplateResult-coinbaseTxn": "Information about the coinbase transaction", "getBlockTemplateResult-coinbaseAux": "Data that should be included in the coinbase signature script",
"getBlockTemplateResult-coinbaseValue": "Total amount available for the coinbase in Satoshi", "getBlockTemplateResult-coinbaseTxn": "Information about the coinbase transaction",
"getBlockTemplateResult-workId": "This value must be returned with result if provided (not provided)", "getBlockTemplateResult-coinbaseValue": "Total amount available for the coinbase in Satoshi",
"getBlockTemplateResult-longPollId": "Identifier for long poll request which allows monitoring for expiration", "getBlockTemplateResult-workId": "This value must be returned with result if provided (not provided)",
"getBlockTemplateResult-longPollUri": "An alternate URI to use for long poll requests if provided (not provided)", "getBlockTemplateResult-longPollId": "Identifier for long poll request which allows monitoring for expiration",
"getBlockTemplateResult-submitOld": "Not applicable", "getBlockTemplateResult-longPollUri": "An alternate URI to use for long poll requests if provided (not provided)",
"getBlockTemplateResult-target": "Hex-encoded big-endian number which valid results must be less than", "getBlockTemplateResult-submitOld": "Not applicable",
"getBlockTemplateResult-expires": "Maximum number of seconds (starting from when the server sent the response) this work is valid for", "getBlockTemplateResult-target": "Hex-encoded big-endian number which valid results must be less than",
"getBlockTemplateResult-maxTime": "Maximum allowed time", "getBlockTemplateResult-expires": "Maximum number of seconds (starting from when the server sent the response) this work is valid for",
"getBlockTemplateResult-minTime": "Minimum allowed time", "getBlockTemplateResult-maxTime": "Maximum allowed time",
"getBlockTemplateResult-mutable": "List of mutations the server explicitly allows", "getBlockTemplateResult-minTime": "Minimum allowed time",
"getBlockTemplateResult-nonceRange": "Two concatenated hex-encoded big-endian 64-bit integers which represent the valid ranges of nonces the miner may scan", "getBlockTemplateResult-mutable": "List of mutations the server explicitly allows",
"getBlockTemplateResult-capabilities": "List of server capabilities including 'proposal' to indicate support for block proposals", "getBlockTemplateResult-nonceRange": "Two concatenated hex-encoded big-endian 64-bit integers which represent the valid ranges of nonces the miner may scan",
"getBlockTemplateResult-rejectReason": "Reason the proposal was invalid as-is (only applies to proposal responses)", "getBlockTemplateResult-capabilities": "List of server capabilities including 'proposal' to indicate support for block proposals",
"getBlockTemplateResult-rejectReason": "Reason the proposal was invalid as-is (only applies to proposal responses)",
// GetBlockTemplateCmd help. // GetBlockTemplateCmd help.
"getBlockTemplate--synopsis": "Returns a JSON object with information necessary to construct a block to mine or accepts a proposal to validate.\n" + "getBlockTemplate--synopsis": "Returns a JSON object with information necessary to construct a block to mine or accepts a proposal to validate.\n" +