Skip to content

Commit

Permalink
Merge pull request #590 from lochjin/dev1.2
Browse files Browse the repository at this point in the history
BUG:block hash in confusion
  • Loading branch information
dindinw authored Dec 25, 2023
2 parents 1909023 + 25abaa7 commit 69fa64f
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 21 deletions.
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

0 comments on commit 69fa64f

Please sign in to comment.