Skip to content

Commit

Permalink
Merge pull request #536 from iotaledger/fix/ledger-updates-before-com…
Browse files Browse the repository at this point in the history
…mitment

Fix trigger of StateDiffApplied event before commitment is stored
  • Loading branch information
muXxer authored Nov 20, 2023
2 parents 668aa15 + 6be358d commit 2dc7db9
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 19 deletions.
5 changes: 3 additions & 2 deletions components/inx/server_utxo.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/iotaledger/hive.go/runtime/workerpool"
inx "github.com/iotaledger/inx/go"
"github.com/iotaledger/iota-core/pkg/protocol/engine/mempool"
"github.com/iotaledger/iota-core/pkg/protocol/engine/notarization"
"github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
iotago "github.com/iotaledger/iota.go/v4"
)
Expand Down Expand Up @@ -322,8 +323,8 @@ func (s *Server) ListenToLedgerUpdates(req *inx.SlotRangeRequest, srv inx.INX_Li

wp := workerpool.New("ListenToLedgerUpdates", workerpool.WithWorkerCount(workerCount)).Start()

unhook := deps.Protocol.Events.Engine.Ledger.StateDiffApplied.Hook(func(slot iotago.SlotIndex, newOutputs utxoledger.Outputs, newSpents utxoledger.Spents) {
done, err := handleRangedSend2(slot, newOutputs, newSpents, stream, catchUpFunc, sendFunc)
unhook := deps.Protocol.Events.Engine.Notarization.SlotCommitted.Hook(func(scd *notarization.SlotCommittedDetails) {
done, err := handleRangedSend2(scd.Commitment.Slot(), scd.OutputsCreated, scd.OutputsConsumed, stream, catchUpFunc, sendFunc)
switch {
case err != nil:
innerErr = err
Expand Down
3 changes: 0 additions & 3 deletions pkg/protocol/engine/ledger/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package ledger

import (
"github.com/iotaledger/hive.go/runtime/event"
"github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
iotago "github.com/iotaledger/iota.go/v4"
)

type Events struct {
StateDiffApplied *event.Event3[iotago.SlotIndex, utxoledger.Outputs, utxoledger.Spents]
AccountCreated *event.Event1[iotago.AccountID]
AccountDestroyed *event.Event1[iotago.AccountID]

Expand All @@ -17,7 +15,6 @@ type Events struct {
// NewEvents contains the constructor of the Events object (it is generated by a generic factory).
var NewEvents = event.CreateGroupConstructor(func() (newEvents *Events) {
return &Events{
StateDiffApplied: event.New3[iotago.SlotIndex, utxoledger.Outputs, utxoledger.Spents](),
AccountCreated: event.New1[iotago.AccountID](),
AccountDestroyed: event.New1[iotago.AccountID](),
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/protocol/engine/ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type Ledger interface {
ManaManager() *mana.Manager
RMCManager() *rmc.Manager

CommitSlot(slot iotago.SlotIndex) (stateRoot, mutationRoot, accountRoot iotago.Identifier, err error)
CommitSlot(slot iotago.SlotIndex) (stateRoot, mutationRoot, accountRoot iotago.Identifier, created utxoledger.Outputs, consumed utxoledger.Spents, err error)

Import(reader io.ReadSeeker) error
Export(writer io.WriteSeeker, targetSlot iotago.SlotIndex) error
Expand Down
22 changes: 10 additions & 12 deletions pkg/protocol/engine/ledger/ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@ func (l *Ledger) AttachTransaction(block *blocks.Block) (attachedTransaction mem
return nil, false
}

func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier, mutationRoot iotago.Identifier, accountRoot iotago.Identifier, err error) {
func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier, mutationRoot iotago.Identifier, accountRoot iotago.Identifier, created utxoledger.Outputs, consumed utxoledger.Spents, err error) {
ledgerIndex, err := l.utxoLedger.ReadLedgerSlot()
if err != nil {
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, err
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, nil, nil, err
}

if slot != ledgerIndex+1 {
Expand All @@ -150,15 +150,15 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier,

stateDiff, err := l.memPool.StateDiff(slot)
if err != nil {
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, ierrors.Errorf("failed to retrieve state diff for slot %d: %w", slot, err)
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, nil, nil, ierrors.Errorf("failed to retrieve state diff for slot %d: %w", slot, err)
}

// collect outputs and allotments from the "uncompacted" stateDiff
// outputs need to be processed in the "uncompacted" version of the state diff, as we need to be able to store
// and retrieve intermediate outputs to show to the user
spends, outputs, accountDiffs, err := l.processStateDiffTransactions(stateDiff)
if err != nil {
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, ierrors.Errorf("failed to process state diff transactions in slot %d: %w", slot, err)
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, nil, nil, ierrors.Errorf("failed to process state diff transactions in slot %d: %w", slot, err)
}

// Now we process the collected account changes, for that we consume the "compacted" state diff to get the overall
Expand All @@ -167,15 +167,15 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier,
// output side
createdAccounts, consumedAccounts, destroyedAccounts, err := l.processCreatedAndConsumedAccountOutputs(stateDiff, accountDiffs)
if err != nil {
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, ierrors.Errorf("failed to process outputs consumed and created in slot %d: %w", slot, err)
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, nil, nil, ierrors.Errorf("failed to process outputs consumed and created in slot %d: %w", slot, err)
}

l.prepareAccountDiffs(accountDiffs, slot, consumedAccounts, createdAccounts)

// Commit the changes
// Update the UTXO ledger
if err = l.utxoLedger.ApplyDiff(slot, outputs, spends); err != nil {
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, ierrors.Errorf("failed to apply diff to UTXO ledger for slot %d: %w", slot, err)
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, nil, nil, ierrors.Errorf("failed to apply diff to UTXO ledger for slot %d: %w", slot, err)
}

// Update the Accounts ledger
Expand All @@ -187,15 +187,15 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier,
}
rmcForSlot, err := l.rmcManager.RMC(rmcSlot)
if err != nil {
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, ierrors.Errorf("ledger failed to get RMC for slot %d: %w", rmcSlot, err)
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, nil, nil, ierrors.Errorf("ledger failed to get RMC for slot %d: %w", rmcSlot, err)
}
if err = l.accountsLedger.ApplyDiff(slot, rmcForSlot, accountDiffs, destroyedAccounts); err != nil {
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, ierrors.Errorf("failed to apply diff to Accounts ledger for slot %d: %w", slot, err)
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, nil, nil, ierrors.Errorf("failed to apply diff to Accounts ledger for slot %d: %w", slot, err)
}

// Update the mana manager's cache
if err = l.manaManager.ApplyDiff(slot, destroyedAccounts, createdAccounts, accountDiffs); err != nil {
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, ierrors.Errorf("failed to apply diff to mana manager for slot %d: %w", slot, err)
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, nil, nil, ierrors.Errorf("failed to apply diff to mana manager for slot %d: %w", slot, err)
}

// Mark each transaction as committed so the mempool can evict it
Expand All @@ -204,9 +204,7 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier,
return true
})

l.events.StateDiffApplied.Trigger(slot, outputs, spends)

return l.utxoLedger.StateTreeRoot(), stateDiff.Mutations().Root(), l.accountsLedger.AccountsTreeRoot(), nil
return l.utxoLedger.StateTreeRoot(), stateDiff.Mutations().Root(), l.accountsLedger.AccountsTreeRoot(), outputs, spends, nil
}

func (l *Ledger) AddAccount(output *utxoledger.Output, blockIssuanceCredits iotago.BlockIssuanceCredits) error {
Expand Down
3 changes: 3 additions & 0 deletions pkg/protocol/engine/notarization/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"github.com/iotaledger/hive.go/ads"
"github.com/iotaledger/hive.go/runtime/event"
"github.com/iotaledger/iota-core/pkg/model"
"github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
iotago "github.com/iotaledger/iota.go/v4"
)

Expand All @@ -28,4 +29,6 @@ type SlotCommittedDetails struct {
Commitment *model.Commitment
AcceptedBlocks ads.Set[iotago.Identifier, iotago.BlockID]
ActiveValidatorsCount int
OutputsCreated utxoledger.Outputs
OutputsConsumed utxoledger.Spents
}
4 changes: 3 additions & 1 deletion pkg/protocol/engine/notarization/slotnotarization/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (m *Manager) createCommitment(slot iotago.SlotIndex) (*model.Commitment, er
return nil, ierrors.Wrap(err, "failed to commit attestations")
}

stateRoot, mutationRoot, accountRoot, err := m.ledger.CommitSlot(slot)
stateRoot, mutationRoot, accountRoot, created, consumed, err := m.ledger.CommitSlot(slot)
if err != nil {
return nil, ierrors.Wrap(err, "failed to commit ledger")
}
Expand Down Expand Up @@ -255,6 +255,8 @@ func (m *Manager) createCommitment(slot iotago.SlotIndex) (*model.Commitment, er
Commitment: newModelCommitment,
AcceptedBlocks: acceptedBlocks,
ActiveValidatorsCount: 0,
OutputsCreated: created,
OutputsConsumed: consumed,
})

if err = m.storage.Settings().SetLatestCommitment(newModelCommitment); err != nil {
Expand Down

0 comments on commit 2dc7db9

Please sign in to comment.