Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:iotaledger/iota-core into feat/r…
Browse files Browse the repository at this point in the history
…eactive-chainmanager
  • Loading branch information
hmoog committed Oct 4, 2023
2 parents 8722a2f + ae3db7f commit 8ec344f
Show file tree
Hide file tree
Showing 39 changed files with 462 additions and 278 deletions.
70 changes: 70 additions & 0 deletions components/inx/server_issuance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package inx

import (
"context"

"github.com/iotaledger/hive.go/ierrors"
"github.com/iotaledger/hive.go/lo"
"github.com/iotaledger/hive.go/serializer/v2/serix"
inx "github.com/iotaledger/inx/go"
"github.com/iotaledger/iota-core/pkg/protocol/engine/mempool"
iotago "github.com/iotaledger/iota.go/v4"
)

func (s *Server) RequestTips(_ context.Context, req *inx.TipsRequest) (*inx.TipsResponse, error) {
references := deps.Protocol.MainEngineInstance().TipSelection.SelectTips(int(req.GetCount()))

return &inx.TipsResponse{
StrongTips: inx.NewBlockIds(references[iotago.StrongParentType]),
WeakTips: inx.NewBlockIds(references[iotago.WeakParentType]),
ShallowLikeTips: inx.NewBlockIds(references[iotago.ShallowLikeParentType]),
}, nil
}

func (s *Server) ValidatePayload(_ context.Context, payload *inx.RawPayload) (*inx.PayloadValidationResponse, error) {
if err := func() error {
blockPayload, unwrapErr := payload.Unwrap(deps.Protocol.CurrentAPI(), serix.WithValidation())
if unwrapErr != nil {
return unwrapErr
}

switch typedPayload := blockPayload.(type) {
case *iotago.SignedTransaction:
memPool := deps.Protocol.MainEngineInstance().Ledger.MemPool()

inputReferences, inputsErr := memPool.VM().Inputs(typedPayload.Transaction)
if inputsErr != nil {
return inputsErr
}

loadedInputs := make([]mempool.State, 0)
for _, inputReference := range inputReferences {
metadata, metadataErr := memPool.StateMetadata(inputReference)
if metadataErr != nil {
return metadataErr
}

loadedInputs = append(loadedInputs, metadata.State())
}

executionContext, validationErr := memPool.VM().ValidateSignatures(typedPayload, loadedInputs)
if validationErr != nil {
return validationErr
}

return lo.Return2(memPool.VM().Execute(executionContext, typedPayload.Transaction))

case *iotago.TaggedData:
// TaggedData is always valid if serix decoding was successful
return nil

default:
return ierrors.Errorf("unsupported payload type: %T", typedPayload)
}
}(); err != nil {
//nolint:nilerr // this is expected behavior
return &inx.PayloadValidationResponse{IsValid: false, Error: err.Error()}, nil
}

return &inx.PayloadValidationResponse{IsValid: true}, nil
}
18 changes: 0 additions & 18 deletions components/inx/server_tips.go

This file was deleted.

