Skip to content

Commit

Permalink
Merge branch 'master' into disable-transform-subnet-tx
Browse files Browse the repository at this point in the history
  • Loading branch information
dhrubabasu authored Aug 5, 2024
2 parents 35101b4 + 1bcd544 commit e2b5360
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 5 deletions.
21 changes: 16 additions & 5 deletions tests/fixture/tmpnet/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ type Network struct {
// Path where network configuration and data is stored
Dir string

// Id of the network. If zero, must be set in Genesis.
// Id of the network. If zero, must be set in Genesis. Consider
// using the GetNetworkID method if needing to retrieve the ID of
// a running network.
NetworkID uint32

// Configuration common across nodes
Expand Down Expand Up @@ -562,10 +564,7 @@ func (n *Network) EnsureNodeConfig(node *Node) error {
node.NetworkOwner = n.Owner

// Set the network name if available
networkID := n.NetworkID
if networkID == 0 && n.Genesis != nil && n.Genesis.NetworkID > 0 {
networkID = n.Genesis.NetworkID
}
networkID := n.GetNetworkID()
if networkID > 0 {
// Convert the network id to a string to ensure consistency in JSON round-tripping.
flags[config.NetworkNameKey] = strconv.FormatUint(uint64(networkID), 10)
Expand Down Expand Up @@ -845,6 +844,18 @@ func (n *Network) getBootstrapIPsAndIDs(skippedNode *Node) ([]string, []string,
return bootstrapIPs, bootstrapIDs, nil
}

// GetNetworkID returns the effective ID of the network. If the network
// defines a genesis, the network ID in the genesis will be returned. If a
// genesis is not present (i.e. a network with a genesis included in the
// avalanchego binary - mainnet, testnet and local), the value of the
// NetworkID field will be returned
func (n *Network) GetNetworkID() uint32 {
if n.Genesis != nil && n.Genesis.NetworkID > 0 {
return n.Genesis.NetworkID
}
return n.NetworkID
}

// Waits until the provided nodes are healthy.
func waitForHealthy(ctx context.Context, w io.Writer, nodes []*Node) error {
ticker := time.NewTicker(networkHealthCheckInterval)
Expand Down
7 changes: 7 additions & 0 deletions vms/components/fee/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ type (
GasPrice uint64
)

// Cost converts the gas to nAVAX based on the price.
//
// If overflow would occur, an error is returned.
func (g Gas) Cost(price GasPrice) (uint64, error) {
return safemath.Mul(uint64(g), uint64(price))
}

// AddPerSecond returns g + gasPerSecond * seconds.
//
// If overflow would occur, MaxUint64 is returned.
Expand Down
13 changes: 13 additions & 0 deletions vms/components/fee/gas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ var gasPriceMulExpTests = []struct {
},
}

func Test_Gas_Cost(t *testing.T) {
require := require.New(t)

const (
gas Gas = 40
price GasPrice = 100
expected uint64 = 4000
)
actual, err := gas.Cost(price)
require.NoError(err)
require.Equal(expected, actual)
}

func Test_Gas_AddPerSecond(t *testing.T) {
tests := []struct {
initial Gas
Expand Down
27 changes: 27 additions & 0 deletions vms/platformvm/txs/fee/calculator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"github.com/ava-labs/avalanchego/vms/components/fee"
)

const testDynamicPrice = 100

var (
testStaticConfig = StaticConfig{
TxFee: 1 * units.Avax,
Expand All @@ -19,6 +21,12 @@ var (
AddSubnetValidatorFee: 7 * units.Avax,
AddSubnetDelegatorFee: 8 * units.Avax,
}
testDynamicWeights = fee.Dimensions{
fee.Bandwidth: 1,
fee.DBRead: 200,
fee.DBWrite: 300,
fee.Compute: 0, // TODO: Populate
}

// TODO: Rather than hardcoding transactions, consider implementing and
// using a transaction generator.
Expand All @@ -29,30 +37,36 @@ var (
expectedStaticFeeErr error
expectedComplexity fee.Dimensions
expectedComplexityErr error
expectedDynamicFee uint64
expectedDynamicFeeErr error
}{
{
name: "AdvanceTimeTx",
tx: "0000000000130000000066a56fe700000000",
expectedStaticFeeErr: ErrUnsupportedTx,
expectedComplexityErr: ErrUnsupportedTx,
expectedDynamicFeeErr: ErrUnsupportedTx,
},
{
name: "RewardValidatorTx",
tx: "0000000000143d0ad12b8ee8928edf248ca91ca55600fb383f07c32bff1d6dec472b25cf59a700000000",
expectedStaticFeeErr: ErrUnsupportedTx,
expectedComplexityErr: ErrUnsupportedTx,
expectedDynamicFeeErr: ErrUnsupportedTx,
},
{
name: "AddValidatorTx",
tx: "00000000000c0000000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000f4b21e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000015000000006134088000000005000001d1a94a200000000001000000000000000400000000b3da694c70b8bee4478051313621c3f2282088b4000000005f6976d500000000614aaa19000001d1a94a20000000000121e67317cbc4be2aeb00677ad6462778a8f52274b9d605df2591b23027a87dff00000016000000006134088000000007000001d1a94a20000000000000000000000000010000000120868ed5ac611711b33d2e4f97085347415db1c40000000b0000000000000000000000010000000120868ed5ac611711b33d2e4f97085347415db1c400009c40000000010000000900000001620513952dd17c8726d52e9e621618cb38f09fd194abb4cd7b4ee35ecd10880a562ad968dc81a89beab4e87d88d5d582aa73d0d265c87892d1ffff1f6e00f0ef00",
expectedStaticFee: testStaticConfig.AddPrimaryNetworkValidatorFee,
expectedComplexityErr: ErrUnsupportedTx,
expectedDynamicFeeErr: ErrUnsupportedTx,
},
{
name: "AddDelegatorTx",
tx: "00000000000e000000050000000000000000000000000000000000000000000000000000000000000000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000000003b9aca0000000000000000000000000100000001f887b4c7030e95d2495603ae5d8b14cc0a66781a000000011767be999a49ca24fe705de032fa613b682493110fd6468ae7fb56bde1b9d729000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000000012a05f20000000001000000000000000400000000c51c552c49174e2e18b392049d3e4cd48b11490f000000005f692452000000005f73b05200000000ee6b2800000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000700000000ee6b280000000000000000000000000100000001e0cfe8cae22827d032805ded484e393ce51cbedb0000000b00000000000000000000000100000001e0cfe8cae22827d032805ded484e393ce51cbedb00000001000000090000000135cd78758035ed528d230317e5d880083a86a2b68c4a95655571828fe226548f235031c8dabd1fe06366a57613c4370ac26c4c59d1a1c46287a59906ec41b88f00",
expectedStaticFee: testStaticConfig.AddPrimaryNetworkDelegatorFee,
expectedComplexityErr: ErrUnsupportedTx,
expectedDynamicFeeErr: ErrUnsupportedTx,
},
{
name: "AddPermissionlessValidatorTx for primary network",
Expand All @@ -64,6 +78,7 @@ var (
fee.DBWrite: IntrinsicAddPermissionlessValidatorTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + 2*intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 229_100,
},
{
name: "AddPermissionlessValidatorTx for subnet",
Expand All @@ -75,6 +90,7 @@ var (
fee.DBWrite: IntrinsicAddPermissionlessValidatorTxComplexities[fee.DBWrite] + 2*intrinsicInputDBWrite + 3*intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 314_800,
},
{
name: "AddPermissionlessDelegatorTx for primary network",
Expand All @@ -86,6 +102,7 @@ var (
fee.DBWrite: IntrinsicAddPermissionlessDelegatorTxComplexities[fee.DBWrite] + 1*intrinsicInputDBWrite + 2*intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 209_900,
},
{
name: "AddPermissionlessDelegatorTx for subnet",
Expand All @@ -97,6 +114,7 @@ var (
fee.DBWrite: IntrinsicAddPermissionlessDelegatorTxComplexities[fee.DBWrite] + 2*intrinsicInputDBWrite + 3*intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 312_000,
},
{
name: "AddSubnetValidatorTx",
Expand All @@ -108,6 +126,7 @@ var (
fee.DBWrite: IntrinsicAddSubnetValidatorTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 196_000,
},
{
name: "BaseTx",
Expand All @@ -119,6 +138,7 @@ var (
fee.DBWrite: IntrinsicBaseTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + 2*intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 149_900,
},
{
name: "CreateChainTx",
Expand All @@ -130,6 +150,7 @@ var (
fee.DBWrite: IntrinsicCreateChainTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 180_900,
},
{
name: "CreateSubnetTx",
Expand All @@ -141,6 +162,7 @@ var (
fee.DBWrite: IntrinsicCreateSubnetTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 143_900,
},
{
name: "ExportTx",
Expand All @@ -152,6 +174,7 @@ var (
fee.DBWrite: IntrinsicExportTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + 2*intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 153_500,
},
{
name: "ImportTx",
Expand All @@ -163,6 +186,7 @@ var (
fee.DBWrite: IntrinsicImportTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 113_500,
},
{
name: "RemoveSubnetValidatorTx",
Expand All @@ -174,12 +198,14 @@ var (
fee.DBWrite: IntrinsicRemoveSubnetValidatorTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 193_600,
},
{
name: "TransformSubnetTx",
tx: "000000000018000030390000000000000000000000000000000000000000000000000000000000000000000000022f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000007000000000000609b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29cdbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000007002386f263c5fbc0000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000294a113f31a30ee643288277574434f9066e0cdc1d53d6eb2610805c388814134000000002f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a00000005000000000000c137000000010000000094a113f31a30ee643288277574434f9066e0cdc1d53d6eb2610805c38881413400000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db00000005002386f269bbdcc000000001000000000000000097ea88082100491617204ed70c19fc1a2fce4474bee962904359d0b59e84c1242f6399f3e626fe1e75f9daa5e726cb64b7bfec0b6e6d8930eaa9dfa336edca7a000000000000609b000000000000c1370000000000000001000000000000000a0000000000000001000000000000006400127500001fa40000000001000000000000000a64000000010000000a00000001000000000000000300000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca820000000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca820000000009000000015c640ddd6afc7d8059ef54663654d74f0c56cc1ed0b974d401171cdae0b29be67f3223e299d3e5e7c492ef4c7110ddf44d672bd698c42947bfb15ab750f0ca8200",
expectedStaticFee: testStaticConfig.TransformSubnetTxFee,
expectedComplexityErr: ErrUnsupportedTx,
expectedDynamicFeeErr: ErrUnsupportedTx,
},
{
name: "TransferSubnetOwnershipTx",
Expand All @@ -191,6 +217,7 @@ var (
fee.DBWrite: IntrinsicTransferSubnetOwnershipTxComplexities[fee.DBWrite] + intrinsicInputDBWrite + intrinsicOutputDBWrite,
fee.Compute: 0, // TODO: implement
},
expectedDynamicFee: 173_600,
},
}
)
38 changes: 38 additions & 0 deletions vms/platformvm/txs/fee/dynamic_calculator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package fee

import (
"github.com/ava-labs/avalanchego/vms/components/fee"
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
)

var _ Calculator = (*dynamicCalculator)(nil)

func NewDynamicCalculator(
weights fee.Dimensions,
price fee.GasPrice,
) Calculator {
return &dynamicCalculator{
weights: weights,
price: price,
}
}

type dynamicCalculator struct {
weights fee.Dimensions
price fee.GasPrice
}

func (c *dynamicCalculator) CalculateFee(tx txs.UnsignedTx) (uint64, error) {
complexity, err := TxComplexity(tx)
if err != nil {
return 0, err
}
gas, err := complexity.ToGas(c.weights)
if err != nil {
return 0, err
}
return gas.Cost(c.price)
}
32 changes: 32 additions & 0 deletions vms/platformvm/txs/fee/dynamic_calculator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package fee

import (
"encoding/hex"
"testing"

"github.com/stretchr/testify/require"

"github.com/ava-labs/avalanchego/vms/platformvm/txs"
)

func TestDynamicCalculator(t *testing.T) {
calculator := NewDynamicCalculator(testDynamicWeights, testDynamicPrice)
for _, test := range txTests {
t.Run(test.name, func(t *testing.T) {
require := require.New(t)

txBytes, err := hex.DecodeString(test.tx)
require.NoError(err)

tx, err := txs.Parse(txs.Codec, txBytes)
require.NoError(err)

fee, err := calculator.CalculateFee(tx.Unsigned)
require.Equal(int(test.expectedDynamicFee), int(fee))
require.ErrorIs(err, test.expectedDynamicFeeErr)
})
}
}

0 comments on commit e2b5360

Please sign in to comment.