mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-04 13:16:43 +00:00

* [NOD-70] Added GetBlockTemplate method to rpcclient * [NOD-70] Basic infrastructure for mining simulator * [NOD-70] Fix txFees in NewBlockTempalte: include value for fee transaction + don't set fee for coinbase = -totalFees. * [NOD-70] Added capabilities parameter to Client.GetBlockTemplate call * [NOD-70] Dirty version of mining simulator complete * [NOD-70] cleaned up mining simulator * [NOD-70] Added dockerfile to mining simulator * [NOD-70] Updated base config path of mining simulator to mining_simulator * [NOD-70] Remove error return from msgblock.AddTransaction - it never returns one * [NOD-70] Renamed r -> random * [NOD-70] Move paths initialization of mining simulator to main * [NOD-70] Cleaned up mining simulator dockerfile * [NOD-70] Add '--' to tini argument
108 lines
2.9 KiB
Go
108 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"fmt"
|
|
"log"
|
|
"math/rand"
|
|
"strconv"
|
|
"strings"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"github.com/daglabs/btcd/blockdag"
|
|
"github.com/daglabs/btcd/btcjson"
|
|
"github.com/daglabs/btcd/dagconfig/daghash"
|
|
"github.com/daglabs/btcd/rpcclient"
|
|
"github.com/daglabs/btcd/util"
|
|
"github.com/daglabs/btcd/wire"
|
|
)
|
|
|
|
var random = rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
|
func parseBlock(template *btcjson.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, fmt.Errorf("Error decoding hash %s: %s", parentHash, err)
|
|
}
|
|
parentHashes[i] = *hash
|
|
}
|
|
|
|
// parse Bits
|
|
bitsInt64, err := strconv.ParseInt(template.Bits, 16, 32)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("Error decoding bits %s: %s", template.Bits, err)
|
|
}
|
|
bits := uint32(bitsInt64)
|
|
|
|
// parse rest of block
|
|
msgBlock := wire.NewMsgBlock(wire.NewBlockHeader(template.Version, parentHashes, &daghash.Hash{}, &daghash.Hash{}, uint32(bits), 0))
|
|
|
|
for i, txResult := range append([]btcjson.GetBlockTemplateResultTx{*template.CoinbaseTxn}, template.Transactions...) {
|
|
reader := hex.NewDecoder(strings.NewReader(txResult.Data))
|
|
tx := &wire.MsgTx{}
|
|
if err := tx.BtcDecode(reader, 0); err != nil {
|
|
return nil, fmt.Errorf("Error decoding tx #%d: %s", i, err)
|
|
}
|
|
msgBlock.AddTransaction(tx)
|
|
}
|
|
|
|
return util.NewBlock(msgBlock), nil
|
|
}
|
|
|
|
func solveBlock(msgBlock *wire.MsgBlock) {
|
|
maxNonce := ^uint64(0) // 2^64 - 1
|
|
targetDifficulty := util.CompactToBig(msgBlock.Header.Bits)
|
|
for i := uint64(0); i < maxNonce; i++ {
|
|
msgBlock.Header.Nonce = i
|
|
hash := msgBlock.BlockHash()
|
|
if daghash.HashToBig(&hash).Cmp(targetDifficulty) <= 0 {
|
|
break
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func mineLoop(clients []*rpcclient.Client) error {
|
|
clientsCount := int64(len(clients))
|
|
|
|
for atomic.LoadInt32(&isRunning) == 1 {
|
|
var currentClient *rpcclient.Client
|
|
if clientsCount == 1 {
|
|
currentClient = clients[0]
|
|
} else {
|
|
currentClient = clients[random.Int63n(clientsCount)]
|
|
}
|
|
log.Printf("Next block will be mined by: %s", currentClient.Host())
|
|
|
|
template, err := currentClient.GetBlockTemplate([]string{"coinbasetxn"})
|
|
if err != nil {
|
|
return fmt.Errorf("Error getting block template: %s", err)
|
|
}
|
|
|
|
block, err := parseBlock(template)
|
|
if err != nil {
|
|
return fmt.Errorf("Error parsing block: %s", err)
|
|
}
|
|
|
|
msgBlock := block.MsgBlock()
|
|
|
|
msgBlock.Header.HashMerkleRoot = *blockdag.BuildHashMerkleTreeStore(block.Transactions()).Root()
|
|
msgBlock.Header.IDMerkleRoot = *blockdag.BuildIDMerkleTreeStore(block.Transactions()).Root()
|
|
|
|
solveBlock(msgBlock)
|
|
|
|
log.Printf("Found block %s! Submitting", block.Hash())
|
|
|
|
err = currentClient.SubmitBlock(block, &btcjson.SubmitBlockOptions{})
|
|
if err != nil {
|
|
return fmt.Errorf("Error submitting block: %s", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|