From 3f4efa9310ab8eaf99e295ae5d4430cf29b21479 Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Fri, 27 Feb 2026 02:13:11 +0200 Subject: [PATCH 1/2] update BlockChainHook to use last executed block header --- process/smartContract/hooks/blockChainHook.go | 84 +++++++++-------- .../hooks/blockChainHook_test.go | 92 +++++++++++-------- 2 files changed, 99 insertions(+), 77 deletions(-) diff --git a/process/smartContract/hooks/blockChainHook.go b/process/smartContract/hooks/blockChainHook.go index f647cb272b2..9b15e636625 100644 --- a/process/smartContract/hooks/blockChainHook.go +++ b/process/smartContract/hooks/blockChainHook.go @@ -19,6 +19,10 @@ import ( "github.com/multiversx/mx-chain-core-go/data/typeConverters" "github.com/multiversx/mx-chain-core-go/hashing/keccak" "github.com/multiversx/mx-chain-core-go/marshal" + logger "github.com/multiversx/mx-chain-logger-go" + vmcommon "github.com/multiversx/mx-chain-vm-common-go" + "github.com/multiversx/mx-chain-vm-common-go/parsers" + "github.com/multiversx/mx-chain-go/common" "github.com/multiversx/mx-chain-go/config" "github.com/multiversx/mx-chain-go/dataRetriever" @@ -30,9 +34,6 @@ import ( "github.com/multiversx/mx-chain-go/storage" "github.com/multiversx/mx-chain-go/storage/factory" "github.com/multiversx/mx-chain-go/storage/storageunit" - logger "github.com/multiversx/mx-chain-logger-go" - vmcommon "github.com/multiversx/mx-chain-vm-common-go" - "github.com/multiversx/mx-chain-vm-common-go/parsers" ) var _ process.BlockChainHookHandler = (*BlockChainHookImpl)(nil) @@ -338,16 +339,17 @@ func (bh *BlockChainHookImpl) processMaxReadsCounters() error { func (bh *BlockChainHookImpl) GetBlockhash(nonce uint64) ([]byte, error) { defer stopMeasure(startMeasure("GetBlockhash")) - hdr := bh.blockChain.GetCurrentBlockHeader() - - if check.IfNil(hdr) { + lastExecHdr := bh.blockChain.GetLastExecutedBlockHeader() + if check.IfNil(lastExecHdr) { return nil, process.ErrNilBlockHeader } - if nonce > hdr.GetNonce() { + + _, lastExecHash, _ := bh.blockChain.GetLastExecutedBlockInfo() + if nonce > lastExecHdr.GetNonce() { return nil, process.ErrInvalidNonceRequest } - if nonce == hdr.GetNonce() { - return bh.blockChain.GetCurrentBlockHeaderHash(), nil + if nonce == lastExecHdr.GetNonce() { + return lastExecHash, nil } if bh.enableEpochsHandler.IsFlagEnabled(common.DoNotReturnOldBlockInBlockchainHookFlag) { return nil, process.ErrInvalidNonceRequest @@ -364,62 +366,73 @@ func (bh *BlockChainHookImpl) GetBlockhash(nonce uint64) ([]byte, error) { return nil, err } - if header.GetEpoch() != hdr.GetEpoch() { + if header.GetEpoch() != lastExecHdr.GetEpoch() { return nil, process.ErrInvalidBlockRequestOldEpoch } return hash, nil } -// LastNonce returns the nonce from the last committed block +// LastNonce returns the nonce from the last executed block func (bh *BlockChainHookImpl) LastNonce() uint64 { - if !check.IfNil(bh.blockChain.GetCurrentBlockHeader()) { - return bh.blockChain.GetCurrentBlockHeader().GetNonce() + lastExecHdr := bh.blockChain.GetLastExecutedBlockHeader() + if check.IfNil(lastExecHdr) { + return 0 } - return 0 + + return lastExecHdr.GetNonce() } -// LastRound returns the round from the last committed block +// LastRound returns the round from the last executed block func (bh *BlockChainHookImpl) LastRound() uint64 { - if !check.IfNil(bh.blockChain.GetCurrentBlockHeader()) { - return bh.blockChain.GetCurrentBlockHeader().GetRound() + lastExecHdr := bh.blockChain.GetLastExecutedBlockHeader() + if check.IfNil(lastExecHdr) { + return 0 } - return 0 + + return lastExecHdr.GetRound() } -// LastTimeStamp returns the timeStamp from the last committed block +// LastTimeStamp returns the timeStamp from the last executed block func (bh *BlockChainHookImpl) LastTimeStamp() uint64 { - if !check.IfNil(bh.blockChain.GetCurrentBlockHeader()) { - return bh.blockChain.GetCurrentBlockHeader().GetTimeStamp() + lastExecHdr := bh.blockChain.GetLastExecutedBlockHeader() + if check.IfNil(lastExecHdr) { + return 0 } - return 0 + + return lastExecHdr.GetTimeStamp() } -// LastTimeStampMs returns the timeStamp in milliseconds from the last committed block +// LastTimeStampMs returns the timeStamp in milliseconds from the last executed block func (bh *BlockChainHookImpl) LastTimeStampMs() uint64 { - if check.IfNil(bh.blockChain.GetCurrentBlockHeader()) { + lastExecHdr := bh.blockChain.GetLastExecutedBlockHeader() + if check.IfNil(lastExecHdr) { return 0 } - _, timestampMs, _ := common.GetHeaderTimestamps(bh.blockChain.GetCurrentBlockHeader(), bh.enableEpochsHandler) + _, timestampMs, _ := common.GetHeaderTimestamps(lastExecHdr, bh.enableEpochsHandler) return timestampMs } -// LastRandomSeed returns the random seed from the last committed block +// LastRandomSeed returns the random seed from the last executed block func (bh *BlockChainHookImpl) LastRandomSeed() []byte { - if !check.IfNil(bh.blockChain.GetCurrentBlockHeader()) { - return bh.blockChain.GetCurrentBlockHeader().GetRandSeed() + lastExecHdr := bh.blockChain.GetLastExecutedBlockHeader() + if check.IfNil(lastExecHdr) { + return make([]byte, 0) } - return make([]byte, 0) + + return lastExecHdr.GetRandSeed() } -// LastEpoch returns the epoch from the last committed block +// LastEpoch returns the epoch from the last executed block func (bh *BlockChainHookImpl) LastEpoch() uint32 { - if !check.IfNil(bh.blockChain.GetCurrentBlockHeader()) { - return bh.blockChain.GetCurrentBlockHeader().GetEpoch() + lastExecHdr := bh.blockChain.GetLastExecutedBlockHeader() + if check.IfNil(lastExecHdr) { + return 0 } - return 0 + + return lastExecHdr.GetEpoch() } // RoundTime returns the duration of a round @@ -466,11 +479,6 @@ func (bh *BlockChainHookImpl) GetStateRootHash() []byte { } func (bh *BlockChainHookImpl) getCurrentRootHash() []byte { - currentHeader := bh.blockChain.GetCurrentBlockHeader() - if currentHeader != nil && !currentHeader.IsHeaderV3() { - return bh.blockChain.GetCurrentBlockRootHash() - } - _, _, lastExecutedRootHash := bh.blockChain.GetLastExecutedBlockInfo() return lastExecutedRootHash } diff --git a/process/smartContract/hooks/blockChainHook_test.go b/process/smartContract/hooks/blockChainHook_test.go index 420d565cb4b..803b816182d 100644 --- a/process/smartContract/hooks/blockChainHook_test.go +++ b/process/smartContract/hooks/blockChainHook_test.go @@ -727,7 +727,7 @@ func TestBlockChainHookImpl_GetBlockhashNilBlockHeaderExpectError(t *testing.T) args := createMockBlockChainHookArgs() args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { return nil }, } @@ -741,10 +741,14 @@ func TestBlockChainHookImpl_GetBlockhashNilBlockHeaderExpectError(t *testing.T) func TestBlockChainHookImpl_GetBlockhashInvalidNonceExpectError(t *testing.T) { t.Parallel() + lastExecHdr := &block.Header{Nonce: 1} args := createMockBlockChainHookArgs() args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{Nonce: 1} + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { + return lastExecHdr + }, + GetLastExecutedBlockInfoCalled: func() (uint64, []byte, []byte) { + return 1, []byte("hash"), []byte("rootHash") }, } @@ -757,15 +761,15 @@ func TestBlockChainHookImpl_GetBlockhashInvalidNonceExpectError(t *testing.T) { func TestBlockChainHookImpl_GetBlockhashShouldReturnCurrentBlockHeaderHash(t *testing.T) { t.Parallel() - hdrToRet := &block.Header{Nonce: 2} + lastExecHdr := &block.Header{Nonce: 2} hashToRet := []byte("hash") args := createMockBlockChainHookArgs() args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return hdrToRet + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { + return lastExecHdr }, - GetCurrentBlockHeaderHashCalled: func() []byte { - return hashToRet + GetLastExecutedBlockInfoCalled: func() (uint64, []byte, []byte) { + return 2, hashToRet, []byte("rootHash") }, } bh, _ := hooks.NewBlockChainHookImpl(args) @@ -778,10 +782,14 @@ func TestBlockChainHookImpl_GetBlockhashShouldReturnCurrentBlockHeaderHash(t *te func TestBlockChainHookImpl_GetBlockhashFromStorerErrorReadingFromStorage(t *testing.T) { t.Parallel() + lastExecHdr := &block.Header{Nonce: 10} args := createMockBlockChainHookArgs() args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{Nonce: 10} + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { + return lastExecHdr + }, + GetLastExecutedBlockInfoCalled: func() (uint64, []byte, []byte) { + return 10, []byte("hash"), []byte("rootHash") }, } storer := &storageStubs.StorerStub{ @@ -813,9 +821,12 @@ func TestBlockChainHookImpl_GetBlockhashFromStorerInSameEpoch(t *testing.T) { marshalledHeader, _ := args.Marshalizer.Marshal(header) args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { return header }, + GetLastExecutedBlockInfoCalled: func() (uint64, []byte, []byte) { + return nonce, []byte("execHash"), []byte("rootHash") + }, } storerBlockHeader := &storageStubs.StorerStub{ @@ -860,9 +871,12 @@ func TestBlockChainHookImpl_GetBlockhashFromStorerInSameEpochWithFlagEnabled(t * shardID := args.ShardCoordinator.SelfId() args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { return header }, + GetLastExecutedBlockInfoCalled: func() (uint64, []byte, []byte) { + return nonce, []byte("hash"), []byte("rootHash") + }, } storerBlockHeader := &storageStubs.StorerStub{ @@ -902,13 +916,17 @@ func TestBlockChainHookImpl_GetBlockhashFromOldEpochExpectError(t *testing.T) { hdrToRet := &block.Header{Nonce: 2, Epoch: 2} hashToRet := []byte("hash") + lastExecHdr := &block.Header{Nonce: 10, Epoch: 10} args := createMockBlockChainHookArgs() marshaledData, _ := args.Marshalizer.Marshal(hdrToRet) args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return &block.Header{Nonce: 10, Epoch: 10} + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { + return lastExecHdr + }, + GetLastExecutedBlockInfoCalled: func() (uint64, []byte, []byte) { + return 10, []byte("execHash"), []byte("rootHash") }, } args.StorageService = &storageStubs.ChainStorerStub{ @@ -942,7 +960,7 @@ func TestBlockChainHookImpl_GettersFromBlockchainCurrentHeader(t *testing.T) { args := createMockBlockChainHookArgs() args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { return nil }, } @@ -965,7 +983,7 @@ func TestBlockChainHookImpl_GettersFromBlockchainCurrentHeader(t *testing.T) { randSeed := []byte("a") rootHash := []byte("b") epoch := uint32(7) - hdrToRet := &block.Header{ + lastExecutedHdr := &block.Header{ Nonce: nonce, Round: round, TimeStamp: timestamp, @@ -976,11 +994,11 @@ func TestBlockChainHookImpl_GettersFromBlockchainCurrentHeader(t *testing.T) { args := createMockBlockChainHookArgs() args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return hdrToRet + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { + return lastExecutedHdr }, - GetCurrentBlockRootHashCalled: func() []byte { - return hdrToRet.RootHash + GetLastExecutedBlockInfoCalled: func() (uint64, []byte, []byte) { + return nonce, []byte("hash"), rootHash }, } bh, _ := hooks.NewBlockChainHookImpl(args) @@ -1002,7 +1020,7 @@ func TestBlockChainHookImpl_GettersFromBlockchainCurrentHeader(t *testing.T) { randSeed := []byte("a") rootHash := []byte("b") epoch := uint32(7) - hdrToRet := &block.Header{ + lastExecutedHdr := &block.Header{ Nonce: nonce, Round: round, TimeStamp: timestamp, @@ -1014,11 +1032,11 @@ func TestBlockChainHookImpl_GettersFromBlockchainCurrentHeader(t *testing.T) { args := createMockBlockChainHookArgs() args.EnableEpochsHandler = enableEpochsHandlerMock.NewEnableEpochsHandlerStub(common.DoNotReturnOldBlockInBlockchainHookFlag) args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return hdrToRet + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { + return lastExecutedHdr }, - GetCurrentBlockRootHashCalled: func() []byte { - return hdrToRet.RootHash + GetLastExecutedBlockInfoCalled: func() (uint64, []byte, []byte) { + return nonce, []byte("hash"), rootHash }, } bh, _ := hooks.NewBlockChainHookImpl(args) @@ -1038,11 +1056,10 @@ func TestBlockChainHookImpl_GettersFromBlockchainCurrentHeader(t *testing.T) { round := uint64(5) timestamp := uint64(1234) randSeed := []byte("a") - rootHash := []byte("b") rootHash1 := []byte("c") epoch := uint32(7) - hdrToRet := &block.HeaderV3{ + lastExecutedHdr := &block.HeaderV3{ Nonce: nonce, Round: round, TimestampMs: timestamp, @@ -1052,14 +1069,11 @@ func TestBlockChainHookImpl_GettersFromBlockchainCurrentHeader(t *testing.T) { args := createMockBlockChainHookArgs() args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return hdrToRet - }, - GetCurrentBlockRootHashCalled: func() []byte { - return rootHash + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { + return lastExecutedHdr }, GetLastExecutedBlockInfoCalled: func() (uint64, []byte, []byte) { - return 0, []byte(""), rootHash1 + return nonce, []byte("hash"), rootHash1 }, } bh, _ := hooks.NewBlockChainHookImpl(args) @@ -2775,14 +2789,14 @@ func TestBlockChainHookImpl_LastTimeStampMs(t *testing.T) { timestamp := uint64(1234) - hdr := &block.Header{ + lastExecHdr := &block.Header{ TimeStamp: timestamp, } args := createMockBlockChainHookArgs() args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return hdr + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { + return lastExecHdr }, } args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ @@ -2803,14 +2817,14 @@ func TestBlockChainHookImpl_LastTimeStampMs(t *testing.T) { t.Parallel() timestampMs := uint64(1234567) - hdr := &block.Header{ + lastExecHdr := &block.Header{ TimeStamp: timestampMs, } args := createMockBlockChainHookArgs() args.BlockChain = &testscommon.ChainHandlerStub{ - GetCurrentBlockHeaderCalled: func() data.HeaderHandler { - return hdr + GetLastExecutedBlockHeaderCalled: func() data.HeaderHandler { + return lastExecHdr }, } args.EnableEpochsHandler = &enableEpochsHandlerMock.EnableEpochsHandlerStub{ From 18199b3c103bf489041e33aa93a08939e874266d Mon Sep 17 00:00:00 2001 From: Adrian Dobrita Date: Fri, 27 Feb 2026 12:28:12 +0200 Subject: [PATCH 2/2] fixes --- process/smartContract/hooks/blockChainHook.go | 3 +-- process/sync/baseSync.go | 16 ---------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/process/smartContract/hooks/blockChainHook.go b/process/smartContract/hooks/blockChainHook.go index 9b15e636625..3f581d2f320 100644 --- a/process/smartContract/hooks/blockChainHook.go +++ b/process/smartContract/hooks/blockChainHook.go @@ -343,12 +343,11 @@ func (bh *BlockChainHookImpl) GetBlockhash(nonce uint64) ([]byte, error) { if check.IfNil(lastExecHdr) { return nil, process.ErrNilBlockHeader } - - _, lastExecHash, _ := bh.blockChain.GetLastExecutedBlockInfo() if nonce > lastExecHdr.GetNonce() { return nil, process.ErrInvalidNonceRequest } if nonce == lastExecHdr.GetNonce() { + _, lastExecHash, _ := bh.blockChain.GetLastExecutedBlockInfo() return lastExecHash, nil } if bh.enableEpochsHandler.IsFlagEnabled(common.DoNotReturnOldBlockInBlockchainHookFlag) { diff --git a/process/sync/baseSync.go b/process/sync/baseSync.go index 8d2234b8ebb..b0f8e9eccb0 100644 --- a/process/sync/baseSync.go +++ b/process/sync/baseSync.go @@ -1964,22 +1964,6 @@ func (boot *baseBootstrap) getHeaderFromPool(hash []byte) (data.HeaderHandler, e return process.GetShardHeaderFromPool(hash, boot.headers) } -func (boot *baseBootstrap) getMetaHeaderWithNonce( - nonce uint64, -) (data.HeaderHandler, []byte, error) { - header, hash, err := process.GetMetaHeaderFromPoolWithNonce(nonce, boot.headers) - if err == nil { - return header, hash, nil - } - - return process.GetMetaHeaderFromStorageWithNonce( - nonce, - boot.store, - boot.uint64Converter, - boot.marshalizer, - ) -} - func (boot *baseBootstrap) getHeaderFromPoolWithNonce( nonce uint64, ) (data.HeaderHandler, []byte, error) {