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

quaiclient - Fix testHeader #1297

Closed
wants to merge 10 commits into from
3 changes: 2 additions & 1 deletion consensus/progpow/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,8 @@ func (progpow *Progpow) verifySeal(header *types.Header) (common.Hash, error) {
if progpow.fakeFail == header.Number().Uint64() {
return common.Hash{}, errInvalidPoW
}
return common.Hash{}, nil
//if hash is empty here, it fails because of div / 0 on poem.go: IntrinsicLogS()
return common.HexToHash("0xf5d8c9fb1a61e47c6dd4b5d0a1a0d6c0f7bce9cfae0e2a9d8a9c8d6d6f8f4f7"), nil
}
// If we're running a shared PoW, delegate verification to it
if progpow.shared != nil {
Expand Down
23 changes: 13 additions & 10 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ import (
"github.com/dominant-strategies/go-quai/common"
"github.com/dominant-strategies/go-quai/consensus"
"github.com/dominant-strategies/go-quai/consensus/misc"
"github.com/dominant-strategies/go-quai/core/rawdb"
"github.com/dominant-strategies/go-quai/core/state"
"github.com/dominant-strategies/go-quai/core/types"
"github.com/dominant-strategies/go-quai/core/vm"
"github.com/dominant-strategies/go-quai/ethdb"
"github.com/dominant-strategies/go-quai/params"
"github.com/dominant-strategies/go-quai/trie"
)

// BlockGen creates blocks for testing.
Expand Down Expand Up @@ -215,7 +217,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
chainreader := &fakeChainReader{config: config}
genblock := func(i int, parent *types.Block, statedb *state.StateDB) (*types.Block, types.Receipts) {
b := &BlockGen{i: i, chain: blocks, parent: parent, statedb: statedb, config: config, engine: engine}
b.header = makeHeader(chainreader, parent, statedb, b.engine)
b.header = makeHeader(chainreader, parent, statedb, b.engine, config.GenesisHash)

// Execute any user modifications to the block
if gen != nil {
Expand Down Expand Up @@ -243,38 +245,39 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
panic(err)
}
block, receipt := genblock(i, parent, statedb)
rawdb.WriteBlock(db, block)
blocks[i] = block
receipts[i] = receipt
parent = block
}
return blocks, receipts
}

func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header {
func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.StateDB, engine consensus.Engine, genesisHash common.Hash) *types.Header {
var time uint64
if parent.Time() == 0 {
time = 10
} else {
time = parent.Time() + 10 // block time is fixed at 10 seconds
}

// Temporary header values just to calc difficulty
diffheader := types.EmptyHeader()
diffheader.SetDifficulty(parent.Difficulty())
diffheader.SetNumber(parent.Number())
diffheader.SetTime(time - 10)
diffheader.SetUncleHash(parent.UncleHash())

// Make new header
header := types.EmptyHeader()
header.SetRoot(state.IntermediateRoot(true))
header.SetParentHash(parent.Hash())
header.SetCoinbase(parent.Coinbase())
header.SetDifficulty(engine.CalcDifficulty(chain, diffheader))
header.SetDifficulty(engine.CalcDifficulty(chain, parent.Header()))
header.SetGasLimit(parent.GasLimit())
header.SetNumber(new(big.Int).Add(parent.Number(), common.Big1))
header.SetTime(time)
header.SetBaseFee(misc.CalcBaseFee(chain.Config(), parent.Header()))

//new array receive its first value as genesisHash
manifest := types.BlockManifest{genesisHash}
header.SetManifestHash(types.DeriveSha(manifest, trie.NewStackTrie(nil)))

header.SetLocation(common.Location{0,0})

return header
}

