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

En 6597 state code pruning #1998

Merged
merged 10 commits into from
Jun 26, 2020

Conversation

BeniaminDrasovean
Copy link
Contributor

When SC code is saved to the trie, now also the number of references to the same code is saved in the same db. If the number of references to a certain code reaches 0, the trie node that contains the code is marked for eviction, and it will be pruned from the db.

@BeniaminDrasovean BeniaminDrasovean self-assigned this Jun 23, 2020
@sasurobert sasurobert self-requested a review June 23, 2020 14:17
@SebastianMarian SebastianMarian self-requested a review June 23, 2020 16:16
Code: []byte("newCode"),
NumReferences: 1,
}
marsh := &mock.MarshalizerMock{}
Copy link
Contributor

Choose a reason for hiding this comment

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

marsh sounds strange :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed.

}

return &journalEntryCode{
codeHash: codeHash,
updater: updater,
oldCodeEntry: oldCodeEntry,
Copy link
Contributor

Choose a reason for hiding this comment

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

oldCodeEntry could be nil? If not you should check it above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oldCodeEntry could be nil in the following case: If a newCode is set to an account that had no code before, the oldCodeEntry should be nil, in case that a revert occurs.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok

if jea.oldCodeEntry.NumReferences == 1 {
delete(jea.codeForEviction, string(jea.oldCodeHash))
}

Copy link
Contributor

Choose a reason for hiding this comment

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

jea.oldCodeEntry.NumReferences-- ?

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

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, because oldCodeEntry already has the numReferences set as before the changes. You can see in the accountDB that updateOldCodeEntry() returns unmodifiedOldCodeEntry that is used when creating a new journal entry.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok

return nil
}

if jea.oldCodeEntry.NumReferences == 1 {
Copy link
Contributor

Choose a reason for hiding this comment

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

<= ?

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.

@@ -940,3 +945,294 @@ func TestAccountsDB_GetAllLeaves(t *testing.T) {
assert.True(t, recreateCalled)
assert.True(t, getAllLeavesCalled)
}

func getTestAccountsDbAndTrie(marsh marshal.Marshalizer, hsh hashing.Hasher) (*state.AccountsDB, data.Trie) {
Copy link
Contributor

Choose a reason for hiding this comment

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

marsh sounds strange :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed.

return oldAccount.GetCodeHash(), nil
}

func (adb *AccountsDB) saveCode(accountHandler baseAccountHandler, oldAcc AccountHandler) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

accountHandler to newAcc

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.

if jea.oldCodeEntry.NumReferences == 1 {
delete(jea.codeForEviction, string(jea.oldCodeHash))
}

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

@@ -1665,3 +1666,146 @@ func testNodeStateCheckpointSnapshotAndPruning(
assert.NotNil(t, err)
}
}

func TestContinuouslyAccountCodeChanges(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.

function too big. make a few smaller ones.

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.

@@ -20,6 +20,9 @@ type AccountsDB struct {
marshalizer marshal.Marshalizer
accountFactory AccountFactory

codeForEviction map[string]struct{}
Copy link
Contributor

Choose a reason for hiding this comment

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

codeForEviction cannot be used with current state of smart contract process, as delete function, delete smart contract is not called at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If a code is updated and the old version is not used anymore, it needs to be evicted.

newCodeHash = adb.hasher.Compute(string(newCode))
}

if bytes.Equal(oldCodeHash, newCodeHash) {
Copy link
Contributor

Choose a reason for hiding this comment

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

saveCode should be called only there is a new code. if there is something in old code - delete account / code should be called. If a code is delete the whole account is deleted.

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 also sets the codeHash for the account. If a code is updated, isn't the same account used? In this case, there is something in both oldCode and newCode.

@@ -90,7 +95,7 @@ func (adb *AccountsDB) SaveAccount(account AccountHandler) error {

baseAcc, ok := account.(baseAccountHandler)
if ok {
err = adb.saveCode(baseAcc)
err = adb.saveCode(baseAcc, oldAccount)
Copy link
Contributor

Choose a reason for hiding this comment

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

make a separate function to saveCode and saveDataTrie where you can handle all the cases.

Copy link
Contributor

Choose a reason for hiding this comment

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

make type assertion for oldAccount as well. for save code you need baseAccountHandler only.

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.

}

newCode := accountHandler.GetCode()
newCode := newAcc.GetCode()
Copy link
Contributor

Choose a reason for hiding this comment

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

newAcc is always not nil? If not, add a check above

Copy link
Contributor Author

Choose a reason for hiding this comment

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

newAccount is always not nil. It is checked on L72, when SaveAccount() is called.

@BeniaminDrasovean BeniaminDrasovean merged commit 45d0a91 into feat/new-features Jun 26, 2020
@BeniaminDrasovean BeniaminDrasovean deleted the EN-6597-state-code-pruning branch June 26, 2020 14:16
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.

None yet

4 participants