mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-23 14:32:32 +00:00
[NOD-1093] Add hashMerkleRoot to GetBlockTemplateResult (#776)
* Add hashMerkleRoot field to GetBlockTemplateResult * Use hashMerkleRoot from template instead of recalculating * Move ParseBlock from kaspaminer into rpcclient * Rename ParseBlock to ConvertGetBlockTemplateResultToBlock and wrap errors
This commit is contained in:
parent
0a7a4ce7d6
commit
d3c6a3dffc
@ -1,23 +1,17 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
nativeerrors "errors"
|
nativeerrors "errors"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/rpcclient"
|
"github.com/kaspanet/kaspad/rpcclient"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/blockdag"
|
|
||||||
"github.com/kaspanet/kaspad/rpcmodel"
|
"github.com/kaspanet/kaspad/rpcmodel"
|
||||||
"github.com/kaspanet/kaspad/util"
|
"github.com/kaspanet/kaspad/util"
|
||||||
"github.com/kaspanet/kaspad/util/daghash"
|
"github.com/kaspanet/kaspad/util/daghash"
|
||||||
"github.com/kaspanet/kaspad/wire"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var random = rand.New(rand.NewSource(time.Now().UnixNano()))
|
var random = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
@ -104,52 +98,6 @@ func handleFoundBlock(client *minerClient, block *util.Block) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseBlock(template *rpcmodel.GetBlockTemplateResult) (*util.Block, error) {
|
|
||||||
// parse parent hashes
|
|
||||||
parentHashes := make([]*daghash.Hash, len(template.ParentHashes))
|
|
||||||
for i, parentHash := range template.ParentHashes {
|
|
||||||
hash, err := daghash.NewHashFromStr(parentHash)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Errorf("Error decoding hash %s: %s", parentHash, err)
|
|
||||||
}
|
|
||||||
parentHashes[i] = hash
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse Bits
|
|
||||||
bitsUint64, err := strconv.ParseUint(template.Bits, 16, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Errorf("Error decoding bits %s: %s", template.Bits, err)
|
|
||||||
}
|
|
||||||
bits := uint32(bitsUint64)
|
|
||||||
|
|
||||||
// parseAcceptedIDMerkleRoot
|
|
||||||
acceptedIDMerkleRoot, err := daghash.NewHashFromStr(template.AcceptedIDMerkleRoot)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Errorf("Error parsing acceptedIDMerkleRoot: %s", err)
|
|
||||||
}
|
|
||||||
utxoCommitment, err := daghash.NewHashFromStr(template.UTXOCommitment)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Errorf("Error parsing utxoCommitment: %s", err)
|
|
||||||
}
|
|
||||||
// parse rest of block
|
|
||||||
msgBlock := wire.NewMsgBlock(
|
|
||||||
wire.NewBlockHeader(template.Version, parentHashes, &daghash.Hash{},
|
|
||||||
acceptedIDMerkleRoot, utxoCommitment, bits, 0))
|
|
||||||
|
|
||||||
for i, txResult := range template.Transactions {
|
|
||||||
reader := hex.NewDecoder(strings.NewReader(txResult.Data))
|
|
||||||
tx := &wire.MsgTx{}
|
|
||||||
if err := tx.KaspaDecode(reader, 0); err != nil {
|
|
||||||
return nil, errors.Errorf("Error decoding tx #%d: %s", i, err)
|
|
||||||
}
|
|
||||||
msgBlock.AddTransaction(tx)
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
||||||
msgBlock := block.MsgBlock()
|
msgBlock := block.MsgBlock()
|
||||||
targetDifficulty := util.CompactToBig(msgBlock.Header.Bits)
|
targetDifficulty := util.CompactToBig(msgBlock.Header.Bits)
|
||||||
@ -231,7 +179,7 @@ func solveLoop(newTemplateChan chan *rpcmodel.GetBlockTemplateResult, foundBlock
|
|||||||
}
|
}
|
||||||
|
|
||||||
stopOldTemplateSolving = make(chan struct{})
|
stopOldTemplateSolving = make(chan struct{})
|
||||||
block, err := parseBlock(template)
|
block, err := rpcclient.ConvertGetBlockTemplateResultToBlock(template)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errChan <- errors.Errorf("Error parsing block: %s", err)
|
errChan <- errors.Errorf("Error parsing block: %s", err)
|
||||||
return
|
return
|
||||||
|
@ -7,8 +7,13 @@ package rpcclient
|
|||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/kaspanet/kaspad/rpcmodel"
|
"github.com/kaspanet/kaspad/rpcmodel"
|
||||||
"github.com/kaspanet/kaspad/util"
|
"github.com/kaspanet/kaspad/util"
|
||||||
|
"github.com/kaspanet/kaspad/util/daghash"
|
||||||
|
"github.com/kaspanet/kaspad/wire"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -100,3 +105,55 @@ func (r FutureGetBlockTemplateResult) Receive() (*rpcmodel.GetBlockTemplateResul
|
|||||||
func (c *Client) GetBlockTemplate(payAddress string, longPollID string) (*rpcmodel.GetBlockTemplateResult, error) {
|
func (c *Client) GetBlockTemplate(payAddress string, longPollID string) (*rpcmodel.GetBlockTemplateResult, error) {
|
||||||
return c.GetBlockTemplateAsync(payAddress, longPollID).Receive()
|
return c.GetBlockTemplateAsync(payAddress, longPollID).Receive()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConvertGetBlockTemplateResultToBlock Accepts a GetBlockTemplateResult and parses it into a Block
|
||||||
|
func ConvertGetBlockTemplateResultToBlock(template *rpcmodel.GetBlockTemplateResult) (*util.Block, error) {
|
||||||
|
// parse parent hashes
|
||||||
|
parentHashes := make([]*daghash.Hash, len(template.ParentHashes))
|
||||||
|
for i, parentHash := range template.ParentHashes {
|
||||||
|
hash, err := daghash.NewHashFromStr(parentHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error decoding hash: '%s'", parentHash)
|
||||||
|
}
|
||||||
|
parentHashes[i] = hash
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse Bits
|
||||||
|
bitsUint64, err := strconv.ParseUint(template.Bits, 16, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error decoding bits: '%s'", template.Bits)
|
||||||
|
}
|
||||||
|
bits := uint32(bitsUint64)
|
||||||
|
|
||||||
|
// parse hashMerkleRoot
|
||||||
|
hashMerkleRoot, err := daghash.NewHashFromStr(template.HashMerkleRoot)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error parsing HashMerkleRoot: '%s'", template.HashMerkleRoot)
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse AcceptedIDMerkleRoot
|
||||||
|
acceptedIDMerkleRoot, err := daghash.NewHashFromStr(template.AcceptedIDMerkleRoot)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error parsing acceptedIDMerkleRoot: '%s'", template.AcceptedIDMerkleRoot)
|
||||||
|
}
|
||||||
|
utxoCommitment, err := daghash.NewHashFromStr(template.UTXOCommitment)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error parsing utxoCommitment '%s'", template.UTXOCommitment)
|
||||||
|
}
|
||||||
|
// parse rest of block
|
||||||
|
msgBlock := wire.NewMsgBlock(
|
||||||
|
wire.NewBlockHeader(template.Version, parentHashes, hashMerkleRoot,
|
||||||
|
acceptedIDMerkleRoot, utxoCommitment, bits, 0))
|
||||||
|
|
||||||
|
for i, txResult := range template.Transactions {
|
||||||
|
reader := hex.NewDecoder(strings.NewReader(txResult.Data))
|
||||||
|
tx := &wire.MsgTx{}
|
||||||
|
if err := tx.KaspaDecode(reader, 0); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error decoding tx #%d", i)
|
||||||
|
}
|
||||||
|
msgBlock.AddTransaction(tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
block := util.NewBlock(msgBlock)
|
||||||
|
return block, nil
|
||||||
|
}
|
||||||
|
@ -141,6 +141,7 @@ type GetBlockTemplateResult struct {
|
|||||||
ParentHashes []string `json:"parentHashes"`
|
ParentHashes []string `json:"parentHashes"`
|
||||||
MassLimit int64 `json:"massLimit,omitempty"`
|
MassLimit int64 `json:"massLimit,omitempty"`
|
||||||
Transactions []GetBlockTemplateResultTx `json:"transactions"`
|
Transactions []GetBlockTemplateResultTx `json:"transactions"`
|
||||||
|
HashMerkleRoot string `json:"hashMerkleRoot"`
|
||||||
AcceptedIDMerkleRoot string `json:"acceptedIdMerkleRoot"`
|
AcceptedIDMerkleRoot string `json:"acceptedIdMerkleRoot"`
|
||||||
UTXOCommitment string `json:"utxoCommitment"`
|
UTXOCommitment string `json:"utxoCommitment"`
|
||||||
Version int32 `json:"version"`
|
Version int32 `json:"version"`
|
||||||
|
@ -716,6 +716,7 @@ func (state *gbtWorkState) blockTemplateResult(s *Server) (*rpcmodel.GetBlockTem
|
|||||||
ParentHashes: daghash.Strings(header.ParentHashes),
|
ParentHashes: daghash.Strings(header.ParentHashes),
|
||||||
MassLimit: wire.MaxMassPerBlock,
|
MassLimit: wire.MaxMassPerBlock,
|
||||||
Transactions: transactions,
|
Transactions: transactions,
|
||||||
|
HashMerkleRoot: header.HashMerkleRoot.String(),
|
||||||
AcceptedIDMerkleRoot: header.AcceptedIDMerkleRoot.String(),
|
AcceptedIDMerkleRoot: header.AcceptedIDMerkleRoot.String(),
|
||||||
UTXOCommitment: header.UTXOCommitment.String(),
|
UTXOCommitment: header.UTXOCommitment.String(),
|
||||||
Version: header.Version,
|
Version: header.Version,
|
||||||
|
@ -313,6 +313,7 @@ var helpDescsEnUS = map[string]string{
|
|||||||
"getBlockTemplateResult-sigOpLimit": "Number of sigops allowed in blocks",
|
"getBlockTemplateResult-sigOpLimit": "Number of sigops allowed in blocks",
|
||||||
"getBlockTemplateResult-massLimit": "Max transaction mass allowed in blocks",
|
"getBlockTemplateResult-massLimit": "Max transaction mass allowed in blocks",
|
||||||
"getBlockTemplateResult-transactions": "Array of transactions as JSON objects",
|
"getBlockTemplateResult-transactions": "Array of transactions as JSON objects",
|
||||||
|
"getBlockTemplateResult-hashMerkleRoot": "The root of the merkle tree of all transaction IDs in this block",
|
||||||
"getBlockTemplateResult-acceptedIdMerkleRoot": "The root of the merkle tree of transaction IDs accepted by this block",
|
"getBlockTemplateResult-acceptedIdMerkleRoot": "The root of the merkle tree of transaction IDs accepted by this block",
|
||||||
"getBlockTemplateResult-utxoCommitment": "An ECMH UTXO commitment of this block",
|
"getBlockTemplateResult-utxoCommitment": "An ECMH UTXO commitment of this block",
|
||||||
"getBlockTemplateResult-version": "The block version",
|
"getBlockTemplateResult-version": "The block version",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user