Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG:block hash in confusion #590

Merged
merged 1 commit into from
Dec 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions core/blockchain/blockchain_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package blockchain

import (
"github.com/Qitmeer/qng/params"
"testing"
)

func TestBlockClone(t *testing.T) {
block := params.PrivNetParam.GenesisBlock
cloneBlock, err := block.Block().Clone()
if err != nil {
t.Fatal(err)
}
cbHash := cloneBlock.BlockHash()
if !block.Hash().IsEqual(&cbHash) {
t.Fatalf("block hash:%s != %s (expect)", cbHash.String(), block.Hash().String())
}
}
17 changes: 17 additions & 0 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,23 @@ func (b *Block) AddParent(h *hash.Hash) error {

}

// Deep copy
func (b *Block) Clone() (*Block, error) {
var w bytes.Buffer
w.Grow(b.SerializeSize())
err := b.Serialize(&w)
if err != nil {
return nil, err
}
r := bytes.NewReader(w.Bytes())
var block Block
err = block.Deserialize(r)
if err != nil {
return nil, err
}
return &block, nil
}

// SerializedBlock provides easier and more efficient manipulation of raw blocks.
// It also memorizes hashes for the block and its transactions on their first
// access so subsequent accesses don't have to repeat the relatively expensive
Expand Down
25 changes: 15 additions & 10 deletions services/miner/cpuworker.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,9 @@ out:
if w.discrete && w.discreteNum <= 0 {
continue
}
if w.solveBlock() {
block := types.NewBlock(w.miner.template.Block)
sb := w.solveBlock()
if sb != nil {
block := types.NewBlock(sb)
info, err := w.miner.submitBlock(block)
if err != nil {
log.Error(fmt.Sprintf("Failed to submit new block:%s ,%v", block.Hash().String(), err))
Expand Down Expand Up @@ -352,17 +353,21 @@ func (w *CPUWorker) cleanDiscrete() {
}
}

func (w *CPUWorker) solveBlock() bool {
func (w *CPUWorker) solveBlock() *types.Block {
if w.miner.template == nil {
return false
return nil
}
// Start a ticker which is used to signal checks for stale work and
// updates to the speed monitor.
ticker := time.NewTicker(333 * time.Millisecond)
defer ticker.Stop()

// Create a couple of convenience variables.
block := w.miner.template.Block
block, err := w.miner.template.Block.Clone()
if err != nil {
log.Error(err.Error())
return nil
}
header := &block.Header

// Initial state.
Expand Down Expand Up @@ -390,7 +395,7 @@ func (w *CPUWorker) solveBlock() bool {
for i := uint64(0); i <= maxNonce; i++ {
select {
case <-w.quit:
return false
return nil

case <-ticker.C:
w.updateHashes <- hashesCompleted
Expand All @@ -401,13 +406,13 @@ func (w *CPUWorker) solveBlock() bool {
// generated and it has been at least 3 seconds,
// or if it's been one minute.
if w.hasNewWork || roughtime.Now().After(lastGenerated.Add(gbtRegenerateSeconds*time.Second)) {
return false
return nil
}

err := mining.UpdateBlockTime(block, w.miner.BlockChain(), w.miner.timeSource, params.ActiveNetParams.Params)
if err != nil {
log.Warn(fmt.Sprintf("CPU miner unable to update block template time: %v", err))
return false
return nil
}

default:
Expand All @@ -421,11 +426,11 @@ func (w *CPUWorker) solveBlock() bool {
header.Pow = instance
if header.Pow.FindSolver(header.BlockData(), header.BlockHash(), header.Difficulty) {
w.updateHashes <- hashesCompleted
return true
return block
}
// Each hash is actually a double hash (tow hashes), so
}
return false
return nil
}

func NewCPUWorker(miner *Miner) *CPUWorker {
Expand Down
24 changes: 13 additions & 11 deletions services/miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -654,32 +654,34 @@ func (m *Miner) submitBlockHeader(header *types.BlockHeader, extraNonce uint64)
if !m.IsEnable() || m.template == nil {
return nil, fmt.Errorf("You must enable miner by --miner.")
}
tHeader := &m.template.Block.Header
if !IsEqualForMiner(tHeader, header) {
if !IsEqualForMiner(&m.template.Block.Header, header) {
return nil, fmt.Errorf("You're overdue")
}
block, err := m.template.Block.Clone()
if err != nil {
return nil, err
}
if extraNonce <= 0 {
if !tHeader.TxRoot.IsEqual(&header.TxRoot) {
if !block.Header.TxRoot.IsEqual(&header.TxRoot) {
return nil, fmt.Errorf("You're overdue about tx root.")
}
} else {
ctx := types.NewTx(m.template.Block.Transactions[0]).Tx
ctx := types.NewTx(block.Transactions[0]).Tx
txRoot, err := mining.DoCalculateTransactionsRoot(ctx, m.template.TxMerklePath, m.template.TxWitnessRoot, extraNonce)
if err != nil {
return nil, err
}
if !txRoot.IsEqual(&header.TxRoot) {
return nil, fmt.Errorf("You're overdue about tx root.")
}
tHeader.TxRoot = header.TxRoot
m.template.Block.Transactions[0] = ctx
block.Header.TxRoot = header.TxRoot
block.Transactions[0] = ctx
}

tHeader.Difficulty = header.Difficulty
tHeader.Timestamp = header.Timestamp
tHeader.Pow = header.Pow
block := types.NewBlock(m.template.Block)
return m.submitBlock(block)
block.Header.Difficulty = header.Difficulty
block.Header.Timestamp = header.Timestamp
block.Header.Pow = header.Pow
return m.submitBlock(types.NewBlock(block))
}

func (m *Miner) CanMining() error {
Expand Down
Loading