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

State changes collector #5585

Merged
merged 18 commits into from
Sep 4, 2024
Merged

Conversation

BeniaminDrasovean
Copy link
Contributor

@BeniaminDrasovean BeniaminDrasovean commented Sep 18, 2023

Reasoning behind the pull request

  • The lite clients will need the state changes delta for each transaction. Currently, the protocol does not collect the state changes triggered by each transaction.

Proposed changes

  • The accountsDB will collect all state changes in a new struct. When an account is saved, the new stateChangesCollector will save all the changes made to that account. This includes code changes, data trie changes, data trie migration, etc. No extra processing is needed, the new data is already available in the trackableDataTrie
  • After each tx executed by the txProcessor, get the collected state changes, and reset the stateChangesCollector so that it will be ready for the next tx execution.
  • Add a new flag in config CollectStateChangesEnabled which is disabled by default.

Testing procedure

  • Normal testing procedure
  • Create a separate trie which is modified only by applying the collected state changes. The real trie and the new trie should have the same rootHash after each block.

Pre-requisites

Based on the Contributing Guidelines the PR author and the reviewers must check the following requirements are met:

  • was the PR targeted to the correct branch?
  • if this is a larger feature that probably needs more than one PR, is there a feat branch created?
  • if this is a feat branch merging, do all satellite projects have a proper tag inside go.mod?

@codecov
Copy link

codecov bot commented Sep 18, 2023

Codecov Report

Attention: Patch coverage is 76.84729% with 47 lines in your changes are missing coverage. Please review.

Project coverage is 80.17%. Comparing base (edcbe7b) to head (5331072).

Files Patch % Lines
state/accountsDB.go 78.87% 12 Missing and 3 partials ⚠️
state/trackableDataTrie/trackableDataTrie.go 78.57% 11 Missing and 4 partials ⚠️
factory/state/stateComponents.go 82.60% 2 Missing and 2 partials ⚠️
...ocess/transactionEvaluator/simulationAccountsDB.go 0.00% 4 Missing ⚠️
state/accountsDBApi.go 0.00% 4 Missing ⚠️
state/accountsDBApiWithHistory.go 0.00% 3 Missing ⚠️
update/genesis/import.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@                     Coverage Diff                     @@
##           feat/light-client-support    #5585    +/-   ##
===========================================================
  Coverage                      80.17%   80.17%            
===========================================================
  Files                            752      753     +1     
  Lines                          97907    98035   +128     
===========================================================
+ Hits                           78493    78601   +108     
- Misses                         14043    14056    +13     
- Partials                        5371     5378     +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@BeniaminDrasovean BeniaminDrasovean changed the base branch from rc/v1.6.0 to feat/light-client-support September 18, 2023 08:20
iulianpascalau and others added 9 commits January 26, 2024 14:26
…t-client-support

Merge rc/v1.7.0 in feat/light client support
…llector

# Conflicts:
#	epochStart/metachain/systemSCs_test.go
#	factory/api/apiResolverFactory.go
#	factory/processing/blockProcessorCreator_test.go
#	factory/state/stateComponents.go
#	genesis/process/memoryComponents.go
#	integrationTests/state/stateTrie/stateTrie_test.go
#	integrationTests/testInitializer.go
#	process/transaction/metaProcess.go
#	state/accountsDB.go
#	state/accountsDB_test.go
#	state/errors.go
#	state/factory/accountsAdapterAPICreator_test.go
#	state/interface.go
#	state/storagePruningManager/storagePruningManager_test.go
#	state/trackableDataTrie/trackableDataTrie.go
#	state/trackableDataTrie/trackableDataTrie_test.go
#	testscommon/integrationtests/factory.go
#	testscommon/state/accountsAdapterStub.go
#	update/genesis/import.go
…-client-support

Merge rc/1.7.0 in feat/light client support
# Conflicts:
#	cmd/node/config/config.toml
#	state/accountsDB_test.go
#	state/errors.go
#	state/interface.go
#	state/trackableDataTrie/trackableDataTrie.go
Comment on lines +23 to +24
stateChanges []StateChangeDTO
stateChangesForTx []StateChangesForTx
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need lock protection for these?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file was removed in your PR. Will leave like this so it won't generate any more conflicts.

}
})

