mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
Avoid redundant Block.Header() deep-copy (#3050)
* Add separate Block.Nonce() and Block.NonceU64() * Add Block.Seal() * Avoid redundant Block.Header() deep-copy * Add warning comment for Block.Header()
This commit is contained in:
parent
8104a90993
commit
57d641b6f9
@ -3679,8 +3679,8 @@ func scanReceipts(chaindata string, block uint64) error {
|
||||
fix := true
|
||||
if chainConfig.IsByzantium(blockNum) {
|
||||
receiptSha := types.DeriveSha(receipts1)
|
||||
if receiptSha != block.Header().ReceiptHash {
|
||||
fmt.Printf("(retrace) mismatched receipt headers for block %d: %x, %x\n", block.NumberU64(), receiptSha, block.Header().ReceiptHash)
|
||||
if receiptSha != block.ReceiptHash() {
|
||||
fmt.Printf("(retrace) mismatched receipt headers for block %d: %x, %x\n", block.NumberU64(), receiptSha, block.ReceiptHash())
|
||||
fix = false
|
||||
}
|
||||
}
|
||||
|
@ -303,9 +303,9 @@ func syncBySmallSteps(db kv.RwDB, miningConfig params.MiningConfig, ctx context.
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if miner.MiningConfig.Enabled && nextBlock != nil && nextBlock.Header().Coinbase != (common.Address{}) {
|
||||
miner.MiningConfig.Etherbase = nextBlock.Header().Coinbase
|
||||
miner.MiningConfig.ExtraData = nextBlock.Header().Extra
|
||||
if miner.MiningConfig.Enabled && nextBlock != nil && nextBlock.Coinbase() != (common.Address{}) {
|
||||
miner.MiningConfig.Etherbase = nextBlock.Coinbase()
|
||||
miner.MiningConfig.ExtraData = nextBlock.Extra()
|
||||
miningStages.MockExecFunc(stages.MiningCreateBlock, func(firstCycle bool, badBlockUnwind bool, s *stagedsync.StageState, u stagedsync.Unwinder, tx kv.RwTx) error {
|
||||
err = stagedsync.SpawnMiningCreateBlockStage(s, tx,
|
||||
stagedsync.StageMiningCreateBlockCfg(db, miner, *chainConfig, engine, nil, nil, tmpDir),
|
||||
@ -314,10 +314,10 @@ func syncBySmallSteps(db kv.RwDB, miningConfig params.MiningConfig, ctx context.
|
||||
return err
|
||||
}
|
||||
miner.MiningBlock.Uncles = nextBlock.Uncles()
|
||||
miner.MiningBlock.Header.Time = nextBlock.Header().Time
|
||||
miner.MiningBlock.Header.GasLimit = nextBlock.Header().GasLimit
|
||||
miner.MiningBlock.Header.Difficulty = nextBlock.Header().Difficulty
|
||||
miner.MiningBlock.Header.Nonce = nextBlock.Header().Nonce
|
||||
miner.MiningBlock.Header.Time = nextBlock.Time()
|
||||
miner.MiningBlock.Header.GasLimit = nextBlock.GasLimit()
|
||||
miner.MiningBlock.Header.Difficulty = nextBlock.Difficulty()
|
||||
miner.MiningBlock.Header.Nonce = nextBlock.Nonce()
|
||||
miner.MiningBlock.LocalTxs = types.NewTransactionsFixedOrder(nextBlock.Transactions())
|
||||
miner.MiningBlock.RemoteTxs = types.NewTransactionsFixedOrder(nil)
|
||||
//debugprint.Headers(miningWorld.Block.Header, nextBlock.Header())
|
||||
@ -390,16 +390,15 @@ func checkChanges(expectedAccountChanges map[uint64]*changeset.ChangeSet, tx kv.
|
||||
}
|
||||
|
||||
func checkMinedBlock(b1, b2 *types.Block, chainConfig *params.ChainConfig) {
|
||||
h1 := b1.Header()
|
||||
h2 := b2.Header()
|
||||
if h1.Root != h2.Root ||
|
||||
(chainConfig.IsByzantium(b1.NumberU64()) && h1.ReceiptHash != h2.ReceiptHash) ||
|
||||
h1.TxHash != h2.TxHash ||
|
||||
h1.ParentHash != h2.ParentHash ||
|
||||
h1.UncleHash != h2.UncleHash ||
|
||||
h1.GasUsed != h2.GasUsed ||
|
||||
!bytes.Equal(h1.Extra, h2.Extra) {
|
||||
debugprint.Headers(h1, h2)
|
||||
if b1.Root() != b2.Root() ||
|
||||
(chainConfig.IsByzantium(b1.NumberU64()) && b1.ReceiptHash() != b2.ReceiptHash()) ||
|
||||
b1.TxHash() != b2.TxHash() ||
|
||||
b1.ParentHash() != b2.ParentHash() ||
|
||||
b1.UncleHash() != b2.UncleHash() ||
|
||||
b1.GasUsed() != b2.GasUsed() ||
|
||||
!bytes.Equal(b1.Extra(), b2.Extra()) { // TODO: Extra() doesn't need to be a copy for a read-only compare
|
||||
// Header()'s deep-copy doesn't matter here since it will panic anyway
|
||||
debugprint.Headers(b1.Header(), b2.Header())
|
||||
panic("blocks are not same")
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ func CheckChangeSets(genesis *core.Genesis, logger log.Logger, blockNum uint64,
|
||||
if writeReceipts {
|
||||
if chainConfig.IsByzantium(block.Number().Uint64()) {
|
||||
receiptSha := types.DeriveSha(receipts)
|
||||
if receiptSha != block.Header().ReceiptHash {
|
||||
if receiptSha != block.ReceiptHash() {
|
||||
return fmt.Errorf("mismatched receipt headers for block %d", block.NumberU64())
|
||||
}
|
||||
}
|
||||
|
@ -557,7 +557,7 @@ func OpcodeTracer(genesis *core.Genesis, blockNum uint64, chaindata string, numB
|
||||
}
|
||||
if chainConfig.IsByzantium(block.Number().Uint64()) {
|
||||
receiptSha := types.DeriveSha(receipts)
|
||||
if receiptSha != block.Header().ReceiptHash {
|
||||
if receiptSha != block.ReceiptHash() {
|
||||
return fmt.Errorf("mismatched receipt headers for block %d", block.NumberU64())
|
||||
}
|
||||
}
|
||||
|
@ -293,20 +293,20 @@ func TestStaleSubmission(t *testing.T) {
|
||||
}
|
||||
select {
|
||||
case res := <-results:
|
||||
if res.Header().Nonce != fakeNonce {
|
||||
t.Errorf("case %d block nonce mismatch, want %x, get %x", id+1, fakeNonce, res.Header().Nonce)
|
||||
if res.Nonce() != fakeNonce {
|
||||
t.Errorf("case %d block nonce mismatch, want %x, get %x", id+1, fakeNonce, res.Nonce())
|
||||
}
|
||||
if res.Header().MixDigest != fakeDigest {
|
||||
t.Errorf("case %d block digest mismatch, want %x, get %x", id+1, fakeDigest, res.Header().MixDigest)
|
||||
if res.MixDigest() != fakeDigest {
|
||||
t.Errorf("case %d block digest mismatch, want %x, get %x", id+1, fakeDigest, res.MixDigest())
|
||||
}
|
||||
if res.Header().Difficulty.Uint64() != c.headers[c.submitIndex].Difficulty.Uint64() {
|
||||
t.Errorf("case %d block difficulty mismatch, want %d, get %d", id+1, c.headers[c.submitIndex].Difficulty, res.Header().Difficulty)
|
||||
if res.Difficulty().Uint64() != c.headers[c.submitIndex].Difficulty.Uint64() {
|
||||
t.Errorf("case %d block difficulty mismatch, want %d, get %d", id+1, c.headers[c.submitIndex].Difficulty, res.Difficulty())
|
||||
}
|
||||
if res.Header().Number.Uint64() != c.headers[c.submitIndex].Number.Uint64() {
|
||||
t.Errorf("case %d block number mismatch, want %d, get %d", id+1, c.headers[c.submitIndex].Number.Uint64(), res.Header().Number.Uint64())
|
||||
if res.Number().Uint64() != c.headers[c.submitIndex].Number.Uint64() {
|
||||
t.Errorf("case %d block number mismatch, want %d, get %d", id+1, c.headers[c.submitIndex].Number.Uint64(), res.Number().Uint64())
|
||||
}
|
||||
if res.Header().ParentHash != c.headers[c.submitIndex].ParentHash {
|
||||
t.Errorf("case %d block parent hash mismatch, want %s, get %s", id+1, c.headers[c.submitIndex].ParentHash.Hex(), res.Header().ParentHash.Hex())
|
||||
if res.ParentHash() != c.headers[c.submitIndex].ParentHash {
|
||||
t.Errorf("case %d block parent hash mismatch, want %s, get %s", id+1, c.headers[c.submitIndex].ParentHash.Hex(), res.ParentHash().Hex())
|
||||
}
|
||||
case <-time.NewTimer(time.Second).C:
|
||||
t.Errorf("case %d fetch ethash result timeout", id+1)
|
||||
|
@ -152,7 +152,7 @@ func ExecuteBlockEphemerally(
|
||||
|
||||
if chainConfig.IsByzantium(header.Number.Uint64()) && !vmConfig.NoReceipts {
|
||||
receiptSha := types.DeriveSha(receipts)
|
||||
if receiptSha != block.Header().ReceiptHash {
|
||||
if receiptSha != block.ReceiptHash() {
|
||||
return nil, fmt.Errorf("mismatched receipt headers for block %d", block.NumberU64())
|
||||
}
|
||||
}
|
||||
|
@ -185,12 +185,21 @@ func (b *BlockGen) PrevBlock(index int) *types.Block {
|
||||
// tied to chain length directly.
|
||||
func (b *BlockGen) OffsetTime(seconds int64) {
|
||||
b.header.Time += uint64(seconds)
|
||||
if b.header.Time <= b.parent.Header().Time {
|
||||
parent := b.parent
|
||||
if b.header.Time <= parent.Time() {
|
||||
panic("block time out of range")
|
||||
}
|
||||
chainreader := &FakeChainReader{Cfg: b.config}
|
||||
parent := b.parent.Header()
|
||||
b.header.Difficulty = b.engine.CalcDifficulty(chainreader, b.header.Time, parent.Time, parent.Difficulty, parent.Number.Uint64(), parent.Hash(), parent.UncleHash, parent.Seal)
|
||||
b.header.Difficulty = b.engine.CalcDifficulty(
|
||||
chainreader,
|
||||
b.header.Time,
|
||||
parent.Time(),
|
||||
parent.Difficulty(),
|
||||
parent.NumberU64(),
|
||||
parent.Hash(),
|
||||
parent.UncleHash(),
|
||||
parent.Seal(),
|
||||
)
|
||||
}
|
||||
|
||||
func (b *BlockGen) GetHeader() *types.Header {
|
||||
@ -402,7 +411,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.I
|
||||
parent.Number().Uint64(),
|
||||
parent.Hash(),
|
||||
parent.UncleHash(),
|
||||
parent.Header().Seal,
|
||||
parent.Seal(),
|
||||
),
|
||||
GasLimit: CalcGasLimit(parent.GasUsed(), parent.GasLimit(), parent.GasLimit(), parent.GasLimit()),
|
||||
Number: new(big.Int).Add(parent.Number(), common.Big1),
|
||||
|
@ -154,7 +154,7 @@ func TestBlockStorage(t *testing.T) {
|
||||
}
|
||||
if entry := ReadHeader(tx, block.Hash(), block.NumberU64()); entry == nil {
|
||||
t.Fatalf("Stored header not found")
|
||||
} else if entry.Hash() != block.Header().Hash() {
|
||||
} else if entry.Hash() != block.Hash() {
|
||||
t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, block.Header())
|
||||
}
|
||||
if entry := ReadBodyWithTransactions(tx, block.Hash(), block.NumberU64()); entry == nil {
|
||||
@ -186,8 +186,10 @@ func TestPartialBlockStorage(t *testing.T) {
|
||||
TxHash: types.EmptyRootHash,
|
||||
ReceiptHash: types.EmptyRootHash,
|
||||
})
|
||||
header := block.Header() // Not identical to struct literal above, due to other fields
|
||||
|
||||
// Store a header and check that it's not recognized as a block
|
||||
WriteHeader(tx, block.Header())
|
||||
WriteHeader(tx, header)
|
||||
if entry := ReadBlock(tx, block.Hash(), block.NumberU64()); entry != nil {
|
||||
t.Fatalf("Non existent block returned: %v", entry)
|
||||
}
|
||||
@ -203,7 +205,7 @@ func TestPartialBlockStorage(t *testing.T) {
|
||||
DeleteBody(tx, block.Hash(), block.NumberU64())
|
||||
|
||||
// Store a header and a body separately and check reassembly
|
||||
WriteHeader(tx, block.Header())
|
||||
WriteHeader(tx, header)
|
||||
if err := WriteBody(tx, block.Hash(), block.NumberU64(), block.Body()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -629,6 +629,17 @@ func (h *Header) EmptyReceipts() bool {
|
||||
return h.ReceiptHash == EmptyRootHash
|
||||
}
|
||||
|
||||
func (h *Header) copySeal() []rlp.RawValue {
|
||||
seal := h.Seal
|
||||
if len(seal) > 0 {
|
||||
seal = make([]rlp.RawValue, len(seal))
|
||||
for i, s := range h.Seal {
|
||||
seal[i] = common.CopyBytes(s)
|
||||
}
|
||||
}
|
||||
return seal
|
||||
}
|
||||
|
||||
// Body is a simple (mutable, non-safe) data container for storing and moving
|
||||
// a block's data contents (transactions and uncles) together.
|
||||
type Body struct {
|
||||
@ -1016,12 +1027,7 @@ func CopyHeader(h *Header) *Header {
|
||||
cpy.Extra = make([]byte, len(h.Extra))
|
||||
copy(cpy.Extra, h.Extra)
|
||||
}
|
||||
if len(h.Seal) > 0 {
|
||||
cpy.Seal = make([]rlp.RawValue, len(h.Seal))
|
||||
for i := range h.Seal {
|
||||
cpy.Seal[i] = common.CopyBytes(h.Seal[i])
|
||||
}
|
||||
}
|
||||
cpy.Seal = h.copySeal()
|
||||
return &cpy
|
||||
}
|
||||
|
||||
@ -1203,7 +1209,8 @@ func (b *Block) Time() uint64 { return b.header.Time }
|
||||
|
||||
func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() }
|
||||
func (b *Block) MixDigest() common.Hash { return b.header.MixDigest }
|
||||
func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:]) }
|
||||
func (b *Block) Nonce() BlockNonce { return b.header.Nonce }
|
||||
func (b *Block) NonceU64() uint64 { return b.header.Nonce.Uint64() }
|
||||
func (b *Block) Bloom() Bloom { return b.header.Bloom }
|
||||
func (b *Block) Coinbase() common.Address { return b.header.Coinbase }
|
||||
func (b *Block) Root() common.Hash { return b.header.Root }
|
||||
@ -1218,7 +1225,9 @@ func (b *Block) BaseFee() *big.Int {
|
||||
}
|
||||
return new(big.Int).Set(b.header.BaseFee)
|
||||
}
|
||||
func (b *Block) Seal() (seal []rlp.RawValue) { return b.header.copySeal() }
|
||||
|
||||
// Header returns a deep-copy of the entire block header using CopyHeader()
|
||||
func (b *Block) Header() *Header { return CopyHeader(b.header) }
|
||||
|
||||
// Body returns the non-header content of the block.
|
||||
|
@ -52,7 +52,7 @@ func TestBlockEncoding(t *testing.T) {
|
||||
check("MixDigest", block.MixDigest(), common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498"))
|
||||
check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017"))
|
||||
check("Hash", block.Hash(), common.HexToHash("0a5843ac1cb04865017cb35a57b50b07084e5fcee39b5acadade33149f4fff9e"))
|
||||
check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4))
|
||||
check("Nonce", block.NonceU64(), uint64(0xa13a5a8c8f2bb1c4))
|
||||
check("Time", block.Time(), uint64(1426516743))
|
||||
check("Size", block.Size(), common.StorageSize(len(blockEnc)))
|
||||
|
||||
@ -89,7 +89,7 @@ func TestEIP1559BlockEncoding(t *testing.T) {
|
||||
check("MixDigest", block.MixDigest(), common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498"))
|
||||
check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017"))
|
||||
check("Hash", block.Hash(), common.HexToHash("c7252048cd273fe0dac09650027d07f0e3da4ee0675ebbb26627cea92729c372"))
|
||||
check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4))
|
||||
check("Nonce", block.NonceU64(), uint64(0xa13a5a8c8f2bb1c4))
|
||||
check("Time", block.Time(), uint64(1426516743))
|
||||
check("Size", block.Size(), common.StorageSize(len(blockEnc)))
|
||||
check("BaseFee", block.BaseFee(), new(big.Int).SetUint64(params.InitialBaseFee))
|
||||
@ -154,7 +154,7 @@ func TestEIP2718BlockEncoding(t *testing.T) {
|
||||
check("Coinbase", block.Coinbase(), common.HexToAddress("8888f1f195afa192cfee860698584c030f4c9db1"))
|
||||
check("MixDigest", block.MixDigest(), common.HexToHash("bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff498"))
|
||||
check("Root", block.Root(), common.HexToHash("ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017"))
|
||||
check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4))
|
||||
check("Nonce", block.NonceU64(), uint64(0xa13a5a8c8f2bb1c4))
|
||||
check("Time", block.Time(), uint64(1426516743))
|
||||
check("Size", block.Size(), common.StorageSize(len(blockEnc)))
|
||||
|
||||
|
@ -55,7 +55,7 @@ func SpawnMiningFinishStage(s *StageState, tx kv.RwTx, cfg MiningFinishCfg, quit
|
||||
//prev = sealHash
|
||||
|
||||
// Tests may set pre-calculated nonce
|
||||
if block.Header().Nonce.Uint64() != 0 {
|
||||
if block.NonceU64() != 0 {
|
||||
cfg.miningState.MiningResultCh <- block
|
||||
return nil
|
||||
}
|
||||
|
@ -123,8 +123,8 @@ var ReceiptRepair = Migration{
|
||||
fix := true
|
||||
if chainConfig.IsByzantium(block.Number().Uint64()) {
|
||||
receiptSha := types.DeriveSha(receipts1)
|
||||
if receiptSha != block.Header().ReceiptHash {
|
||||
fmt.Printf("(retrace) mismatched receipt headers for block %d: %x, %x\n", block.NumberU64(), receiptSha, block.Header().ReceiptHash)
|
||||
if receiptSha != block.ReceiptHash() {
|
||||
fmt.Printf("(retrace) mismatched receipt headers for block %d: %x, %x\n", block.NumberU64(), receiptSha, block.ReceiptHash())
|
||||
fix = false
|
||||
}
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ func (t *BlockTest) validateImportedHeaders(tx kv.Tx, validBlocks []btBlock) err
|
||||
if err := validateHeader(bmap[b.Hash()].BlockHeader, b.Header()); err != nil {
|
||||
return fmt.Errorf("imported block header validation failed: %w", err)
|
||||
}
|
||||
b, _ = rawdb.ReadBlockByHash(tx, b.Header().ParentHash)
|
||||
b, _ = rawdb.ReadBlockByHash(tx, b.ParentHash())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -1024,11 +1024,12 @@ func (hd *HeaderDownload) Fetching() bool {
|
||||
}
|
||||
|
||||
func (hd *HeaderDownload) AddMinedBlock(block *types.Block) error {
|
||||
header := block.Header()
|
||||
buf := bytes.NewBuffer(nil)
|
||||
if err := block.Header().EncodeRLP(buf); err != nil {
|
||||
if err := header.EncodeRLP(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
segments, _, err := hd.SingleHeaderAsSegment(buf.Bytes(), block.Header())
|
||||
segments, _, err := hd.SingleHeaderAsSegment(buf.Bytes(), header)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ func ComputeTxEnv(ctx context.Context, block *types.Block, cfg *params.ChainConf
|
||||
statedb.Prepare(tx.Hash(), blockHash, idx)
|
||||
|
||||
// Assemble the transaction call message and return if the requested offset
|
||||
msg, _ := tx.AsMessage(*signer, block.Header().BaseFee)
|
||||
msg, _ := tx.AsMessage(*signer, block.BaseFee())
|
||||
TxContext := core.NewEVMTxContext(msg)
|
||||
if idx == int(txIndex) {
|
||||
return msg, BlockContext, TxContext, statedb, reader, nil
|
||||
|
Loading…
Reference in New Issue
Block a user