6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ require (
github.com/iotaledger/hive.go/runtime v0.0.0-20230929122509-67f34bfed40d
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20230929122509-67f34bfed40d
github.com/iotaledger/hive.go/stringify v0.0.0-20230929122509-67f34bfed40d
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20230927140518-622f63be6182
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20230927140257-bfa0bb0af2bd
github.com/iotaledger/iota.go/v4 v4.0.0-20231003101444-5687809cd68a
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231001095511-32be422a567e
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231001095356-923e8f138951
github.com/iotaledger/iota.go/v4 v4.0.0-20231003181920-a3245ad7a737
github.com/labstack/echo/v4 v4.11.1
github.com/labstack/gommon v0.4.0
github.com/libp2p/go-libp2p v0.30.0
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,12 @@ github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20230929122509-67f34bf
github.com/iotaledger/hive.go/serializer/v2 v2.0.0-rc.1.0.20230929122509-67f34bfed40d/go.mod h1:IJgaaxbgKCsNat18jlJJEAxCY2oVYR3F30B+M4vJ89I=
github.com/iotaledger/hive.go/stringify v0.0.0-20230929122509-67f34bfed40d h1:ekHWRypoaiCXgrJVUQS7rCewsK3FuG1gTbPxu5jYn9c=
github.com/iotaledger/hive.go/stringify v0.0.0-20230929122509-67f34bfed40d/go.mod h1:FTo/UWzNYgnQ082GI9QVM9HFDERqf9rw9RivNpqrnTs=
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20230927140518-622f63be6182 h1:lQiktl3Q0B+cHbVum7WzJikOEP+buw686oSrw5Unyz8=
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20230927140518-622f63be6182/go.mod h1:q24QEsS887ZWJVX76w2kwSgC84KS7wIKOy1otuqZ2ZM=
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20230927140257-bfa0bb0af2bd h1:nFG3Zq/zFA4KhBYFX2IezX1C74zfE0DqCt0LrgTa9Ig=
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20230927140257-bfa0bb0af2bd/go.mod h1:c5778OnWpLq108YE+Eb2m8Ri/t/4ydV0TvI/Sy5YivQ=
github.com/iotaledger/iota.go/v4 v4.0.0-20231003101444-5687809cd68a h1:xgh1YQvLN+Y3KwX1G9/znGbCaQsfpDtpSLn8nKvaP8s=
github.com/iotaledger/iota.go/v4 v4.0.0-20231003101444-5687809cd68a/go.mod h1:+e3bsJFDr9HxmUMe+eQOLNut5wfcB/ivhJdouOJgOnE=
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231001095511-32be422a567e h1:Mwoe7M6gI2DAjJIXmIskgnI8KdxCY1LyEEhtJCNYBsU=
github.com/iotaledger/inx-app v1.0.0-rc.3.0.20231001095511-32be422a567e/go.mod h1:jhzexR5X8m6qcmrwt5OX477O/ZwT7Ak9sPT83ByPkAo=
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231001095356-923e8f138951 h1:qUf1W0fE1IyZzVy3Exv0Kj+SKECXG3S26c9m2ETb07U=
github.com/iotaledger/inx/go v1.0.0-rc.2.0.20231001095356-923e8f138951/go.mod h1:c5778OnWpLq108YE+Eb2m8Ri/t/4ydV0TvI/Sy5YivQ=
github.com/iotaledger/iota.go/v4 v4.0.0-20231003181920-a3245ad7a737 h1:6fuDHswgN9zTwsMuKRKNClnT+rJCojvWf3Hk8f03cvc=
github.com/iotaledger/iota.go/v4 v4.0.0-20231003181920-a3245ad7a737/go.mod h1:+e3bsJFDr9HxmUMe+eQOLNut5wfcB/ivhJdouOJgOnE=
github.com/ipfs/boxo v0.10.0 h1:tdDAxq8jrsbRkYoF+5Rcqyeb91hgWe2hp7iLu7ORZLY=
github.com/ipfs/boxo v0.10.0/go.mod h1:Fg+BnfxZ0RPzR0nOodzdIq3A7KgoWAOWsEIImrIQdBM=
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
Expand Down
2 changes: 2 additions & 0 deletions pkg/protocol/engine/accounts/mana.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func NewMana(value iotago.Mana, excessBaseTokens iotago.BaseToken, updateTime io
}
}

