Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic Fees - Introducing fees calculators #2619

Closed
wants to merge 12 commits into from
5 changes: 3 additions & 2 deletions vms/avm/block/executor/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ func (b *Block) Verify(context.Context) error {
// before performing any possible DB reads.
for _, tx := range txs {
err := tx.Unsigned.Visit(&executor.SyntacticVerifier{
Backend: b.manager.backend,
Tx: tx,
Backend: b.manager.backend,
BlkTimestamp: newChainTime,
Tx: tx,
})
if err != nil {
txID := tx.ID()
Expand Down
5 changes: 3 additions & 2 deletions vms/avm/block/executor/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@ func (m *manager) VerifyTx(tx *txs.Tx) error {
}

err := tx.Unsigned.Visit(&executor.SyntacticVerifier{
Backend: m.backend,
Tx: tx,
Backend: m.backend,
BlkTimestamp: m.state.GetTimestamp(),
Tx: tx,
})
if err != nil {
return err
Expand Down
11 changes: 7 additions & 4 deletions vms/avm/block/executor/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ func TestManagerVerifyTx(t *testing.T) {
Unsigned: unsigned,
}
},
managerF: func(*gomock.Controller) *manager {
managerF: func(ctrl *gomock.Controller) *manager {
state := state.NewMockState(ctrl)
state.EXPECT().GetTimestamp().Return(time.Time{})
return &manager{
backend: &executor.Backend{
Bootstrapped: true,
Expand All @@ -154,6 +156,7 @@ func TestManagerVerifyTx(t *testing.T) {
EUpgradeTime: mockable.MaxTime,
},
},
state: state,
}
},
expectedErr: errTestSyntacticVerifyFail,
Expand All @@ -176,7 +179,7 @@ func TestManagerVerifyTx(t *testing.T) {
// These values don't matter for this test
state := state.NewMockState(ctrl)
state.EXPECT().GetLastAccepted().Return(lastAcceptedID)
state.EXPECT().GetTimestamp().Return(time.Time{})
state.EXPECT().GetTimestamp().Return(time.Time{}).Times(2)

return &manager{
backend: &executor.Backend{
Expand Down Expand Up @@ -212,7 +215,7 @@ func TestManagerVerifyTx(t *testing.T) {
// These values don't matter for this test
state := state.NewMockState(ctrl)
state.EXPECT().GetLastAccepted().Return(lastAcceptedID)
state.EXPECT().GetTimestamp().Return(time.Time{})
state.EXPECT().GetTimestamp().Return(time.Time{}).Times(2)

return &manager{
backend: &executor.Backend{
Expand Down Expand Up @@ -248,7 +251,7 @@ func TestManagerVerifyTx(t *testing.T) {
// These values don't matter for this test
state := state.NewMockState(ctrl)
state.EXPECT().GetLastAccepted().Return(lastAcceptedID)
state.EXPECT().GetTimestamp().Return(time.Time{})
state.EXPECT().GetTimestamp().Return(time.Time{}).Times(2)

return &manager{
backend: &executor.Backend{
Expand Down
77 changes: 52 additions & 25 deletions vms/avm/txs/executor/semantic_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/vms/avm/state"
"github.com/ava-labs/avalanchego/vms/avm/txs"
"github.com/ava-labs/avalanchego/vms/avm/txs/fees"
"github.com/ava-labs/avalanchego/vms/components/avax"
"github.com/ava-labs/avalanchego/vms/components/verify"
)
Expand All @@ -31,36 +32,15 @@ type SemanticVerifier struct {
}

func (v *SemanticVerifier) BaseTx(tx *txs.BaseTx) error {
for i, in := range tx.Ins {
// Note: Verification of the length of [t.tx.Creds] happens during
// syntactic verification, which happens before semantic verification.
cred := v.Tx.Creds[i].Credential
if err := v.verifyTransfer(tx, in, cred); err != nil {
return err
}
}

for _, out := range tx.Outs {
fxIndex, err := v.getFx(out.Out)
if err != nil {
return err
}

assetID := out.AssetID()
if err := v.verifyFxUsage(fxIndex, assetID); err != nil {
return err
}
}

return nil
return v.verifyBaseTx(tx, nil, nil)
}

func (v *SemanticVerifier) CreateAssetTx(tx *txs.CreateAssetTx) error {
return v.BaseTx(&tx.BaseTx)
}

func (v *SemanticVerifier) OperationTx(tx *txs.OperationTx) error {
if err := v.BaseTx(&tx.BaseTx); err != nil {
if err := v.verifyBaseTx(&tx.BaseTx, nil, nil); err != nil {
return err
}

Expand All @@ -81,7 +61,7 @@ func (v *SemanticVerifier) OperationTx(tx *txs.OperationTx) error {
}

func (v *SemanticVerifier) ImportTx(tx *txs.ImportTx) error {
if err := v.BaseTx(&tx.BaseTx); err != nil {
if err := v.verifyBaseTx(&tx.BaseTx, tx.ImportedIns, nil); err != nil {
return err
}

Expand Down Expand Up @@ -122,7 +102,7 @@ func (v *SemanticVerifier) ImportTx(tx *txs.ImportTx) error {
}

func (v *SemanticVerifier) ExportTx(tx *txs.ExportTx) error {
if err := v.BaseTx(&tx.BaseTx); err != nil {
if err := v.verifyBaseTx(&tx.BaseTx, nil, tx.ExportedOuts); err != nil {
return err
}

Expand All @@ -146,6 +126,53 @@ func (v *SemanticVerifier) ExportTx(tx *txs.ExportTx) error {
return nil
}

func (v *SemanticVerifier) verifyBaseTx(
tx *txs.BaseTx,
importedIns []*avax.TransferableInput,
exportedOuts []*avax.TransferableOutput,
) error {
feeCalculator := fees.Calculator{
Config: v.Config,
}
if err := tx.Visit(&feeCalculator); err != nil {
return err
}

err := avax.VerifyTx(
feeCalculator.Fee,
v.FeeAssetID,
[][]*avax.TransferableInput{tx.Ins, importedIns},
[][]*avax.TransferableOutput{tx.Outs, exportedOuts},
v.Codec,
)
if err != nil {
return err
}

for i, in := range tx.Ins {
// Note: Verification of the length of [t.tx.Creds] happens during
// syntactic verification, which happens before semantic verification.
cred := v.Tx.Creds[i].Credential
if err := v.verifyTransfer(tx, in, cred); err != nil {
return err
}
}

for _, out := range tx.Outs {
fxIndex, err := v.getFx(out.Out)
if err != nil {
return err
}

assetID := out.AssetID()
if err := v.verifyFxUsage(fxIndex, assetID); err != nil {
return err
}
}

return nil
}

func (v *SemanticVerifier) verifyTransfer(
tx txs.UnsignedTx,
in *avax.TransferableInput,
Expand Down
66 changes: 3 additions & 63 deletions vms/avm/txs/executor/syntactic_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"errors"
"fmt"
"strings"
"time"
"unicode"

"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils"
"github.com/ava-labs/avalanchego/utils/set"
"github.com/ava-labs/avalanchego/vms/avm/txs"
"github.com/ava-labs/avalanchego/vms/components/avax"
)

const (
Expand Down Expand Up @@ -47,25 +47,15 @@ var (

type SyntacticVerifier struct {
*Backend
Tx *txs.Tx
BlkTimestamp time.Time
Tx *txs.Tx
}

func (v *SyntacticVerifier) BaseTx(tx *txs.BaseTx) error {
if err := tx.BaseTx.Verify(v.Ctx); err != nil {
return err
}

err := avax.VerifyTx(
v.Config.TxFee,
v.FeeAssetID,
[][]*avax.TransferableInput{tx.Ins},
[][]*avax.TransferableOutput{tx.Outs},
v.Codec,
)
if err != nil {
return err
}

for _, cred := range v.Tx.Creds {
if err := cred.Verify(); err != nil {
return err
Expand Down Expand Up @@ -118,17 +108,6 @@ func (v *SyntacticVerifier) CreateAssetTx(tx *txs.CreateAssetTx) error {
return err
}

err := avax.VerifyTx(
v.Config.CreateAssetTxFee,
v.FeeAssetID,
[][]*avax.TransferableInput{tx.Ins},
[][]*avax.TransferableOutput{tx.Outs},
v.Codec,
)
if err != nil {
return err
}

for _, state := range tx.States {
if err := state.Verify(v.Codec, len(v.Fxs)); err != nil {
return err
Expand Down Expand Up @@ -166,17 +145,6 @@ func (v *SyntacticVerifier) OperationTx(tx *txs.OperationTx) error {
return err
}

err := avax.VerifyTx(
v.Config.TxFee,
v.FeeAssetID,
[][]*avax.TransferableInput{tx.Ins},
[][]*avax.TransferableOutput{tx.Outs},
v.Codec,
)
if err != nil {
return err
}

inputs := set.NewSet[ids.ID](len(tx.Ins))
for _, in := range tx.Ins {
inputs.Add(in.InputID())
Expand Down Expand Up @@ -226,20 +194,6 @@ func (v *SyntacticVerifier) ImportTx(tx *txs.ImportTx) error {
return err
}

err := avax.VerifyTx(
v.Config.TxFee,
v.FeeAssetID,
[][]*avax.TransferableInput{
tx.Ins,
tx.ImportedIns,
},
[][]*avax.TransferableOutput{tx.Outs},
v.Codec,
)
if err != nil {
return err
}

for _, cred := range v.Tx.Creds {
if err := cred.Verify(); err != nil {
return err
Expand Down Expand Up @@ -268,20 +222,6 @@ func (v *SyntacticVerifier) ExportTx(tx *txs.ExportTx) error {
return err
}

err := avax.VerifyTx(
v.Config.TxFee,
v.FeeAssetID,
[][]*avax.TransferableInput{tx.Ins},
[][]*avax.TransferableOutput{
tx.Outs,
tx.ExportedOuts,
},
v.Codec,
)
if err != nil {
return err
}

for _, cred := range v.Tx.Creds {
if err := cred.Verify(); err != nil {
return err
Expand Down
Loading
Loading