From 0419fcf2928b060ade90e0eebdb0d5cdf23bd3cb Mon Sep 17 00:00:00 2001 From: jonastheis <4181434+jonastheis@users.noreply.github.com> Date: Tue, 26 Mar 2024 15:49:53 +0800 Subject: [PATCH 1/4] Implement test/benchmark to understand substantial memory retention in utxo ledger state tree --- .../engine/utxoledger/manager_test.go | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/pkg/protocol/engine/utxoledger/manager_test.go b/pkg/protocol/engine/utxoledger/manager_test.go index 0f2f179d3..6f0b62497 100644 --- a/pkg/protocol/engine/utxoledger/manager_test.go +++ b/pkg/protocol/engine/utxoledger/manager_test.go @@ -2,13 +2,20 @@ package utxoledger_test import ( + "fmt" "testing" + "time" + "github.com/fjl/memsize" "github.com/stretchr/testify/require" + "github.com/iotaledger/hive.go/ads" + "github.com/iotaledger/hive.go/db" + "github.com/iotaledger/hive.go/ierrors" "github.com/iotaledger/hive.go/kvstore/mapdb" "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger" "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger/tpkg" + "github.com/iotaledger/iota-core/pkg/storage/database" iotago "github.com/iotaledger/iota.go/v4" iotago_tpkg "github.com/iotaledger/iota.go/v4/tpkg" ) @@ -238,3 +245,108 @@ func TestConfirmationApplyAndRollbackToPreviousLedger(t *testing.T) { })) require.Empty(t, spentByOutputID) } + +func TestMemLeakStateTree(t *testing.T) { + t.Skip("This test is not meant to be run in CI, it's for local testing only") + + dbConfig := database.Config{ + Engine: db.EngineRocksDB, + Directory: t.TempDir(), + Version: 1, + PrefixHealth: []byte{2}, + } + rocksDB := database.NewDBInstance(dbConfig, nil) + kvStore := rocksDB.KVStore() + stateTree := ads.NewMap[iotago.Identifier](kvStore, + iotago.Identifier.Bytes, + iotago.IdentifierFromBytes, + iotago.OutputID.Bytes, + iotago.OutputIDFromBytes, + (*stateTreeMetadata).Bytes, + stateMetadataFromBytes, + ) + + var totalOutputs int + var allOutputs []*utxoledger.Output + runTest := func(reInit bool, outputCount int) { + totalOutputs += outputCount + fmt.Println(">>> Running with", outputCount, "outputs, reInit:", reInit) + fmt.Println(">>> Total outputs:", totalOutputs) + + start := time.Now() + if reInit { + stateTree = ads.NewMap[iotago.Identifier](kvStore, + iotago.Identifier.Bytes, + iotago.IdentifierFromBytes, + iotago.OutputID.Bytes, + iotago.OutputIDFromBytes, + (*stateTreeMetadata).Bytes, + stateMetadataFromBytes, + ) + } + + newOutputs := make([]*utxoledger.Output, outputCount) + { + for i := 0; i < outputCount; i++ { + newOutputs[i] = tpkg.RandLedgerStateOutputWithType(iotago.OutputBasic) + allOutputs = append(allOutputs, newOutputs[i]) + } + + for _, output := range newOutputs { + if err := stateTree.Set(output.OutputID(), newStateMetadata(output)); err != nil { + panic(ierrors.Wrapf(err, "failed to set new oputput in state tree, outputID: %s", output.OutputID().ToHex())) + } + } + + if err := stateTree.Commit(); err != nil { + panic(ierrors.Wrap(err, "failed to commit state tree")) + } + } + + memConsumptionEnd := memsize.Scan(stateTree) + fmt.Println(">>> Took: ", time.Since(start).String()) + fmt.Println() + fmt.Println(">>> Memory:", memConsumptionEnd.Report()) + + // Check that all outputs are in the tree + for _, output := range allOutputs { + exists, err := stateTree.Has(output.OutputID()) + require.NoError(t, err) + require.True(t, exists) + } + + fmt.Printf("----------------------------------------------------------------\n\n") + } + + runTest(false, 1000000) + runTest(false, 1000000) + runTest(false, 1000000) + runTest(false, 10000) +} + +type stateTreeMetadata struct { + Slot iotago.SlotIndex +} + +func newStateMetadata(output *utxoledger.Output) *stateTreeMetadata { + return &stateTreeMetadata{ + Slot: output.SlotCreated(), + } +} + +func stateMetadataFromBytes(b []byte) (*stateTreeMetadata, int, error) { + s := new(stateTreeMetadata) + + var err error + var n int + s.Slot, n, err = iotago.SlotIndexFromBytes(b) + if err != nil { + return nil, 0, err + } + + return s, n, nil +} + +func (s *stateTreeMetadata) Bytes() ([]byte, error) { + return s.Slot.Bytes() +} From 3eb975b33d0ab09d08ba805859bbb605c25d011b Mon Sep 17 00:00:00 2001 From: jonastheis <4181434+jonastheis@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:59:32 +0800 Subject: [PATCH 2/4] Re-init utxoledger state tree after we commit to release memory --- pkg/protocol/engine/ledger/ledger/ledger.go | 5 +- .../engine/utxoledger/iteration_test.go | 5 +- pkg/protocol/engine/utxoledger/manager.go | 77 +++++++++++++------ .../engine/utxoledger/manager_test.go | 7 +- pkg/protocol/engine/utxoledger/output_test.go | 2 +- .../engine/utxoledger/slot_diff_test.go | 2 +- pkg/protocol/engine/utxoledger/snapshot.go | 4 + .../engine/utxoledger/snapshot_test.go | 16 ++-- 8 files changed, 76 insertions(+), 42 deletions(-) diff --git a/pkg/protocol/engine/ledger/ledger/ledger.go b/pkg/protocol/engine/ledger/ledger/ledger.go index 66bde9022..ddc49b1c1 100644 --- a/pkg/protocol/engine/ledger/ledger/ledger.go +++ b/pkg/protocol/engine/ledger/ledger/ledger.go @@ -178,7 +178,8 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier, // Commit the changes // Update the UTXO ledger - if err = l.utxoLedger.ApplyDiff(slot, outputs, spenders); err != nil { + stateTreeRoot, err := l.utxoLedger.ApplyDiff(slot, outputs, spenders) + if err != nil { return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, nil, nil, nil, ierrors.Wrapf(err, "failed to apply diff to UTXO ledger for slot %d", slot) } @@ -217,7 +218,7 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier, // (due to removing the attachments) and then committed, which would result in a broken state of the transaction. l.memPool.Evict(slot) - return l.utxoLedger.StateTreeRoot(), stateDiff.Mutations().Root(), l.accountsLedger.AccountsTreeRoot(), outputs, spenders, mutations, nil + return stateTreeRoot, stateDiff.Mutations().Root(), l.accountsLedger.AccountsTreeRoot(), outputs, spenders, mutations, nil } func (l *Ledger) AddAccount(output *utxoledger.Output, blockIssuanceCredits iotago.BlockIssuanceCredits) error { diff --git a/pkg/protocol/engine/utxoledger/iteration_test.go b/pkg/protocol/engine/utxoledger/iteration_test.go index b2243e2d6..0b1159af6 100644 --- a/pkg/protocol/engine/utxoledger/iteration_test.go +++ b/pkg/protocol/engine/utxoledger/iteration_test.go @@ -7,6 +7,7 @@ import ( "github.com/stretchr/testify/require" "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/iotaledger/hive.go/lo" "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger" "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger/tpkg" iotago "github.com/iotaledger/iota.go/v4" @@ -34,7 +35,7 @@ func TestUTXOComputeBalance(t *testing.T) { tpkg.RandLedgerStateSpentWithOutput(initialOutput, index), } - require.NoError(t, manager.ApplyDiffWithoutLocking(index, outputs, spents)) + require.NoError(t, lo.Return2(manager.ApplyDiffWithoutLocking(index, outputs, spents))) spent, err := manager.SpentOutputs() require.NoError(t, err) @@ -80,7 +81,7 @@ func TestUTXOIteration(t *testing.T) { tpkg.RandLedgerStateSpentWithOutput(outputs[9], index), } - require.NoError(t, manager.ApplyDiffWithoutLocking(index, outputs, spents)) + require.NoError(t, lo.Return2(manager.ApplyDiffWithoutLocking(index, outputs, spents))) // Prepare values to check outputByID := make(map[string]struct{}) diff --git a/pkg/protocol/engine/utxoledger/manager.go b/pkg/protocol/engine/utxoledger/manager.go index c107608e1..dbd88d30d 100644 --- a/pkg/protocol/engine/utxoledger/manager.go +++ b/pkg/protocol/engine/utxoledger/manager.go @@ -19,24 +19,22 @@ type Manager struct { store kvstore.KVStore storeLock syncutils.RWMutex - stateTree ads.Map[iotago.Identifier, iotago.OutputID, *stateTreeMetadata] + stateTreeKVStore kvstore.KVStore + stateTree ads.Map[iotago.Identifier, iotago.OutputID, *stateTreeMetadata] apiProvider iotago.APIProvider } func New(store kvstore.KVStore, apiProvider iotago.APIProvider) *Manager { - return &Manager{ - store: store, - stateTree: ads.NewMap[iotago.Identifier](lo.PanicOnErr(store.WithExtendedRealm(kvstore.Realm{StoreKeyPrefixStateTree})), - iotago.Identifier.Bytes, - iotago.IdentifierFromBytes, - iotago.OutputID.Bytes, - iotago.OutputIDFromBytes, - (*stateTreeMetadata).Bytes, - stateMetadataFromBytes, - ), - apiProvider: apiProvider, + m := &Manager{ + store: store, + stateTreeKVStore: lo.PanicOnErr(store.WithExtendedRealm(kvstore.Realm{StoreKeyPrefixStateTree})), + apiProvider: apiProvider, } + + m.reInitStateTreeWithoutLocking() + + return m } // KVStore returns the underlying KVStore. @@ -58,6 +56,25 @@ func (m *Manager) ClearLedgerState() (err error) { return m.store.Clear() } +func (m *Manager) ReInitStateTreeWithLocking() { + m.WriteLockLedger() + defer m.WriteUnlockLedger() + + m.reInitStateTreeWithoutLocking() +} + +func (m *Manager) reInitStateTreeWithoutLocking() { + m.stateTree = ads.NewMap[iotago.Identifier]( + m.stateTreeKVStore, + iotago.Identifier.Bytes, + iotago.IdentifierFromBytes, + iotago.OutputID.Bytes, + iotago.OutputIDFromBytes, + (*stateTreeMetadata).Bytes, + stateMetadataFromBytes, + ) +} + func (m *Manager) ReadLockLedger() { m.storeLock.RLock() } @@ -149,22 +166,22 @@ func (m *Manager) ReadLedgerSlot() (iotago.SlotIndex, error) { return m.ReadLedgerIndexWithoutLocking() } -func (m *Manager) ApplyDiffWithoutLocking(slot iotago.SlotIndex, newOutputs Outputs, newSpents Spents) error { +func (m *Manager) ApplyDiffWithoutLocking(slot iotago.SlotIndex, newOutputs Outputs, newSpents Spents) (newStateTreeRoot iotago.Identifier, error error) { mutations, err := m.store.Batched() if err != nil { - return err + return iotago.EmptyIdentifier, err } for _, output := range newOutputs { if err = storeOutput(output, mutations); err != nil { mutations.Cancel() - return err + return iotago.EmptyIdentifier, err } if err := markAsUnspent(output, mutations); err != nil { mutations.Cancel() - return err + return iotago.EmptyIdentifier, err } } @@ -172,7 +189,7 @@ func (m *Manager) ApplyDiffWithoutLocking(slot iotago.SlotIndex, newOutputs Outp if err := storeSpentAndMarkOutputAsSpent(spent, mutations); err != nil { mutations.Cancel() - return err + return iotago.EmptyIdentifier, err } } @@ -185,38 +202,44 @@ func (m *Manager) ApplyDiffWithoutLocking(slot iotago.SlotIndex, newOutputs Outp if err := storeDiff(slotDiff, mutations); err != nil { mutations.Cancel() - return err + return iotago.EmptyIdentifier, err } if err := storeLedgerIndex(slot, mutations); err != nil { mutations.Cancel() - return err + return iotago.EmptyIdentifier, err } if err := mutations.Commit(); err != nil { - return err + return iotago.EmptyIdentifier, err } for _, output := range newOutputs { if err := m.stateTree.Set(output.OutputID(), newStateMetadata(output)); err != nil { - return ierrors.Wrapf(err, "failed to set new oputput in state tree, outputID: %s", output.OutputID().ToHex()) + return iotago.EmptyIdentifier, ierrors.Wrapf(err, "failed to set new oputput in state tree, outputID: %s", output.OutputID().ToHex()) } } for _, spent := range newSpents { if _, err := m.stateTree.Delete(spent.OutputID()); err != nil { - return ierrors.Wrapf(err, "failed to delete spent output from state tree, outputID: %s", spent.OutputID().ToHex()) + return iotago.EmptyIdentifier, ierrors.Wrapf(err, "failed to delete spent output from state tree, outputID: %s", spent.OutputID().ToHex()) } } if err := m.stateTree.Commit(); err != nil { - return ierrors.Wrap(err, "failed to commit state tree") + return iotago.EmptyIdentifier, ierrors.Wrap(err, "failed to commit state tree") } - return nil + root := m.StateTreeRoot() + + // Re-Init the state tree to release memory from the underlying SMT of all the elements that were just added. + // This might increase runtime (as we need to access the disk) but it will reduce memory usage significantly for a big tree. + m.reInitStateTreeWithoutLocking() + + return root, nil } -func (m *Manager) ApplyDiff(slot iotago.SlotIndex, newOutputs Outputs, newSpents Spents) error { +func (m *Manager) ApplyDiff(slot iotago.SlotIndex, newOutputs Outputs, newSpents Spents) (newStateTreeRoot iotago.Identifier, error error) { m.WriteLockLedger() defer m.WriteUnlockLedger() @@ -289,6 +312,8 @@ func (m *Manager) RollbackDiffWithoutLocking(slot iotago.SlotIndex, newOutputs O return ierrors.Wrap(err, "failed to commit state tree") } + m.reInitStateTreeWithoutLocking() + return nil } @@ -321,6 +346,8 @@ func (m *Manager) AddGenesisUnspentOutputWithoutLocking(unspentOutput *Output) e return ierrors.Wrap(err, "failed to commit state tree") } + m.reInitStateTreeWithoutLocking() + return nil } diff --git a/pkg/protocol/engine/utxoledger/manager_test.go b/pkg/protocol/engine/utxoledger/manager_test.go index 6f0b62497..d4b7cc9de 100644 --- a/pkg/protocol/engine/utxoledger/manager_test.go +++ b/pkg/protocol/engine/utxoledger/manager_test.go @@ -13,6 +13,7 @@ import ( "github.com/iotaledger/hive.go/db" "github.com/iotaledger/hive.go/ierrors" "github.com/iotaledger/hive.go/kvstore/mapdb" + "github.com/iotaledger/hive.go/lo" "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger" "github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger/tpkg" "github.com/iotaledger/iota-core/pkg/storage/database" @@ -41,7 +42,7 @@ func TestConfirmationApplyAndRollbackToEmptyLedger(t *testing.T) { tpkg.RandLedgerStateSpentWithOutput(outputs[2], slot), } - require.NoError(t, manager.ApplyDiffWithoutLocking(slot, outputs, spents)) + require.NoError(t, lo.Return2(manager.ApplyDiffWithoutLocking(slot, outputs, spents))) require.NotEqual(t, manager.StateTreeRoot(), iotago.Identifier{}) require.True(t, manager.CheckStateTree()) @@ -107,7 +108,7 @@ func TestConfirmationApplyAndRollbackToPreviousLedger(t *testing.T) { previousSpents := utxoledger.Spents{ tpkg.RandLedgerStateSpentWithOutput(previousOutputs[1], previousMsIndex), } - require.NoError(t, manager.ApplyDiffWithoutLocking(previousMsIndex, previousOutputs, previousSpents)) + require.NoError(t, lo.Return2(manager.ApplyDiffWithoutLocking(previousMsIndex, previousOutputs, previousSpents))) require.True(t, manager.CheckStateTree()) @@ -129,7 +130,7 @@ func TestConfirmationApplyAndRollbackToPreviousLedger(t *testing.T) { tpkg.RandLedgerStateSpentWithOutput(previousOutputs[2], index), tpkg.RandLedgerStateSpentWithOutput(outputs[2], index), } - require.NoError(t, manager.ApplyDiffWithoutLocking(index, outputs, spents)) + require.NoError(t, lo.Return2(manager.ApplyDiffWithoutLocking(index, outputs, spents))) require.True(t, manager.CheckStateTree()) diff --git a/pkg/protocol/engine/utxoledger/output_test.go b/pkg/protocol/engine/utxoledger/output_test.go index b4142f3df..755f6c2b4 100644 --- a/pkg/protocol/engine/utxoledger/output_test.go +++ b/pkg/protocol/engine/utxoledger/output_test.go @@ -41,7 +41,7 @@ func AssertOutputUnspentAndSpentTransitions(t *testing.T, output *utxoledger.Out require.True(t, has) // Spent it with a slot. - require.NoError(t, manager.ApplyDiff(spent.SlotSpent(), utxoledger.Outputs{}, utxoledger.Spents{spent})) + require.NoError(t, lo.Return2(manager.ApplyDiff(spent.SlotSpent(), utxoledger.Outputs{}, utxoledger.Spents{spent}))) // Read Spent from DB and compare readSpent, err := manager.ReadSpentForOutputIDWithoutLocking(outputID) diff --git a/pkg/protocol/engine/utxoledger/slot_diff_test.go b/pkg/protocol/engine/utxoledger/slot_diff_test.go index ad8982831..f270bdc7a 100644 --- a/pkg/protocol/engine/utxoledger/slot_diff_test.go +++ b/pkg/protocol/engine/utxoledger/slot_diff_test.go @@ -80,7 +80,7 @@ func TestSlotDiffSerialization(t *testing.T) { tpkg.RandLedgerStateSpentWithOutput(outputs[2], slot), } - require.NoError(t, manager.ApplyDiffWithoutLocking(slot, outputs, spents)) + require.NoError(t, lo.Return2(manager.ApplyDiffWithoutLocking(slot, outputs, spents))) readDiff, err := manager.SlotDiffWithoutLocking(slot) require.NoError(t, err) diff --git a/pkg/protocol/engine/utxoledger/snapshot.go b/pkg/protocol/engine/utxoledger/snapshot.go index 53af5f0a5..9f0b6eabb 100644 --- a/pkg/protocol/engine/utxoledger/snapshot.go +++ b/pkg/protocol/engine/utxoledger/snapshot.go @@ -215,6 +215,8 @@ func (m *Manager) Import(reader io.ReadSeeker) error { return ierrors.Wrap(err, "unable to commit state tree") } + m.reInitStateTreeWithoutLocking() + return nil } @@ -306,5 +308,7 @@ func (m *Manager) Rollback(targetSlot iotago.SlotIndex) error { return ierrors.Wrap(err, "unable to commit state tree") } + m.reInitStateTreeWithoutLocking() + return nil } diff --git a/pkg/protocol/engine/utxoledger/snapshot_test.go b/pkg/protocol/engine/utxoledger/snapshot_test.go index 1e220077d..a41be7a22 100644 --- a/pkg/protocol/engine/utxoledger/snapshot_test.go +++ b/pkg/protocol/engine/utxoledger/snapshot_test.go @@ -235,13 +235,13 @@ func TestManager_Import(t *testing.T) { require.NoError(t, kvstore.Copy(mapDB, mapDBAtSlot0)) output2 := tpkg.RandLedgerStateOutput() - require.NoError(t, manager.ApplyDiff(1, + require.NoError(t, lo.Return2(manager.ApplyDiff(1, utxoledger.Outputs{ output2, tpkg.RandLedgerStateOutput(), }, utxoledger.Spents{ tpkg.RandLedgerStateSpentWithOutput(output1, 1), - })) + }))) ledgerSlot, err = manager.ReadLedgerSlot() require.NoError(t, err) @@ -250,14 +250,14 @@ func TestManager_Import(t *testing.T) { mapDBAtSlot1 := mapdb.NewMapDB() require.NoError(t, kvstore.Copy(mapDB, mapDBAtSlot1)) - require.NoError(t, manager.ApplyDiff(2, + require.NoError(t, lo.Return2(manager.ApplyDiff(2, utxoledger.Outputs{ tpkg.RandLedgerStateOutput(), tpkg.RandLedgerStateOutput(), tpkg.RandLedgerStateOutput(), }, utxoledger.Spents{ tpkg.RandLedgerStateSpentWithOutput(output2, 2), - })) + }))) ledgerSlot, err = manager.ReadLedgerSlot() require.NoError(t, err) @@ -325,26 +325,26 @@ func TestManager_Export(t *testing.T) { require.NoError(t, manager.AddGenesisUnspentOutput(tpkg.RandLedgerStateOutput())) output2 := tpkg.RandLedgerStateOutput() - require.NoError(t, manager.ApplyDiff(1, + require.NoError(t, lo.Return2(manager.ApplyDiff(1, utxoledger.Outputs{ output2, tpkg.RandLedgerStateOutput(), }, utxoledger.Spents{ tpkg.RandLedgerStateSpentWithOutput(output1, 1), - })) + }))) ledgerSlot, err := manager.ReadLedgerSlot() require.NoError(t, err) require.Equal(t, iotago.SlotIndex(1), ledgerSlot) - require.NoError(t, manager.ApplyDiff(2, + require.NoError(t, lo.Return2(manager.ApplyDiff(2, utxoledger.Outputs{ tpkg.RandLedgerStateOutput(), tpkg.RandLedgerStateOutput(), tpkg.RandLedgerStateOutput(), }, utxoledger.Spents{ tpkg.RandLedgerStateSpentWithOutput(output2, 2), - })) + }))) ledgerSlot, err = manager.ReadLedgerSlot() require.NoError(t, err) From 040a1eb450687aa19d511d4f268f013f9465fb0e Mon Sep 17 00:00:00 2001 From: jonastheis <4181434+jonastheis@users.noreply.github.com> Date: Tue, 26 Mar 2024 17:05:39 +0800 Subject: [PATCH 3/4] Disable debugAPI by default in Docker network and instead only enable on node-1-validator --- tools/docker-network/.env | 2 +- tools/docker-network/docker-compose.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/docker-network/.env b/tools/docker-network/.env index 09fececc7..ecd69a4fb 100644 --- a/tools/docker-network/.env +++ b/tools/docker-network/.env @@ -9,7 +9,7 @@ COMMON_CONFIG=" --db.path=/app/data/database --protocol.snapshot.path=/app/data/snapshot.bin --restAPI.publicRoutes=/health,/api/routes,/api/core/v3/info,/api/core/v3/network*,/api/core/v3/blocks*,/api/core/v3/transactions*,/api/core/v3/commitments*,/api/core/v3/outputs*,/api/core/v3/accounts*,/api/core/v3/validators*,/api/core/v3/rewards*,/api/core/v3/committee*,/api/debug/v2/*,/api/indexer/v2/*,/api/mqtt/v2,/api/blockissuer/v1/*,/api/management/v1/* ---debugAPI.enabled=true +--debugAPI.enabled=false " AUTOPEERING_CONFIG=" diff --git a/tools/docker-network/docker-compose.yml b/tools/docker-network/docker-compose.yml index b69def761..22e425037 100644 --- a/tools/docker-network/docker-compose.yml +++ b/tools/docker-network/docker-compose.yml @@ -34,6 +34,7 @@ services: --inx.bindAddress=0.0.0.0:9029 --prometheus.goMetrics=true --prometheus.processMetrics=true + --debugAPI.enabled=true node-2-validator: image: docker-network-node-1-validator:latest From f43047ca50dadb8e4d174158931afc8ed46f48a7 Mon Sep 17 00:00:00 2001 From: jonastheis <4181434+jonastheis@users.noreply.github.com> Date: Tue, 26 Mar 2024 17:17:40 +0800 Subject: [PATCH 4/4] Please doggo --- pkg/protocol/engine/utxoledger/manager.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/protocol/engine/utxoledger/manager.go b/pkg/protocol/engine/utxoledger/manager.go index dbd88d30d..454cabf92 100644 --- a/pkg/protocol/engine/utxoledger/manager.go +++ b/pkg/protocol/engine/utxoledger/manager.go @@ -166,7 +166,7 @@ func (m *Manager) ReadLedgerSlot() (iotago.SlotIndex, error) { return m.ReadLedgerIndexWithoutLocking() } -func (m *Manager) ApplyDiffWithoutLocking(slot iotago.SlotIndex, newOutputs Outputs, newSpents Spents) (newStateTreeRoot iotago.Identifier, error error) { +func (m *Manager) ApplyDiffWithoutLocking(slot iotago.SlotIndex, newOutputs Outputs, newSpents Spents) (newStateTreeRoot iotago.Identifier, err error) { mutations, err := m.store.Batched() if err != nil { return iotago.EmptyIdentifier, err @@ -239,7 +239,7 @@ func (m *Manager) ApplyDiffWithoutLocking(slot iotago.SlotIndex, newOutputs Outp return root, nil } -func (m *Manager) ApplyDiff(slot iotago.SlotIndex, newOutputs Outputs, newSpents Spents) (newStateTreeRoot iotago.Identifier, error error) { +func (m *Manager) ApplyDiff(slot iotago.SlotIndex, newOutputs Outputs, newSpents Spents) (newStateTreeRoot iotago.Identifier, err error) { m.WriteLockLedger() defer m.WriteUnlockLedger()