Skip to content

Commit

Permalink
Properly track newly created accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
alexsporn committed Jun 4, 2024
1 parent d30796c commit 40256f0
Showing 1 changed file with 22 additions and 16 deletions.
38 changes: 22 additions & 16 deletions pkg/protocol/engine/ledger/ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier,
// account changes at UTXO level without needing to worry about multiple spenders of the same account in the same slot,
// we only care about the initial account output to be consumed and the final account output to be created.
// output side
createdAccounts, consumedAccounts, destroyedAccounts, err := l.processCreatedAndConsumedAccountOutputs(stateDiff, accountDiffs)
createdAccountOutputs, consumedAccountOutputs, createdAccounts, destroyedAccounts, err := l.processCreatedAndConsumedAccountOutputs(stateDiff, accountDiffs)
if err != nil {
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, nil, nil, nil, ierrors.Wrapf(err, "failed to process outputs consumed and created in slot %d", slot)
}
Expand All @@ -181,7 +181,8 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier,

return nil
})
l.prepareAccountDiffs(accountDiffs, slot, consumedAccounts, createdAccounts)

l.prepareAccountDiffs(accountDiffs, slot, consumedAccountOutputs, createdAccountOutputs)

// Commit the changes
// Update the UTXO ledger
Expand All @@ -206,15 +207,17 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier,
}

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

// Created account event need to be triggered only after the AccountLedger and UTXO ledger are updated,
// so that components (like Scheduler) that listen to the event can access the consistent account state.
for accountID := range createdAccounts {
_ = createdAccounts.ForEach(func(accountID iotago.AccountID) error {
l.events.AccountCreated.Trigger(accountID)
}

return nil
})

// Mark each transaction as committed so the mempool can evict it
stateDiff.ExecutedTransactions().ForEach(func(_ iotago.TransactionID, tx mempool.TransactionMetadata) bool {
Expand Down Expand Up @@ -509,9 +512,10 @@ func (l *Ledger) prepareAccountDiffs(accountDiffs map[iotago.AccountID]*model.Ac
}
}

func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.StateDiff, accountDiffs map[iotago.AccountID]*model.AccountDiff) (createdAccounts map[iotago.AccountID]*utxoledger.Output, consumedAccounts map[iotago.AccountID]*utxoledger.Output, destroyedAccounts ds.Set[iotago.AccountID], err error) {
createdAccounts = make(map[iotago.AccountID]*utxoledger.Output)
consumedAccounts = make(map[iotago.AccountID]*utxoledger.Output)
func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.StateDiff, accountDiffs map[iotago.AccountID]*model.AccountDiff) (createdAccountOutputs map[iotago.AccountID]*utxoledger.Output, consumedAccountOutputs map[iotago.AccountID]*utxoledger.Output, createdAccounts ds.Set[iotago.AccountID], destroyedAccounts ds.Set[iotago.AccountID], err error) {
createdAccountOutputs = make(map[iotago.AccountID]*utxoledger.Output)
consumedAccountOutputs = make(map[iotago.AccountID]*utxoledger.Output)
createdAccounts = ds.NewSet[iotago.AccountID]()
destroyedAccounts = ds.NewSet[iotago.AccountID]()

newAccountDelegation := make(map[iotago.ChainID]*iotago.DelegationOutput)
Expand All @@ -536,9 +540,10 @@ func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.State
accountID := createdAccount.AccountID
if accountID.Empty() {
accountID = iotago.AccountIDFromOutputID(createdOutput.OutputID())
createdAccounts.Add(accountID)
}

createdAccounts[accountID] = createdOutput
createdAccountOutputs[accountID] = createdOutput
case iotago.OutputDelegation:
delegationOutput, _ := createdOutput.Output().(*iotago.DelegationOutput)
delegationID := delegationOutput.DelegationID
Expand All @@ -554,15 +559,16 @@ func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.State
// if a basic output is sent to an implicit account creation address, we need to create the account
if createdOutput.Output().UnlockConditionSet().Address().Address.Type() == iotago.AddressImplicitAccountCreation {
accountID := iotago.AccountIDFromOutputID(createdOutput.OutputID())
createdAccounts[accountID] = createdOutput
createdAccounts.Add(accountID)
createdAccountOutputs[accountID] = createdOutput
}
}

return true
})

if err != nil {
return nil, nil, nil, ierrors.Wrap(err, "error while processing created states")
return nil, nil, nil, nil, ierrors.Wrap(err, "error while processing created states")
}

// input side
Expand All @@ -585,10 +591,10 @@ func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.State
if consumedAccount.FeatureSet().BlockIssuer() == nil && consumedAccount.FeatureSet().Staking() == nil {
return true
}
consumedAccounts[accountID] = spentOutput
consumedAccountOutputs[accountID] = spentOutput

// if we have consumed accounts that are not created in the same slot, we need to track them as destroyed
if _, exists := createdAccounts[accountID]; !exists {
if _, exists := createdAccountOutputs[accountID]; !exists {
destroyedAccounts.Add(accountID)
}

Expand All @@ -606,7 +612,7 @@ func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.State
// if a basic output (implicit account) is consumed, get the accountID as hash of the output ID.
if spentOutput.Output().UnlockConditionSet().Address().Address.Type() == iotago.AddressImplicitAccountCreation {
accountID := iotago.AccountIDFromOutputID(spentOutput.OutputID())
consumedAccounts[accountID] = spentOutput
consumedAccountOutputs[accountID] = spentOutput
}
}

Expand All @@ -620,10 +626,10 @@ func (l *Ledger) processCreatedAndConsumedAccountOutputs(stateDiff mempool.State
}

if err != nil {
return nil, nil, nil, ierrors.Wrap(err, "error while processing created states")
return nil, nil, nil, nil, ierrors.Wrap(err, "error while processing created states")
}

return createdAccounts, consumedAccounts, destroyedAccounts, nil
return createdAccountOutputs, consumedAccountOutputs, createdAccounts, destroyedAccounts, nil
}

func (l *Ledger) processStateDiffTransactions(stateDiff mempool.StateDiff) (spents utxoledger.Spents, outputs utxoledger.Outputs, accountDiffs map[iotago.AccountID]*model.AccountDiff, err error) {
Expand Down

0 comments on commit 40256f0

Please sign in to comment.