From 1c68499be967e89c909f8ed7ad7db324eece003e Mon Sep 17 00:00:00 2001 From: Hans Moog <3293976+hmoog@users.noreply.github.com> Date: Fri, 3 May 2024 04:32:41 +0200 Subject: [PATCH] Fix: OutputID empty after rollback --- pkg/protocol/engine/accounts/accounts.go | 3 ++- .../engine/accounts/accountsledger/manager.go | 23 +++++++++++++++++-- .../accounts/accountsledger/snapshot.go | 19 ++++++++------- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/pkg/protocol/engine/accounts/accounts.go b/pkg/protocol/engine/accounts/accounts.go index d57288821..09503bca7 100644 --- a/pkg/protocol/engine/accounts/accounts.go +++ b/pkg/protocol/engine/accounts/accounts.go @@ -2,6 +2,7 @@ package accounts import ( "io" + "strconv" "github.com/iotaledger/hive.go/ierrors" "github.com/iotaledger/hive.go/runtime/options" @@ -172,7 +173,7 @@ func (a *AccountData) String() string { stringify.NewStructField("Credits", a.Credits), stringify.NewStructField("ExpirySlot", uint32(a.ExpirySlot)), stringify.NewStructField("OutputID", a.OutputID), - stringify.NewStructField("BlockIssuerKeys", a.BlockIssuerKeys), + stringify.NewStructField("BlockIssuerKeys", func() string { return strconv.Itoa(a.BlockIssuerKeys.Size()) }()), stringify.NewStructField("ValidatorStake", uint64(a.ValidatorStake)), stringify.NewStructField("DelegationStake", uint64(a.DelegationStake)), stringify.NewStructField("FixedCost", uint64(a.FixedCost)), diff --git a/pkg/protocol/engine/accounts/accountsledger/manager.go b/pkg/protocol/engine/accounts/accountsledger/manager.go index c4a45d6bd..57f7c3512 100644 --- a/pkg/protocol/engine/accounts/accountsledger/manager.go +++ b/pkg/protocol/engine/accounts/accountsledger/manager.go @@ -9,9 +9,11 @@ import ( "github.com/iotaledger/hive.go/ierrors" "github.com/iotaledger/hive.go/kvstore" "github.com/iotaledger/hive.go/lo" + "github.com/iotaledger/hive.go/log" "github.com/iotaledger/hive.go/runtime/module" "github.com/iotaledger/hive.go/runtime/options" "github.com/iotaledger/hive.go/runtime/syncutils" + "github.com/iotaledger/hive.go/stringify" "github.com/iotaledger/iota-core/pkg/model" "github.com/iotaledger/iota-core/pkg/protocol/engine/accounts" "github.com/iotaledger/iota-core/pkg/protocol/engine/blocks" @@ -127,7 +129,22 @@ func (m *Manager) AccountsTreeRoot() iotago.Identifier { m.mutex.RLock() defer m.mutex.RUnlock() - return m.accountsTree.Root() + root := m.accountsTree.Root() + + if m.LogLevel() == log.LevelTrace { + m.LogTrace("retrieving accounts tree", "root", root, "accounts", func() string { + accountsInTree := stringify.NewStructBuilder("Accounts") + _ = m.accountsTree.Stream(func(accountID iotago.AccountID, accountData *accounts.AccountData) error { + accountsInTree.AddField(stringify.NewStructField(accountID.String(), accountData)) + + return nil + }) + + return accountsInTree.String() + }()) + } + + return root } // ApplyDiff applies the given accountDiff to the Account tree. @@ -403,7 +420,9 @@ func (m *Manager) rollbackAccountTo(accountData *accounts.AccountData, targetSlo } // update the output ID of the account if it was changed - accountData.OutputID = diffChange.PreviousOutputID + if diffChange.PreviousOutputID != iotago.EmptyOutputID { + accountData.OutputID = diffChange.PreviousOutputID + } accountData.AddBlockIssuerKeys(diffChange.BlockIssuerKeysRemoved...) accountData.RemoveBlockIssuerKey(diffChange.BlockIssuerKeysAdded...) diff --git a/pkg/protocol/engine/accounts/accountsledger/snapshot.go b/pkg/protocol/engine/accounts/accountsledger/snapshot.go index d729db9f5..345f46e42 100644 --- a/pkg/protocol/engine/accounts/accountsledger/snapshot.go +++ b/pkg/protocol/engine/accounts/accountsledger/snapshot.go @@ -78,27 +78,26 @@ func (m *Manager) Export(writer io.WriteSeeker, targetIndex iotago.SlotIndex) er func (m *Manager) exportAccountTree(writer io.WriteSeeker, targetIndex iotago.SlotIndex) (int, error) { var accountCount int - if err := m.accountsTree.Stream(func(accountID iotago.AccountID, accountData *accounts.AccountData) error { - m.LogDebug("Exporting account", "accountID", accountID, "outputID", accountData.OutputID, "credits.value", accountData.Credits.Value, "credits.updateSlot", accountData.Credits.UpdateSlot) - - wasCreatedAfterTargetSlot, _, err := m.rollbackAccountTo(accountData, targetIndex) + if err := m.accountsTree.Stream(func(id iotago.AccountID, account *accounts.AccountData) error { + wasCreatedAfterTargetSlot, _, err := m.rollbackAccountTo(account, targetIndex) if err != nil { - return ierrors.Wrapf(err, "unable to rollback account %s", accountID) + return ierrors.Wrapf(err, "unable to rollback account %s", id) } - m.LogDebug("Exporting account after rollback", "accountID", accountID, "outputID", accountData.OutputID, "credits.value", accountData.Credits.Value, "credits.updateSlot", accountData.Credits.UpdateSlot) - // Account was created after the target slot, so we don't need to export it. if wasCreatedAfterTargetSlot { - m.LogDebug("Exporting account was created after target slot", "accountID", accountID, "targetSlot", targetIndex) + m.LogTrace("account was created after target slot", "id", id, "targetSlot", targetIndex) + return nil } - if err := stream.WriteObject(writer, accountData, (*accounts.AccountData).Bytes); err != nil { - return ierrors.Wrapf(err, "unable to write account %s", accountID) + if err = stream.WriteObject(writer, account, (*accounts.AccountData).Bytes); err != nil { + return ierrors.Wrapf(err, "unable to write account %s", id) } accountCount++ + m.LogTrace("exported account", "id", id, "account", account) + return nil }); err != nil { return 0, ierrors.Wrap(err, "error in streaming account tree")