// Update is applied when the account output is transitioned, updating the total value and excess base tokens.
func (m *Mana) Update(value iotago.Mana, excessBaseTokens iotago.BaseToken, updateTime iotago.SlotIndex) {
m.mutex.Lock()
defer m.mutex.Unlock()
Expand All @@ -31,6 +32,7 @@ func (m *Mana) Update(value iotago.Mana, excessBaseTokens iotago.BaseToken, upda
m.updateTime = updateTime
}

// UpdateValue is applied when the total decayed value is updated but the account output is not changed.
func (m *Mana) UpdateValue(value iotago.Mana, updateTime iotago.SlotIndex) {
m.mutex.Lock()
defer m.mutex.Unlock()
Expand Down
82 changes: 72 additions & 10 deletions pkg/protocol/engine/accounts/mana/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/iotaledger/hive.go/lo"
"github.com/iotaledger/hive.go/runtime/module"
"github.com/iotaledger/hive.go/runtime/syncutils"
"github.com/iotaledger/iota-core/pkg/model"
"github.com/iotaledger/iota-core/pkg/protocol/engine/accounts"
"github.com/iotaledger/iota-core/pkg/protocol/engine/utxoledger"
iotago "github.com/iotaledger/iota.go/v4"
Expand All @@ -24,15 +25,18 @@ type Manager struct {

accountOutputResolveFunc func(iotago.AccountID, iotago.SlotIndex) (*utxoledger.Output, error)

accountRetrieveFunc func(iotago.AccountID, iotago.SlotIndex) (*accounts.AccountData, bool, error)

mutex syncutils.Mutex

module.Module
}

func NewManager(apiProvider iotago.APIProvider, accountOutputResolveFunc func(iotago.AccountID, iotago.SlotIndex) (*utxoledger.Output, error)) *Manager {
func NewManager(apiProvider iotago.APIProvider, accountOutputResolveFunc func(iotago.AccountID, iotago.SlotIndex) (*utxoledger.Output, error), accountRetrieveFunc func(iotago.AccountID, iotago.SlotIndex) (*accounts.AccountData, bool, error)) *Manager {
return &Manager{
apiProvider: apiProvider,
accountOutputResolveFunc: accountOutputResolveFunc,
accountRetrieveFunc: accountRetrieveFunc,
manaVectorCache: cache.New[iotago.AccountID, *accounts.Mana](10000),
}
}
Expand All @@ -55,7 +59,17 @@ func (m *Manager) GetManaOnAccount(accountID iotago.AccountID, currentSlot iotag
if err != nil {
excessBaseTokens = 0
}
mana = accounts.NewMana(output.StoredMana(), excessBaseTokens, output.SlotCreated())

decayedBIC, err := m.getDecayedBIC(accountID, currentSlot)
if err != nil {
return 0, ierrors.Wrapf(err, "failed to get decayed BIC for %s", accountID)
}
totalMana, err := safemath.SafeAdd(output.StoredMana(), decayedBIC)
if err != nil {
return 0, ierrors.Wrapf(err, "overflow when adding stored mana and decayed BIC for account %s", accountID)
}

mana = accounts.NewMana(totalMana, excessBaseTokens, output.SlotCreated())

if !exists {
m.manaVectorCache.Put(accountID, mana)
Expand All @@ -67,7 +81,7 @@ func (m *Manager) GetManaOnAccount(accountID iotago.AccountID, currentSlot iotag
}

manaDecayProvider := m.apiProvider.CurrentAPI().ManaDecayProvider()
// apply decay to stored Mana and potential that was added on last update
// apply decay to stored, allotted and potential that was added on last update
manaStored, err := manaDecayProvider.ManaWithDecay(mana.Value(), mana.UpdateTime(), currentSlot)
if err != nil {
return 0, err
Expand All @@ -79,30 +93,78 @@ func (m *Manager) GetManaOnAccount(accountID iotago.AccountID, currentSlot iotag
if err != nil {
return 0, err
}
updatedValue += manaPotential
updatedValue, err = safemath.SafeAdd(updatedValue, manaPotential)
if err != nil {
return 0, ierrors.Wrapf(err, "overflow when adding stored and potential mana for account %s", accountID)
}

decayedBIC, err := m.getDecayedBIC(accountID, currentSlot)
if err != nil {
return 0, ierrors.Wrapf(err, "failed to get decayed BIC for %s", accountID)
}
updatedValue, err = safemath.SafeAdd(updatedValue, decayedBIC)
if err != nil {
return 0, ierrors.Wrapf(err, "overflow when adding stored, potential and decayed BIC for account %s", accountID)
}

mana.UpdateValue(updatedValue, currentSlot)

return mana.Value(), nil
}

func (m *Manager) ApplyDiff(slot iotago.SlotIndex, destroyedAccounts ds.Set[iotago.AccountID], accountOutputs map[iotago.AccountID]*utxoledger.Output) {
func (m *Manager) ApplyDiff(slot iotago.SlotIndex, destroyedAccounts ds.Set[iotago.AccountID], accountOutputs map[iotago.AccountID]*utxoledger.Output, accountDiffs map[iotago.AccountID]*model.AccountDiff) error {
m.mutex.Lock()
defer m.mutex.Unlock()

destroyedAccounts.Range(func(accountID iotago.AccountID) {
m.manaVectorCache.Remove(accountID)
})

for accountID, output := range accountOutputs {
for accountID := range accountDiffs {
mana, exists := m.manaVectorCache.Get(accountID)
if exists {
minDeposit := lo.PanicOnErr(m.apiProvider.CurrentAPI().RentStructure().MinDeposit(output.Output()))
excessBaseTokens, err := safemath.SafeSub(output.BaseTokenAmount(), minDeposit)
var excessBaseTokens iotago.BaseToken
var storedMana iotago.Mana
var err error
if output, has := accountOutputs[accountID]; has {
minDeposit := lo.PanicOnErr(m.apiProvider.CurrentAPI().RentStructure().MinDeposit(output.Output()))
excessBaseTokens, err = safemath.SafeSub(output.BaseTokenAmount(), minDeposit)
if err != nil {
excessBaseTokens = 0
}
storedMana = output.StoredMana()
}
decayedBIC, err := m.getDecayedBIC(accountID, slot)
if err != nil {
return err
}
totalMana, err := safemath.SafeAdd(decayedBIC, storedMana)
if err != nil {
excessBaseTokens = 0
return ierrors.Wrapf(err, "overflow when adding stored mana and decayed BIC for account %s", accountID)
}
mana.Update(output.StoredMana(), excessBaseTokens, slot)

mana.Update(totalMana, excessBaseTokens, slot)
}
}

return nil
}

func (m *Manager) getDecayedBIC(accountID iotago.AccountID, slot iotago.SlotIndex) (iotago.Mana, error) {
accountBIC, exists, err := m.accountRetrieveFunc(accountID, slot)
if err != nil {
return 0, ierrors.Wrapf(err, "failed to retrieve account data for %s in slot %s", accountID, slot)
}
if !exists {
return 0, ierrors.Errorf("account data for %s in slot %s does not exist", accountID, slot)
}
if accountBIC.Credits.Value <= 0 {
return 0, nil
}
decayedBIC, err := m.apiProvider.CurrentAPI().ManaDecayProvider().ManaWithDecay(iotago.Mana(accountBIC.Credits.Value), accountBIC.Credits.UpdateTime, slot)
if err != nil {
return 0, ierrors.Wrapf(err, "failed to apply mana decay for account %s", accountID)
}

return decayedBIC, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,9 @@ func NewProvider(opts ...options.Option[Scheduler]) module.Provider[*engine.Engi
return 0, err
}

minMana := s.apiProvider.CurrentAPI().ProtocolParameters().CongestionControlParameters().MinMana
if mana < minMana {
return 0, ierrors.Errorf("account %s has insufficient Mana for block to be scheduled: account Mana %d, min Mana %d", accountID, mana, minMana)
}
mana = lo.Min(mana, iotago.Mana(s.maxDeficit()-1))

return Deficit(mana / minMana), nil
return 1 + Deficit(mana), nil
}
})
s.TriggerConstructed()
Expand Down
18 changes: 10 additions & 8 deletions pkg/protocol/engine/ledger/ledger/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ func NewProvider() module.Provider[*engine.Engine, ledger.Ledger] {

l.setRetainTransactionFailureFunc(e.Retainer.RetainTransactionFailure)

l.memPool = mempoolv1.New(l.validateStardustTransaction, l.executeStardustVM, l.extractInputReferences, l.resolveState, e.Workers.CreateGroup("MemPool"), l.conflictDAG, e, l.errorHandler, mempoolv1.WithForkAllTransactions[ledger.BlockVoteRank](true))
l.memPool = mempoolv1.New(NewVM(l), l.resolveState, e.Workers.CreateGroup("MemPool"), l.conflictDAG, l.errorHandler, mempoolv1.WithForkAllTransactions[ledger.BlockVoteRank](true))
e.EvictionState.Events.SlotEvicted.Hook(l.memPool.Evict)

l.manaManager = mana.NewManager(l.apiProvider, l.resolveAccountOutput)
l.manaManager = mana.NewManager(l.apiProvider, l.resolveAccountOutput, l.accountsLedger.Account)
latestCommittedSlot := e.Storage.Settings().LatestCommitment().Slot()
l.accountsLedger.SetLatestCommittedSlot(latestCommittedSlot)
l.rmcManager.SetLatestCommittedSlot(latestCommittedSlot)
Expand Down Expand Up @@ -170,9 +170,6 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier,
l.prepareAccountDiffs(accountDiffs, slot, consumedAccounts, createdAccounts)

// Commit the changes
// Update the mana manager's cache
l.manaManager.ApplyDiff(slot, destroyedAccounts, createdAccounts)

// 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)
Expand All @@ -190,6 +187,11 @@ func (l *Ledger) CommitSlot(slot iotago.SlotIndex) (stateRoot iotago.Identifier,
return iotago.Identifier{}, iotago.Identifier{}, iotago.Identifier{}, 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)
}

// Mark each transaction as committed so the mempool can evict it
stateDiff.ExecutedTransactions().ForEach(func(_ iotago.TransactionID, tx mempool.TransactionMetadata) bool {
tx.Commit()
Expand Down Expand Up @@ -689,7 +691,7 @@ func (l *Ledger) resolveAccountOutput(accountID iotago.AccountID, slot iotago.Sl
return accountOutput, nil
}

func (l *Ledger) resolveState(stateRef iotago.Input) *promise.Promise[mempool.State] {
func (l *Ledger) resolveState(stateRef mempool.StateReference) *promise.Promise[mempool.State] {
p := promise.New[mempool.State]()

l.utxoLedger.ReadLockLedger()
Expand Down Expand Up @@ -725,8 +727,8 @@ func (l *Ledger) resolveState(stateRef iotago.Input) *promise.Promise[mempool.St

return p.Resolve(loadedCommitment)
case iotago.InputBlockIssuanceCredit, iotago.InputReward:
// these are always resolved as they depend on the commitment or UTXO inputs
return p.Resolve(stateRef)
//nolint:forcetypeassert
return p.Resolve(stateRef.(mempool.State))
default:
return p.Reject(ierrors.Errorf("unsupported input type %s", stateRef.Type()))
}
Expand Down
Loading

0 comments on commit 8ec344f

Please sign in to comment.