diff --git a/btcjson/dagsvrresults.go b/btcjson/dagsvrresults.go index 48336fb5c..b0e275fc7 100644 --- a/btcjson/dagsvrresults.go +++ b/btcjson/dagsvrresults.go @@ -135,18 +135,19 @@ type GetBlockTemplateResultAux struct { type GetBlockTemplateResult struct { // Base fields from BIP 0022. CoinbaseAux is optional. One of // CoinbaseTxn or CoinbaseValue must be specified, but not both. - Bits string `json:"bits"` - CurTime int64 `json:"curTime"` - Height uint64 `json:"height"` - ParentHashes []string `json:"parentHashes"` - SigOpLimit int64 `json:"sigOpLimit,omitempty"` - SizeLimit int64 `json:"sizeLimit,omitempty"` - Transactions []GetBlockTemplateResultTx `json:"transactions"` - Version int32 `json:"version"` - CoinbaseAux *GetBlockTemplateResultAux `json:"coinbaseAux,omitempty"` - CoinbaseTxn *GetBlockTemplateResultTx `json:"coinbaseTxn,omitempty"` - CoinbaseValue *uint64 `json:"coinbaseValue,omitempty"` - WorkID string `json:"workId,omitempty"` + Bits string `json:"bits"` + CurTime int64 `json:"curTime"` + Height uint64 `json:"height"` + ParentHashes []string `json:"parentHashes"` + SigOpLimit int64 `json:"sigOpLimit,omitempty"` + SizeLimit int64 `json:"sizeLimit,omitempty"` + Transactions []GetBlockTemplateResultTx `json:"transactions"` + AcceptedIDMerkleRoot string `json:"acceptedIdMerkleRoot"` + Version int32 `json:"version"` + CoinbaseAux *GetBlockTemplateResultAux `json:"coinbaseAux,omitempty"` + CoinbaseTxn *GetBlockTemplateResultTx `json:"coinbaseTxn,omitempty"` + CoinbaseValue *uint64 `json:"coinbaseValue,omitempty"` + WorkID string `json:"workId,omitempty"` // Optional long polling from BIP 0022. LongPollID string `json:"longPollId,omitempty"` diff --git a/mining/simulator/mineloop.go b/mining/simulator/mineloop.go index 93ae55d1a..843bedbc4 100644 --- a/mining/simulator/mineloop.go +++ b/mining/simulator/mineloop.go @@ -36,8 +36,15 @@ func parseBlock(template *btcjson.GetBlockTemplateResult) (*util.Block, error) { } 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 - 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...) { reader := hex.NewDecoder(strings.NewReader(txResult.Data)) @@ -48,7 +55,9 @@ func parseBlock(template *btcjson.GetBlockTemplateResult) (*util.Block, error) { 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) { @@ -124,10 +133,6 @@ func solveLoop(newTemplateChan chan *btcjson.GetBlockTemplateResult, foundBlock return } - msgBlock := block.MsgBlock() - - msgBlock.Header.HashMerkleRoot = blockdag.BuildHashMerkleTreeStore(block.Transactions()).Root() - go solveBlock(block, stopOldTemplateSolving, foundBlock) } } diff --git a/server/rpc/rpcserver.go b/server/rpc/rpcserver.go index 661eca64a..08b784b28 100644 --- a/server/rpc/rpcserver.go +++ b/server/rpc/rpcserver.go @@ -1780,22 +1780,23 @@ func (state *gbtWorkState) blockTemplateResult(useCoinbaseValue bool, submitOld targetDifficulty := fmt.Sprintf("%064x", util.CompactToBig(header.Bits)) longPollID := encodeLongPollID(state.tipHashes, state.lastGenerated) reply := btcjson.GetBlockTemplateResult{ - Bits: strconv.FormatInt(int64(header.Bits), 16), - CurTime: header.Timestamp.Unix(), - Height: template.Height, - ParentHashes: daghash.Strings(header.ParentHashes), - SigOpLimit: blockdag.MaxSigOpsPerBlock, - SizeLimit: wire.MaxBlockPayload, - Transactions: transactions, - Version: header.Version, - LongPollID: longPollID, - SubmitOld: submitOld, - Target: targetDifficulty, - MinTime: state.minTimestamp.Unix(), - MaxTime: maxTime.Unix(), - Mutable: gbtMutableFields, - NonceRange: gbtNonceRange, - Capabilities: gbtCapabilities, + Bits: strconv.FormatInt(int64(header.Bits), 16), + CurTime: header.Timestamp.Unix(), + Height: template.Height, + ParentHashes: daghash.Strings(header.ParentHashes), + SigOpLimit: blockdag.MaxSigOpsPerBlock, + SizeLimit: wire.MaxBlockPayload, + Transactions: transactions, + AcceptedIDMerkleRoot: header.AcceptedIDMerkleRoot.String(), + Version: header.Version, + LongPollID: longPollID, + SubmitOld: submitOld, + Target: targetDifficulty, + MinTime: state.minTimestamp.Unix(), + MaxTime: maxTime.Unix(), + Mutable: gbtMutableFields, + NonceRange: gbtNonceRange, + Capabilities: gbtCapabilities, } if useCoinbaseValue { diff --git a/server/rpc/rpcserverhelp.go b/server/rpc/rpcserverhelp.go index 284c7dee9..95ebfb9e5 100644 --- a/server/rpc/rpcserverhelp.go +++ b/server/rpc/rpcserverhelp.go @@ -307,29 +307,30 @@ var helpDescsEnUS = map[string]string{ "getBlockTemplateResultAux-flags": "Hex-encoded byte-for-byte data to include in the coinbase signature script", // GetBlockTemplateResult help. - "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-height": "Height of the block to be solved", - "getBlockTemplateResult-parentHashes": "Hex-encoded big-endian hashes of the parent blocks", - "getBlockTemplateResult-sigOpLimit": "Number of sigops allowed in blocks ", - "getBlockTemplateResult-sizeLimit": "Number of bytes allowed in blocks", - "getBlockTemplateResult-transactions": "Array of transactions as JSON objects", - "getBlockTemplateResult-version": "The block version", - "getBlockTemplateResult-coinbaseAux": "Data that should be included in the coinbase signature script", - "getBlockTemplateResult-coinbaseTxn": "Information about the coinbase transaction", - "getBlockTemplateResult-coinbaseValue": "Total amount available for the coinbase in Satoshi", - "getBlockTemplateResult-workId": "This value must be returned with result if provided (not provided)", - "getBlockTemplateResult-longPollId": "Identifier for long poll request which allows monitoring for expiration", - "getBlockTemplateResult-longPollUri": "An alternate URI to use for long poll requests if provided (not provided)", - "getBlockTemplateResult-submitOld": "Not applicable", - "getBlockTemplateResult-target": "Hex-encoded big-endian number which valid results must be less than", - "getBlockTemplateResult-expires": "Maximum number of seconds (starting from when the server sent the response) this work is valid for", - "getBlockTemplateResult-maxTime": "Maximum allowed time", - "getBlockTemplateResult-minTime": "Minimum allowed time", - "getBlockTemplateResult-mutable": "List of mutations the server explicitly allows", - "getBlockTemplateResult-nonceRange": "Two concatenated hex-encoded big-endian 64-bit integers which represent the valid ranges of nonces the miner may scan", - "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)", + "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-height": "Height of the block to be solved", + "getBlockTemplateResult-parentHashes": "Hex-encoded big-endian hashes of the parent blocks", + "getBlockTemplateResult-sigOpLimit": "Number of sigops allowed in blocks ", + "getBlockTemplateResult-sizeLimit": "Number of bytes allowed in blocks", + "getBlockTemplateResult-transactions": "Array of transactions as JSON objects", + "getBlockTemplateResult-acceptedIdMerkleRoot": "The root of the merkle tree of transaction IDs accepted by this block", + "getBlockTemplateResult-version": "The block version", + "getBlockTemplateResult-coinbaseAux": "Data that should be included in the coinbase signature script", + "getBlockTemplateResult-coinbaseTxn": "Information about the coinbase transaction", + "getBlockTemplateResult-coinbaseValue": "Total amount available for the coinbase in Satoshi", + "getBlockTemplateResult-workId": "This value must be returned with result if provided (not provided)", + "getBlockTemplateResult-longPollId": "Identifier for long poll request which allows monitoring for expiration", + "getBlockTemplateResult-longPollUri": "An alternate URI to use for long poll requests if provided (not provided)", + "getBlockTemplateResult-submitOld": "Not applicable", + "getBlockTemplateResult-target": "Hex-encoded big-endian number which valid results must be less than", + "getBlockTemplateResult-expires": "Maximum number of seconds (starting from when the server sent the response) this work is valid for", + "getBlockTemplateResult-maxTime": "Maximum allowed time", + "getBlockTemplateResult-minTime": "Minimum allowed time", + "getBlockTemplateResult-mutable": "List of mutations the server explicitly allows", + "getBlockTemplateResult-nonceRange": "Two concatenated hex-encoded big-endian 64-bit integers which represent the valid ranges of nonces the miner may scan", + "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. "getBlockTemplate--synopsis": "Returns a JSON object with information necessary to construct a block to mine or accepts a proposal to validate.\n" +