mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-23 06:22:31 +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
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
nativeerrors "errors"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/kaspanet/kaspad/rpcclient"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/kaspanet/kaspad/blockdag"
|
||||
"github.com/kaspanet/kaspad/rpcmodel"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
"github.com/kaspanet/kaspad/util/daghash"
|
||||
"github.com/kaspanet/kaspad/wire"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var random = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
@ -104,52 +98,6 @@ func handleFoundBlock(client *minerClient, block *util.Block) error {
|
||||
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) {
|
||||
msgBlock := block.MsgBlock()
|
||||
targetDifficulty := util.CompactToBig(msgBlock.Header.Bits)
|
||||
@ -231,7 +179,7 @@ func solveLoop(newTemplateChan chan *rpcmodel.GetBlockTemplateResult, foundBlock
|
||||
}
|
||||
|
||||
stopOldTemplateSolving = make(chan struct{})
|
||||
block, err := parseBlock(template)
|
||||
block, err := rpcclient.ConvertGetBlockTemplateResultToBlock(template)
|
||||
if err != nil {
|
||||
errChan <- errors.Errorf("Error parsing block: %s", err)
|
||||
return
|
||||
|
@ -7,8 +7,13 @@ package rpcclient
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/kaspanet/kaspad/rpcmodel"
|
||||
"github.com/kaspanet/kaspad/util"
|
||||
"github.com/kaspanet/kaspad/util/daghash"
|
||||
"github.com/kaspanet/kaspad/wire"
|
||||
"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) {
|
||||
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"`
|
||||
MassLimit int64 `json:"massLimit,omitempty"`
|
||||
Transactions []GetBlockTemplateResultTx `json:"transactions"`
|
||||
HashMerkleRoot string `json:"hashMerkleRoot"`
|
||||
AcceptedIDMerkleRoot string `json:"acceptedIdMerkleRoot"`
|
||||
UTXOCommitment string `json:"utxoCommitment"`
|
||||
Version int32 `json:"version"`
|
||||
|
@ -716,6 +716,7 @@ func (state *gbtWorkState) blockTemplateResult(s *Server) (*rpcmodel.GetBlockTem
|
||||
ParentHashes: daghash.Strings(header.ParentHashes),
|
||||
MassLimit: wire.MaxMassPerBlock,
|
||||
Transactions: transactions,
|
||||
HashMerkleRoot: header.HashMerkleRoot.String(),
|
||||
AcceptedIDMerkleRoot: header.AcceptedIDMerkleRoot.String(),
|
||||
UTXOCommitment: header.UTXOCommitment.String(),
|
||||
Version: header.Version,
|
||||
|
@ -313,6 +313,7 @@ var helpDescsEnUS = map[string]string{
|
||||
"getBlockTemplateResult-sigOpLimit": "Number of sigops allowed in blocks",
|
||||
"getBlockTemplateResult-massLimit": "Max transaction mass allowed in blocks",
|
||||
"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-utxoCommitment": "An ECMH UTXO commitment of this block",
|
||||
"getBlockTemplateResult-version": "The block version",
|
||||
|
Loading…
x
Reference in New Issue
Block a user