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

Deep VM queries: deep-history observer vs. regular observer #6005

Merged
merged 10 commits into from
Mar 5, 2024
1 change: 1 addition & 0 deletions factory/api/apiResolverFactory.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ func createScQueryElement(
Marshaller: args.coreComponents.InternalMarshalizer(),
Hasher: args.coreComponents.Hasher(),
Uint64ByteSliceConverter: args.coreComponents.Uint64ByteSliceConverter(),
IsInSnapshottingMode: args.generalConfig.StateTriesConfig.SnapshotsEnabled,
}

return smartContract.NewSCQueryService(argsNewSCQueryService)
Expand Down
44 changes: 38 additions & 6 deletions process/smartContract/scQueryService.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

// MaxGasLimitPerQuery - each unit is the equivalent of 1 nanosecond processing time
const MaxGasLimitPerQuery = 300_000_000_000
const epochDifferenceToConsiderHistory = 2

// SCQueryService can execute Get functions over SC to fetch stored values
type SCQueryService struct {
Expand All @@ -53,6 +52,8 @@
marshaller marshal.Marshalizer
hasher hashing.Hasher
uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter
latestQueriedEpoch core.OptionalUint32
isInSnapshottingMode bool
}

// ArgsNewSCQueryService defines the arguments needed for the sc query service
Expand All @@ -72,6 +73,7 @@
Marshaller marshal.Marshalizer
Hasher hashing.Hasher
Uint64ByteSliceConverter typeConverters.Uint64ByteSliceConverter
IsInSnapshottingMode bool
}

// NewSCQueryService returns a new instance of SCQueryService
Expand Down Expand Up @@ -103,6 +105,8 @@
marshaller: args.Marshaller,
hasher: args.Hasher,
uint64ByteSliceConverter: args.Uint64ByteSliceConverter,
latestQueriedEpoch: core.OptionalUint32{},
isInSnapshottingMode: args.IsInSnapshottingMode,
}, nil
}

Expand Down Expand Up @@ -255,14 +259,42 @@
}

accountsAdapter := service.blockChainHook.GetAccountsAdapter()
if blockHeader.GetEpoch()+epochDifferenceToConsiderHistory >= service.getCurrentEpoch() {
logQueryService.Trace("calling RecreateTrie, for recent history", "block", blockHeader.GetNonce(), "rootHash", blockRootHash)
return accountsAdapter.RecreateTrie(blockRootHash)

if service.shouldCallRecreateTrieWithoutEpoch(blockHeader.GetEpoch()) {
logQueryService.Trace("calling RecreateTrie", "block", blockHeader.GetNonce(), "rootHash", blockRootHash)

err := accountsAdapter.RecreateTrie(blockRootHash)
if err != nil {
return err

Check warning on line 268 in process/smartContract/scQueryService.go

View check run for this annotation

Codecov / codecov/patch

process/smartContract/scQueryService.go#L268

Added line #L268 was not covered by tests
}

service.rememberQueriedEpoch(blockHeader.GetEpoch())
Copy link
Contributor

Choose a reason for hiding this comment

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

missing return here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Indeed, fixed.

return nil
}

logQueryService.Trace("calling RecreateTrieFromEpoch, for older history", "block", blockHeader.GetNonce(), "rootHash", blockRootHash)
logQueryService.Trace("calling RecreateTrieFromEpoch", "block", blockHeader.GetNonce(), "rootHash", blockRootHash)
holder := holders.NewRootHashHolder(blockRootHash, core.OptionalUint32{Value: blockHeader.GetEpoch(), HasValue: true})
return accountsAdapter.RecreateTrieFromEpoch(holder)

err := accountsAdapter.RecreateTrieFromEpoch(holder)
if err != nil {
return err

Check warning on line 280 in process/smartContract/scQueryService.go

View check run for this annotation

Codecov / codecov/patch

process/smartContract/scQueryService.go#L280

Added line #L280 was not covered by tests
}

service.rememberQueriedEpoch(blockHeader.GetEpoch())
return nil
}

func (service *SCQueryService) shouldCallRecreateTrieWithoutEpoch(epochInQuestion uint32) bool {
if !service.isInSnapshottingMode {
// for snapshotless operation, we need to force this method to return true so the RecreateTrie will be called instead of RecreateTrieFromEpoch
return true
}

return service.latestQueriedEpoch.HasValue && service.latestQueriedEpoch.Value == epochInQuestion
}

func (service *SCQueryService) rememberQueriedEpoch(epoch uint32) {
service.latestQueriedEpoch = core.OptionalUint32{Value: epoch, HasValue: true}
}

func (service *SCQueryService) getCurrentEpoch() uint32 {
Expand Down