t.Run("getStateChanges without tx hash", func(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

add a test case for these 2 scenarios combined?
AddStateChange -> AddTxHashToCollectedStateChanges -> AddStateChange and then GetStateChanges

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file was removed in your PR. Will leave like this so it won't generate any more conflicts.

adb.stateChangesCollector.AddTxHashToCollectedStateChanges(txHash)
}

func (adb *AccountsDB) ResetStateChangesCollector() []StateChangesForTx {
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe rename to FetchAndReset...?

Copy link
Contributor

Choose a reason for hiding this comment

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

so this function will be used if we want to collect and save state changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This func was removed in your PR. Will leave like this so it won't generate any more conflicts.

Comment on lines +41 to +42
if len(scc.stateChanges) > 0 {
scc.AddTxHashToCollectedStateChanges([]byte{})
Copy link
Contributor

Choose a reason for hiding this comment

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

so if GetStateChanges will be called after several AddStateChange without AddTxHashToCollectedStateChanges those state changes will remain with empty tx hash, does it help to reference state changes without an identifier?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was addressed in your PR.

@ssd04 ssd04 changed the base branch from feat/light-client-support to feat/state-changes August 26, 2024 07:38
@@ -913,6 +913,7 @@ func createAccountsDB(
StoragePruningManager: spm,
AddressConverter: &testscommon.PubkeyConverterMock{},
SnapshotsManager: disabledState.NewDisabledSnapshotsManager(),
StateChangesCollector: state.NewStateChangesCollector(),
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe use the disabled collector

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@@ -205,6 +205,7 @@ func createAccountAdapter(
StoragePruningManager: disabled.NewDisabledStoragePruningManager(),
AddressConverter: &testscommon.PubkeyConverterMock{},
SnapshotsManager: disabledState.NewDisabledSnapshotsManager(),
StateChangesCollector: state.NewStateChangesCollector(),
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe use the disabled collector, and only in the specific test use a real state collector.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -228,6 +235,11 @@ func (scf *stateComponentsFactory) createPeerAdapter(triesContainer common.Tries
return nil, err
}

stateChangesCollector := disabled.NewDisabledStateChangesCollector()
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe we should have the state changes collected since the genesis if we only use these to export the data and index it.
Then use a flag for when we add the changes to the block.

There can also be a config flag (not enable epoch), if we want it to be exported from the node (through the outport driver) or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was refactored in the PR from Darius

@@ -172,6 +172,16 @@ func (r *simulationAccountsDB) GetStackDebugFirstEntry() []byte {
return nil
}

// SetTxHashForLatestStateChanges -
func (r *simulationAccountsDB) SetTxHashForLatestStateChanges(txHash []byte) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this will not affect also the collected changes during processing right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, it will not affect

}
adb.stateChangesCollector.AddStateChange(stateChange)

return err
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe return nil? as err!=nil was already returned at 273

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -195,6 +195,8 @@ func (txProc *txProcessor) ProcessTransaction(tx *transaction.Transaction) (vmco
txProc.pubkeyConv,
)

defer txProc.accounts.SetTxHashForLatestStateChanges(txHash)
Copy link
Contributor

Choose a reason for hiding this comment

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

the defer would call this method after return, and I see processing happens before, shouldn't the set happen before the processing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea was to link all the changes triggered by a tx to the txHash after the tx was executed. It can be refactored as you say, but I would do that in the next PR to avoid generating more conflicts with @ssd04's PR

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added TODO

@@ -217,7 +222,8 @@ func (adb *AccountsDB) ImportAccount(account vmcommon.AccountHandler) error {
}

mainTrie := adb.getMainTrie()
return adb.saveAccountToTrie(account, mainTrie)
_, err := adb.saveAccountToTrie(account, mainTrie)
Copy link
Contributor

Choose a reason for hiding this comment

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

what was the purpose of this save?
also does it affect the trie state? if it does then we should collect the data as state change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is used only on the old hardFork component, which will be removed.


// ResetStateChangesCollector returns nil
func (accountsDB *accountsDBApi) ResetStateChangesCollector() []StateChangesForTx {
return nil
Copy link
Contributor

Choose a reason for hiding this comment

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

this doesn't seem to reset anything but for the setTxHashForLatestStateChanges a txhash seems to be registered.

so is this empty reset ok and should setTxHashForLatestStateChanges do nothing as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed for consistency. This component uses a disabledStateChangesCollector, so it would not do anything.

@@ -66,7 +66,7 @@ func (jea *journalEntryCode) revertOldCodeEntry() error {
return nil
}

err := saveCodeEntry(jea.oldCodeHash, jea.oldCodeEntry, jea.trie, jea.marshalizer)
_, err := saveCodeEntry(jea.oldCodeHash, jea.oldCodeEntry, jea.trie, jea.marshalizer)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think I have seen any treatment for the revert in the state collector, I guess that is on another PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is treated in the PR from @ssd04

}

type stateChangesCollector struct {
stateChanges []StateChangeDTO
Copy link
Contributor

Choose a reason for hiding this comment

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

what are the separate state changes not linked to a txhash for?

I guess they should still be linked to a reason of the change, even if there is no tx for that - e.g rating change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed. This will be done in the next PR

@BeniaminDrasovean BeniaminDrasovean marked this pull request as ready for review September 4, 2024 13:09
@AdoAdoAdo AdoAdoAdo merged commit ccffe6d into feat/state-changes Sep 4, 2024
6 checks passed
@AdoAdoAdo AdoAdoAdo deleted the state-changes-collector branch September 4, 2024 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants