Skip to content
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
87 changes: 84 additions & 3 deletions process/sync/baseSync.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import (
"github.com/multiversx/mx-chain-core-go/marshal"
logger "github.com/multiversx/mx-chain-logger-go"

"github.com/multiversx/mx-chain-go/epochStart"
"github.com/multiversx/mx-chain-go/epochStart/bootstrap/disabled"
"github.com/multiversx/mx-chain-go/process/asyncExecution/queue"
"github.com/multiversx/mx-chain-go/update"
updateSync "github.com/multiversx/mx-chain-go/update/sync"

"github.com/multiversx/mx-chain-go/common"
"github.com/multiversx/mx-chain-go/consensus"
Expand All @@ -50,6 +54,7 @@ var _ closing.Closer = (*baseBootstrap)(nil)
// sleepTime defines the time in milliseconds between each iteration made in syncBlocks method
const sleepTime = 50 * time.Millisecond
const minimumProcessWaitTime = time.Millisecond * 100
const defaultTimeToWaitForRequestedData = 5 * time.Minute

// hdrInfo hold the data related to a header
type hdrInfo struct {
Expand Down Expand Up @@ -146,6 +151,9 @@ type baseBootstrap struct {
preparedForSyncAtBootstrap bool

repopulateTokensSupplies bool

miniBlocksSyncer epochStart.PendingMiniBlocksSyncHandler
txSyncer update.TransactionsSyncHandler
}

func (boot *baseBootstrap) getProcessWaitTime(round uint64) time.Duration {
Expand Down Expand Up @@ -818,7 +826,7 @@ func (boot *baseBootstrap) prepareForSyncAtBoostrapIfNeeded() error {
"currHeader nonce", currentHeader.GetNonce(),
)

err := boot.prepareForSyncIfNeeded(syncingNonce)
err := boot.prepareForSyncIfNeeded(syncingNonce, true)
if err != nil {
return err
}
Expand Down Expand Up @@ -990,7 +998,7 @@ func (boot *baseBootstrap) prepareForLegacySyncIfNeeded() error {
// Finally, if everything works, the block will be committed and added into the processing queue.
// And all this mechanism will be reiterated for the next block.
func (boot *baseBootstrap) syncBlockV3(body data.BodyHandler, header data.HeaderHandler) error {
err := boot.prepareForSyncIfNeeded(header.GetNonce())
err := boot.prepareForSyncIfNeeded(header.GetNonce(), false)
if err != nil {
return err
}
Expand Down Expand Up @@ -1045,7 +1053,38 @@ func (boot *baseBootstrap) syncBlockV3(body data.BodyHandler, header data.Header
return nil
}

func (boot *baseBootstrap) prepareForSyncIfNeeded(syncingNonce uint64) error {
func (boot *baseBootstrap) syncMiniBlocksAndTxsForHeader(
header data.HeaderHandler,
) error {
boot.miniBlocksSyncer.ClearFields()
ctx, cancel := context.WithTimeout(context.Background(), defaultTimeToWaitForRequestedData)
err := boot.miniBlocksSyncer.SyncPendingMiniBlocks(header.GetMiniBlockHeaderHandlers(), ctx)
cancel()
if err != nil {
return err
}

miniBlocks, err := boot.miniBlocksSyncer.GetMiniBlocks()
if err != nil {
return err
}

// sync all txs into pools

ctx, cancel = context.WithTimeout(context.Background(), defaultTimeToWaitForRequestedData)
err = boot.txSyncer.SyncTransactionsFor(miniBlocks, header.GetEpoch(), ctx)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here ctx is reused but already canceled on L1062

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, updated

Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The context is being used after it has been cancelled. The context is created and cancelled before calling SyncTransactionsFor on line 1074. This will cause the transaction sync operation to fail immediately since it receives an already-cancelled context. A new context should be created for the SyncTransactionsFor call, or the cancel should be deferred until after both sync operations complete.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

cancel()
if err != nil {
return err
}

return nil
}

func (boot *baseBootstrap) prepareForSyncIfNeeded(
syncingNonce uint64,
withTxs bool,
) error {
if boot.preparedForSync {
return nil
}
Expand All @@ -1067,6 +1106,13 @@ func (boot *baseBootstrap) prepareForSyncIfNeeded(syncingNonce uint64) error {
return errGetBody
}

if withTxs {
err = boot.syncMiniBlocksAndTxsForHeader(currentHeader)
if err != nil {
return err
}
}

err = boot.saveProposedTxsToPool(currentHeader, currentBody)
if err != nil {
return err
Expand Down Expand Up @@ -1103,6 +1149,13 @@ func (boot *baseBootstrap) prepareForSyncIfNeeded(syncingNonce uint64) error {
return errGetBody
}

if withTxs {
err = boot.syncMiniBlocksAndTxsForHeader(hdr)
if err != nil {
return err
}
}

err = boot.saveProposedTxsToPool(hdr, body)
if err != nil {
return err
Expand Down Expand Up @@ -2209,3 +2262,31 @@ func (boot *baseBootstrap) getHeaderMiniBlocks(
func (boot *baseBootstrap) IsInterfaceNil() bool {
return boot == nil
}

func (boot *baseBootstrap) createTxSyncer() error {
var err error

syncMiniBlocksArgs := updateSync.ArgsNewPendingMiniBlocksSyncer{
Storage: disabled.CreateMemUnit(),
Cache: boot.dataPool.MiniBlocks(),
Marshalizer: boot.marshalizer,
RequestHandler: boot.requestHandler,
}
boot.miniBlocksSyncer, err = updateSync.NewPendingMiniBlocksSyncer(syncMiniBlocksArgs)
if err != nil {
return err
}

syncTxsArgs := updateSync.ArgsNewTransactionsSyncer{
DataPools: boot.dataPool,
Storages: boot.store,
Marshaller: boot.marshalizer,
RequestHandler: boot.requestHandler,
}
boot.txSyncer, err = updateSync.NewTransactionsSyncer(syncTxsArgs)
if err != nil {
return err
}

return nil
}
5 changes: 5 additions & 0 deletions process/sync/metablock.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@ func NewMetaBootstrap(arguments ArgMetaBootstrapper) (*MetaBootstrap, error) {
return nil, err
}

err = base.createTxSyncer()
if err != nil {
return nil, err
}

base.init()

return &boot, nil
Expand Down
5 changes: 5 additions & 0 deletions process/sync/shardblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ func NewShardBootstrap(arguments ArgShardBootstrapper) (*ShardBootstrap, error)
return nil, err
}

err = base.createTxSyncer()
if err != nil {
return nil, err
}

base.init()

return &boot, nil
Expand Down
6 changes: 4 additions & 2 deletions process/sync/shardblock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ func createFullStore() dataRetriever.StorageService {
store.AddStorer(dataRetriever.ScheduledSCRsUnit, generateTestUnit())
store.AddStorer(dataRetriever.UserAccountsUnit, generateTestUnit())
store.AddStorer(dataRetriever.PeerAccountsUnit, generateTestUnit())
store.AddStorer(dataRetriever.UnsignedTransactionUnit, generateTestUnit())
return store
}

Expand Down Expand Up @@ -678,7 +679,7 @@ func TestNewShardBootstrap_OkValsShouldWork(t *testing.T) {

assert.False(t, check.IfNil(bs))
assert.Nil(t, err)
assert.Equal(t, 2, wasCalled)
assert.Equal(t, 3, wasCalled)
assert.False(t, bs.IsInterfaceNil())
assert.True(t, bs.IsInImportMode())

Expand Down Expand Up @@ -1937,7 +1938,8 @@ func TestBootstrap_GetTxBodyHavingHashFoundInStorageShouldWork(t *testing.T) {
},
}

bs, _ := sync.NewShardBootstrap(args)
bs, err := sync.NewShardBootstrap(args)
require.Nil(t, err)
gotMbsAndHashes, _ := bs.GetMiniBlocks(requestedHash)

assert.Equal(t, mbsAndHashes, gotMbsAndHashes)
Expand Down
Loading