Expand Down
30 changes: 29 additions & 1 deletion core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,35 @@ func NewCore(db ethdb.Database, config *Config, isLocalBlock func(block *types.H
// Initialize the sync target to current header parent entropy
c.syncTarget = c.CurrentHeader()

c.AppendQueueProcessCache()

return c, nil
}

// Used on unit testing
func NewFakeCore(db ethdb.Database, config *Config, isLocalBlock func(block *types.Header) bool, txConfig *TxPoolConfig, txLookupLimit *uint64, chainConfig *params.ChainConfig, slicesRunning []common.Location, domClientUrl string, subClientUrls []string, engine consensus.Engine, cacheConfig *CacheConfig, vmConfig vm.Config, genesis *Genesis) (*Core, error) {
slice, err := NewFakeSlice(db, config, txConfig, txLookupLimit, isLocalBlock, chainConfig, slicesRunning, domClientUrl, subClientUrls, engine, cacheConfig, vmConfig, genesis)
if err != nil {
return nil, err
}

c := &Core{
sl: slice,
engine: engine,
quit: make(chan struct{}),
procCounter: 0,
normalListBackoff: 1,
}

// Initialize the sync target to current header parent entropy
c.syncTarget = c.CurrentHeader()

c.AppendQueueProcessCache()

return c, nil
}

func (c *Core) AppendQueueProcessCache() {
appendQueue, _ := lru.New(c_maxAppendQueue)
c.appendQueue = appendQueue

Expand All @@ -107,7 +136,6 @@ func NewCore(db ethdb.Database, config *Config, isLocalBlock func(block *types.H
go c.updateAppendQueue()
go c.startStatsTimer()
go c.checkSyncTarget()
return c, nil
}

// InsertChain attempts to append a list of blocks to the slice, optionally
Expand Down
56 changes: 55 additions & 1 deletion core/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,61 @@ func NewSlice(db ethdb.Database, config *Config, txConfig *TxPoolConfig, txLooku
if nodeCtx != common.PRIME_CTX {
go func() {
sl.domClient = makeDomClient(domClientUrl)
}()
}()
}

if err := sl.init(genesis); err != nil {
return nil, err
}

sl.CheckForBadHashAndRecover()

if nodeCtx == common.ZONE_CTX && sl.ProcessingState() {
go sl.asyncPendingHeaderLoop()
}

return sl, nil
}

func NewFakeSlice(db ethdb.Database, config *Config, txConfig *TxPoolConfig, txLookupLimit *uint64, isLocalBlock func(block *types.Header) bool, chainConfig *params.ChainConfig, slicesRunning []common.Location, domClientUrl string, subClientUrls []string, engine consensus.Engine, cacheConfig *CacheConfig, vmConfig vm.Config, genesis *Genesis) (*Slice, error) {
nodeCtx := common.NodeLocation.Context()
sl := &Slice{
config: chainConfig,
engine: engine,
sliceDb: db,
quit: make(chan struct{}),
badHashesCache: make(map[common.Hash]bool),
}

var err error
sl.hc, err = NewHeaderChain(db, engine, sl.GetPEtxRollupAfterRetryThreshold, sl.GetPEtxAfterRetryThreshold, chainConfig, cacheConfig, txLookupLimit, vmConfig, slicesRunning)
if err != nil {
return nil, err
}

sl.validator = NewBlockValidator(chainConfig, sl.hc, engine)

// tx pool is only used in zone
if nodeCtx == common.ZONE_CTX && sl.ProcessingState() {
sl.txPool = NewTxPool(*txConfig, chainConfig, sl.hc)
sl.hc.pool = sl.txPool
}

sl.miner = New(sl.hc, sl.txPool, config, db, chainConfig, engine, isLocalBlock, sl.ProcessingState())

sl.phCache, _ = lru.New(c_phCacheSize)

// only set the subClients if the chain is not Zone
sl.subClients = make([]*quaiclient.Client, 3)
if nodeCtx != common.ZONE_CTX {
sl.subClients = makeSubClients(subClientUrls)
}

// only set domClient if the chain is not Prime.
if nodeCtx != common.PRIME_CTX {
go func () {
sl.domClient = quaiclient.NewClient(&quaiclient.TestRpcClient{})
}()
}

if err := sl.init(genesis); err != nil {
Expand Down
59 changes: 59 additions & 0 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,65 @@ type Header struct {
PowDigest atomic.Value
}

func (h1 *Header) Compare(h2 *Header) error{
if h1 == nil || h2 == nil {
if h1 == h2{
return nil
}
return fmt.Errorf("Headers are not equal expected %v, got %v", h1, h2)
}

fields := map[string][]interface{}{
"parentHash": {h1.parentHash, h2.parentHash},
"uncleHash": {h1.uncleHash, h2.uncleHash},
"coinbase": {h1.coinbase, h2.coinbase},
"root": {h1.root, h2.root},
"txHash": {h1.txHash, h2.txHash},
"etxHash": {h1.etxHash, h2.etxHash},
"etxRollupHash": {h1.etxRollupHash, h2.etxRollupHash},
"manifestHash": {h1.manifestHash, h2.manifestHash},
"receiptHash": {h1.receiptHash, h2.receiptHash},
"difficulty": {h1.difficulty, h2.difficulty},
"number": {h1.number, h2.number},
"gasLimit": {h1.gasLimit, h2.gasLimit},
"gasUsed": {h1.gasUsed, h2.gasUsed},
"baseFee": {h1.baseFee, h2.baseFee},
"location": {h1.location, h2.location},
"time": {h1.time, h2.time},
"extra": {h1.extra, h2.extra},
"mixHash": {h1.mixHash, h2.mixHash},
"nonce": {h1.nonce, h2.nonce},
"hash": {h1.hash, h2.hash},
"sealHash": {h1.sealHash, h2.sealHash},
"PowHash": {h1.PowHash, h2.PowHash},
"PowDigest": {h1.PowDigest, h2.PowDigest},
}

for fieldName, values := range fields {
if !reflect.DeepEqual(values[0], values[1]) {
return fmt.Errorf("Field %s is not equal expected %v, got %v", fieldName, values[0], values[1])
}
}

if len(h1.parentEntropy) != len(h2.parentEntropy) {
return fmt.Errorf("Field parentEntropy is not equal expected %v, got %v", h1.parentEntropy, h2.parentEntropy)
}
for i := range h1.parentEntropy {
if h1.parentEntropy[i].Cmp(h2.parentEntropy[i]) != 0 {
return fmt.Errorf("Field parentEntropy at index %d is not equal expected %v, got %v", i, h1.parentEntropy[i], h2.parentEntropy[i])
}
}
if len(h1.parentDeltaS) != len(h2.parentDeltaS) {
return fmt.Errorf("Field parentEntropy is not equal expected %v, got %v", h1.parentEntropy, h2.parentEntropy)
}
for i := range h1.parentDeltaS {
if h1.parentEntropy[i].Cmp(h2.parentDeltaS[i]) != 0 {
return fmt.Errorf("Field parentDeltaS at index %d is not equal expected %v, got %v", i, h1.parentDeltaS[i], h2.parentDeltaS[i])
}
}
return nil
}

// field type overrides for gencodec
type headerMarshaling struct {
Difficulty *hexutil.Big
Expand Down
Loading
Loading