From c1f5fb251f24cfe1ed40b11c9cc0be298687bd37 Mon Sep 17 00:00:00 2001 From: Meaghan FitzGerald Date: Tue, 23 Jul 2024 19:21:37 -0400 Subject: [PATCH 01/15] typo (#3220) Signed-off-by: Meaghan FitzGerald --- vms/platformvm/warp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/platformvm/warp/README.md b/vms/platformvm/warp/README.md index a21861bc7245..4365a08bc0b1 100644 --- a/vms/platformvm/warp/README.md +++ b/vms/platformvm/warp/README.md @@ -88,7 +88,7 @@ Once the validator set of a blockchain is willing to sign an arbitrary message ` ## Verifying / Receiving an Avalanche Warp Message -Avalanache Warp Messages are verified within the context of a specific P-Chain height included in the [ProposerVM](../../proposervm/README.md)'s header. The P-Chain height is provided as context to the underlying VM when verifying the underlying VM's blocks (implemented by the optional interface [WithVerifyContext](../../../snow/engine/snowman/block/block_context_vm.go)). +Avalanche Warp Messages are verified within the context of a specific P-Chain height included in the [ProposerVM](../../proposervm/README.md)'s header. The P-Chain height is provided as context to the underlying VM when verifying the underlying VM's blocks (implemented by the optional interface [WithVerifyContext](../../../snow/engine/snowman/block/block_context_vm.go)). To verify the message, the underlying VM utilizes this `warp` package to perform the following steps: From f6701a7f838c5ed1e479539677990576d8d12425 Mon Sep 17 00:00:00 2001 From: felipemadero Date: Wed, 24 Jul 2024 12:34:40 -0300 Subject: [PATCH 02/15] add getSubnet to p-chain api reference (#3204) Signed-off-by: felipemadero Co-authored-by: Stephen Buttolph --- vms/platformvm/service.md | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/vms/platformvm/service.md b/vms/platformvm/service.md index b6005a8f1569..caa040103533 100644 --- a/vms/platformvm/service.md +++ b/vms/platformvm/service.md @@ -1202,6 +1202,60 @@ Testnet: U8iRqJoiJm8xZHAacmvYyZVwqQx6uDNtQeP3CQ6fcgQk3JqnK ::: +### `platform.getSubnet` + +Get owners and elastic info about the Subnet. + +**Signature:** + +```sh +platform.getSubnet({ + subnetID: string +}) -> +{ + isPermissioned: bool, + controlKeys: []string, + threshold: string, + locktime: string, + subnetTransformationTxID: string +} +``` + +- `subnetID` is the ID of the Subnet to get information about. If omitted, fails. +- `threshold` signatures from addresses in `controlKeys` are needed to make changes to + a permissioned subnet. If the Subnet is a PoS Subnet, then `threshold` will be `0` and `controlKeys` + will be empty. +- changes can not be made into the subnet until `locktime` is in the past. +- `subnetTransformationTxID` is the ID of the transaction that changed the subnet into a elastic one, + for when this change was performed. + +**Example Call:** + +```sh +curl -X POST --data '{ + "jsonrpc": "2.0", + "method": "platform.getSubnet", + "params": {"subnetID":"Vz2ArUpigHt7fyE79uF3gAXvTPLJi2LGgZoMpgNPHowUZJxBb"}, + "id": 1 +}' -H 'content-type:application/json;' 127.0.0.1:9650/ext/bc/P +``` + +**Example Response:** + +```json +{ + "jsonrpc": "2.0", + "result": { + "isPermissioned": true, + "controlKeys": ["P-fuji1ztvstx6naeg6aarfd047fzppdt8v4gsah88e0c","P-fuji193kvt4grqewv6ce2x59wnhydr88xwdgfcedyr3"], + "threshold": "1", + "locktime": "0", + "subnetTransformationTxID": "11111111111111111111111111111111LpoYY" + }, + "id": 1 +} +``` + ### `platform.getSubnets` :::caution From 0bf042fb73f1fe3a44ddeaf0a97f4fbcc0812ca1 Mon Sep 17 00:00:00 2001 From: marun Date: Wed, 24 Jul 2024 11:48:52 -0700 Subject: [PATCH 03/15] [ci] Update fuzz workflows to target master branch (#3221) --- .github/workflows/fuzz.yml | 4 +--- .github/workflows/fuzz_merkledb.yml | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index abc4f141ef3c..ef6deedfe840 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -2,7 +2,7 @@ name: Run fuzz tests on: schedule: - - cron: "0 0 * * *" + - cron: "0 0 * * *" # Once a day at midnight UTC permissions: contents: read @@ -13,8 +13,6 @@ jobs: steps: - name: Git checkout uses: actions/checkout@v4 - with: - ref: 'dev' - name: Set up Go uses: ./.github/actions/setup-go-for-project - name: Run fuzz tests diff --git a/.github/workflows/fuzz_merkledb.yml b/.github/workflows/fuzz_merkledb.yml index 1b331f0cfad6..8019b449068c 100644 --- a/.github/workflows/fuzz_merkledb.yml +++ b/.github/workflows/fuzz_merkledb.yml @@ -15,8 +15,6 @@ jobs: steps: - name: Git checkout uses: actions/checkout@v4 - with: - ref: 'dev' - name: Set up Go uses: ./.github/actions/setup-go-for-project - name: Run merkledb fuzz tests From 1b4c6328aaf31d45d4d7a7ccf3048d9b278260e3 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 24 Jul 2024 16:16:40 -0400 Subject: [PATCH 04/15] Cleanup wallet tests (#3230) --- wallet/chain/p/builder_test.go | 282 +++++++++++++++++++-------------- 1 file changed, 165 insertions(+), 117 deletions(-) diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 9f73b9e399b9..80164f052942 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -67,7 +67,7 @@ func TestBaseTx(t *testing.T) { builder = builder.New(set.Of(utxoAddr), testContext, backend) // data to build the transaction - outputsToMove = []*avax.TransferableOutput{{ + outputToMove = &avax.TransferableOutput{ Asset: avax.Asset{ID: avaxAssetID}, Out: &secp256k1fx.TransferOutput{ Amt: 7 * units.Avax, @@ -76,22 +76,25 @@ func TestBaseTx(t *testing.T) { Addrs: []ids.ShortID{utxoAddr}, }, }, - }} + } ) - utx, err := builder.NewBaseTx(outputsToMove) + utx, err := builder.NewBaseTx([]*avax.TransferableOutput{outputToMove}) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 2) - require.Len(outs, 2) + // check that the output is included in the transaction + require.Contains(utx.Outs, outputToMove) - expectedConsumed := testContext.BaseTxFee + outputsToMove[0].Out.Amount() - consumed := ins[0].In.Amount() + ins[1].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) - require.Equal(outputsToMove[0], outs[1]) + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs), + map[ids.ID]uint64{ + avaxAssetID: testContext.BaseTxFee, + }, + ), + addInputAmounts(utx.Ins), + ) } func TestAddSubnetValidatorTx(t *testing.T) { @@ -140,15 +143,16 @@ func TestAddSubnetValidatorTx(t *testing.T) { utx, err := builder.NewAddSubnetValidatorTx(subnetValidator) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 2) - require.Len(outs, 1) - - expectedConsumed := testContext.AddSubnetValidatorFee - consumed := ins[0].In.Amount() + ins[1].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs), + map[ids.ID]uint64{ + avaxAssetID: testContext.AddSubnetValidatorFee, + }, + ), + addInputAmounts(utx.Ins), + ) } func TestRemoveSubnetValidatorTx(t *testing.T) { @@ -191,15 +195,16 @@ func TestRemoveSubnetValidatorTx(t *testing.T) { ) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 1) - require.Len(outs, 1) - - expectedConsumed := testContext.BaseTxFee - consumed := ins[0].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs), + map[ids.ID]uint64{ + avaxAssetID: testContext.BaseTxFee, + }, + ), + addInputAmounts(utx.Ins), + ) } func TestCreateChainTx(t *testing.T) { @@ -250,15 +255,16 @@ func TestCreateChainTx(t *testing.T) { ) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 1) - require.Len(outs, 1) - - expectedConsumed := testContext.CreateBlockchainTxFee - consumed := ins[0].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs), + map[ids.ID]uint64{ + avaxAssetID: testContext.CreateBlockchainTxFee, + }, + ), + addInputAmounts(utx.Ins), + ) } func TestCreateSubnetTx(t *testing.T) { @@ -298,15 +304,16 @@ func TestCreateSubnetTx(t *testing.T) { utx, err := builder.NewCreateSubnetTx(subnetOwner) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 1) - require.Len(outs, 1) - - expectedConsumed := testContext.CreateSubnetTxFee - consumed := ins[0].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs), + map[ids.ID]uint64{ + avaxAssetID: testContext.CreateSubnetTxFee, + }, + ), + addInputAmounts(utx.Ins), + ) } func TestTransferSubnetOwnershipTx(t *testing.T) { @@ -349,15 +356,16 @@ func TestTransferSubnetOwnershipTx(t *testing.T) { ) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 1) - require.Len(outs, 1) - - expectedConsumed := testContext.BaseTxFee - consumed := ins[0].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs), + map[ids.ID]uint64{ + avaxAssetID: testContext.BaseTxFee, + }, + ), + addInputAmounts(utx.Ins), + ) } func TestImportTx(t *testing.T) { @@ -397,17 +405,18 @@ func TestImportTx(t *testing.T) { ) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - outs := utx.Outs - importedIns := utx.ImportedInputs - require.Empty(ins) // we spend the imported input (at least partially) - require.Len(importedIns, 1) - require.Len(outs, 1) - - expectedConsumed := testContext.BaseTxFee - consumed := importedIns[0].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) + require.Empty(utx.Ins) // we spend the imported input (at least partially) + + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs), + map[ids.ID]uint64{ + avaxAssetID: testContext.BaseTxFee, + }, + ), + addInputAmounts(utx.Ins, utx.ImportedInputs), + ) } func TestExportTx(t *testing.T) { @@ -447,16 +456,18 @@ func TestExportTx(t *testing.T) { ) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 2) - require.Len(outs, 1) - - expectedConsumed := testContext.BaseTxFee + exportedOutputs[0].Out.Amount() - consumed := ins[0].In.Amount() + ins[1].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) require.Equal(utx.ExportedOutputs, exportedOutputs) + + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs, utx.ExportedOutputs), + map[ids.ID]uint64{ + avaxAssetID: testContext.BaseTxFee, + }, + ), + addInputAmounts(utx.Ins), + ) } func TestTransformSubnetTx(t *testing.T) { @@ -515,18 +526,17 @@ func TestTransformSubnetTx(t *testing.T) { ) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - outs := utx.Outs - require.Len(ins, 2) - require.Len(outs, 2) - - expectedConsumedSubnetAsset := maxSupply - initialSupply - consumedSubnetAsset := ins[0].In.Amount() - outs[1].Out.Amount() - require.Equal(expectedConsumedSubnetAsset, consumedSubnetAsset) - expectedConsumed := testContext.TransformSubnetTxFee - consumed := ins[1].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs), + map[ids.ID]uint64{ + avaxAssetID: testContext.TransformSubnetTxFee, + subnetAssetID: maxSupply - initialSupply, + }, + ), + addInputAmounts(utx.Ins), + ) } func TestAddPermissionlessValidatorTx(t *testing.T) { @@ -583,20 +593,24 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { ) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - staked := utx.StakeOuts - outs := utx.Outs - require.Len(ins, 4) - require.Len(staked, 2) - require.Len(outs, 2) - - expectedConsumedSubnetAsset := utx.Validator.Weight() - consumedSubnetAsset := staked[0].Out.Amount() + staked[1].Out.Amount() - require.Equal(expectedConsumedSubnetAsset, consumedSubnetAsset) - expectedConsumed := testContext.AddPrimaryNetworkValidatorFee - consumed := ins[1].In.Amount() + ins[3].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) + // check stake amount + require.Equal( + map[ids.ID]uint64{ + avaxAssetID: 2 * units.Avax, + }, + addOutputAmounts(utx.StakeOuts), + ) + + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs, utx.StakeOuts), + map[ids.ID]uint64{ + avaxAssetID: testContext.AddPrimaryNetworkValidatorFee, + }, + ), + addInputAmounts(utx.Ins), + ) } func TestAddPermissionlessDelegatorTx(t *testing.T) { @@ -641,20 +655,24 @@ func TestAddPermissionlessDelegatorTx(t *testing.T) { ) require.NoError(err) - // check UTXOs selection and fee financing - ins := utx.Ins - staked := utx.StakeOuts - outs := utx.Outs - require.Len(ins, 4) - require.Len(staked, 2) - require.Len(outs, 2) - - expectedConsumedSubnetAsset := utx.Validator.Weight() - consumedSubnetAsset := staked[0].Out.Amount() + staked[1].Out.Amount() - require.Equal(expectedConsumedSubnetAsset, consumedSubnetAsset) - expectedConsumed := testContext.AddPrimaryNetworkDelegatorFee - consumed := ins[1].In.Amount() + ins[3].In.Amount() - outs[0].Out.Amount() - require.Equal(expectedConsumed, consumed) + // check stake amount + require.Equal( + map[ids.ID]uint64{ + avaxAssetID: 2 * units.Avax, + }, + addOutputAmounts(utx.StakeOuts), + ) + + // check fee calculation + require.Equal( + addAmounts( + addOutputAmounts(utx.Outs, utx.StakeOuts), + map[ids.ID]uint64{ + avaxAssetID: testContext.AddPrimaryNetworkDelegatorFee, + }, + ), + addInputAmounts(utx.Ins), + ) } func makeTestUTXOs(utxosKey *secp256k1.PrivateKey) []*avax.UTXO { @@ -745,3 +763,33 @@ func makeTestUTXOs(utxosKey *secp256k1.PrivateKey) []*avax.UTXO { }, } } + +func addAmounts(allAmounts ...map[ids.ID]uint64) map[ids.ID]uint64 { + amounts := make(map[ids.ID]uint64) + for _, amountsToAdd := range allAmounts { + for assetID, amount := range amountsToAdd { + amounts[assetID] += amount + } + } + return amounts +} + +func addInputAmounts(inputSlices ...[]*avax.TransferableInput) map[ids.ID]uint64 { + consumed := make(map[ids.ID]uint64) + for _, inputs := range inputSlices { + for _, in := range inputs { + consumed[in.AssetID()] += in.In.Amount() + } + } + return consumed +} + +func addOutputAmounts(outputSlices ...[]*avax.TransferableOutput) map[ids.ID]uint64 { + produced := make(map[ids.ID]uint64) + for _, outputs := range outputSlices { + for _, out := range outputs { + produced[out.AssetID()] += out.Out.Amount() + } + } + return produced +} From 57fb839459554d521606f2d1e974a7ea1e4ca065 Mon Sep 17 00:00:00 2001 From: Ceyhun Onur Date: Thu, 25 Jul 2024 17:16:36 +0300 Subject: [PATCH 05/15] Update local validator start time (#3224) Co-authored-by: Stephen Buttolph --- genesis/config.go | 38 +++++++++++++++++++++- genesis/config_test.go | 66 ++++++++++++++++++++++++++++++++++++++ genesis/genesis_local.json | 4 +-- genesis/genesis_test.go | 15 ++++----- 4 files changed, 112 insertions(+), 11 deletions(-) diff --git a/genesis/config.go b/genesis/config.go index de7d88f2f693..4ecd5f53b12a 100644 --- a/genesis/config.go +++ b/genesis/config.go @@ -12,6 +12,7 @@ import ( "fmt" "os" "path/filepath" + "time" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils" @@ -21,6 +22,8 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/signer" ) +const localNetworkUpdateStartTimePeriod = 9 * 30 * 24 * time.Hour // 9 months + var ( _ utils.Sortable[Allocation] = Allocation{} @@ -170,6 +173,10 @@ var ( // LocalConfig is the config that should be used to generate a local // genesis. LocalConfig Config + + // unmodifiedLocalConfig is the LocalConfig before advancing the StartTime + // to a recent value. + unmodifiedLocalConfig Config ) func init() { @@ -196,10 +203,21 @@ func init() { panic(err) } - LocalConfig, err = unparsedLocalConfig.Parse() + unmodifiedLocalConfig, err = unparsedLocalConfig.Parse() if err != nil { panic(err) } + + // Renew the staking start time of the local config if required + definedStartTime := time.Unix(int64(unmodifiedLocalConfig.StartTime), 0) + recentStartTime := getRecentStartTime( + definedStartTime, + time.Now(), + localNetworkUpdateStartTimePeriod, + ) + + LocalConfig = unmodifiedLocalConfig + LocalConfig.StartTime = uint64(recentStartTime.Unix()) } func GetConfig(networkID uint32) *Config { @@ -247,3 +265,21 @@ func parseGenesisJSONBytesToConfig(bytes []byte) (*Config, error) { } return &config, nil } + +// getRecentStartTime advances [definedStartTime] in chunks of [period]. It +// returns the latest startTime that isn't after [now]. +func getRecentStartTime( + definedStartTime time.Time, + now time.Time, + period time.Duration, +) time.Time { + startTime := definedStartTime + for { + nextStartTime := startTime.Add(period) + if now.Before(nextStartTime) { + break + } + startTime = nextStartTime + } + return startTime +} diff --git a/genesis/config_test.go b/genesis/config_test.go index 8a9bc96a9c94..693ee267d959 100644 --- a/genesis/config_test.go +++ b/genesis/config_test.go @@ -5,6 +5,7 @@ package genesis import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -51,3 +52,68 @@ func TestAllocationCompare(t *testing.T) { }) } } + +func TestGetRecentStartTime(t *testing.T) { + type test struct { + name string + defined time.Time + now time.Time + expected time.Time + } + tests := []test{ + { + name: "before 1 period and 1 second", + defined: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + now: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(-localNetworkUpdateStartTimePeriod - time.Second), + expected: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + }, + { + name: "before 1 second", + defined: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + now: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(-time.Second), + expected: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + }, + { + name: "equal", + defined: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + now: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + expected: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + }, + { + name: "after 1 second", + defined: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + now: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(time.Second), + expected: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + }, + { + name: "after 1 period", + defined: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + now: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(localNetworkUpdateStartTimePeriod), + expected: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(localNetworkUpdateStartTimePeriod), + }, + { + name: "after 1 period and 1 second", + defined: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + now: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(localNetworkUpdateStartTimePeriod + time.Second), + expected: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(localNetworkUpdateStartTimePeriod), + }, + { + name: "after 2 periods", + defined: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + now: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(2 * localNetworkUpdateStartTimePeriod), + expected: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(2 * localNetworkUpdateStartTimePeriod), + }, + { + name: "after 2 periods and 1 second", + defined: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC), + now: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(2*localNetworkUpdateStartTimePeriod + time.Second), + expected: time.Date(2024, time.July, 15, 4, 0, 0, 0, time.UTC).Add(2 * localNetworkUpdateStartTimePeriod), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := getRecentStartTime(tt.defined, tt.now, localNetworkUpdateStartTimePeriod) + require.Equal(t, tt.expected, actual) + }) + } +} diff --git a/genesis/genesis_local.json b/genesis/genesis_local.json index be8dba4edbf1..0137de9dd1b2 100644 --- a/genesis/genesis_local.json +++ b/genesis/genesis_local.json @@ -38,7 +38,7 @@ ] } ], - "startTime": 1690862400, + "startTime": 1721016000, "initialStakeDuration": 31536000, "initialStakeDurationOffset": 5400, "initialStakedFunds": [ @@ -93,4 +93,4 @@ ], "cChainGenesis": "{\"config\":{\"chainId\":43112,\"homesteadBlock\":0,\"daoForkBlock\":0,\"daoForkSupport\":true,\"eip150Block\":0,\"eip150Hash\":\"0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0\",\"eip155Block\":0,\"eip158Block\":0,\"byzantiumBlock\":0,\"constantinopleBlock\":0,\"petersburgBlock\":0,\"istanbulBlock\":0,\"muirGlacierBlock\":0,\"apricotPhase1BlockTimestamp\":0,\"apricotPhase2BlockTimestamp\":0},\"nonce\":\"0x0\",\"timestamp\":\"0x0\",\"extraData\":\"0x00\",\"gasLimit\":\"0x5f5e100\",\"difficulty\":\"0x0\",\"mixHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"coinbase\":\"0x0000000000000000000000000000000000000000\",\"alloc\":{\"8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC\":{\"balance\":\"0x295BE96E64066972000000\"}},\"number\":\"0x0\",\"gasUsed\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\"}", "message": "{{ fun_quote }}" -} +} \ No newline at end of file diff --git a/genesis/genesis_test.go b/genesis/genesis_test.go index 679fc05be914..c2ab1e3e1470 100644 --- a/genesis/genesis_test.go +++ b/genesis/genesis_test.go @@ -343,28 +343,27 @@ func TestGenesisFromFlag(t *testing.T) { func TestGenesis(t *testing.T) { tests := []struct { - networkID uint32 + config *Config expectedID string }{ { - networkID: constants.MainnetID, + config: &MainnetConfig, expectedID: "UUvXi6j7QhVvgpbKM89MP5HdrxKm9CaJeHc187TsDNf8nZdLk", }, { - networkID: constants.FujiID, + config: &FujiConfig, expectedID: "MSj6o9TpezwsQx4Tv7SHqpVvCbJ8of1ikjsqPZ1bKRjc9zBy3", }, { - networkID: constants.LocalID, - expectedID: "S4BvHv1XyihF9gXkJKXWWwQuuDWZqesRXz6wnqavQ9FrjGfAa", + config: &unmodifiedLocalConfig, + expectedID: "23DnViuN2kgePiBN4JxZXh1VrfXca2rwUp6XrKgNGdj3TSQjiN", }, } for _, test := range tests { - t.Run(constants.NetworkIDToNetworkName[test.networkID], func(t *testing.T) { + t.Run(constants.NetworkIDToNetworkName[test.config.NetworkID], func(t *testing.T) { require := require.New(t) - config := GetConfig(test.networkID) - genesisBytes, _, err := FromConfig(config) + genesisBytes, _, err := FromConfig(test.config) require.NoError(err) var genesisID ids.ID = hashing.ComputeHash256Array(genesisBytes) From 536005c8f17cef3b4c00aa6f1200aad3496907ce Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 25 Jul 2024 18:28:35 -0400 Subject: [PATCH 06/15] Update versions for v1.11.10 (#3216) --- RELEASES.md | 64 ++++++++++++++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 +-- proto/README.md | 2 +- version/compatibility.json | 3 ++ version/constants.go | 4 +-- 6 files changed, 73 insertions(+), 6 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index a70ad214e1ff..be6a7cef9548 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,5 +1,69 @@ # Release Notes +## [v1.11.10](https://github.com/ava-labs/avalanchego/releases/tag/v1.11.10) + +This version is backwards compatible to [v1.11.0](https://github.com/ava-labs/avalanchego/releases/tag/v1.11.0). It is optional, but encouraged. + +The plugin version is updated to `36` all plugins must update to be compatible. + +### APIs + +- Renamed `avalanche_{vmName}_plugin_.*` metrics to `avalanche_{vmName}_.*` +- Renamed `avalanche_{vmName}_rpcchainvm_.*` metrics to `avalanche_rpcchainvm_.*` + +### Fixes + +- Updated local network validator start times +- Fixed block building timer recalculation when anyone can propose + +### What's Changed + +- Refactor rpcchainvm metrics registration by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/3170 +- Add example reward calculator usage by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/3171 +- Send AppErrors from p2p SDK by @joshua-kim in https://github.com/ava-labs/avalanchego/pull/2753 +- build(tests): require `//go:build test` tag if importing test packages outside of `_test.go` files by @ARR4N in https://github.com/ava-labs/avalanchego/pull/3173 +- Include VM path in plugin version error by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/3178 +- [ci] Simplify ci monitoring with custom actions by @marun in https://github.com/ava-labs/avalanchego/pull/3161 +- [vms/avm] Replace `strings.Replace` with `fmt.Sprintf` in tests by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/3177 +- Changes to support teleporter e2e tests by @feuGeneA in https://github.com/ava-labs/avalanchego/pull/3179 +- Reduce usage of `getBlock` in consensus by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/3151 +- [ci] Enable run-monitored-tmpnet-cmd reuse by other repos by @marun in https://github.com/ava-labs/avalanchego/pull/3186 +- Restructured fee calculator API by @abi87 in https://github.com/ava-labs/avalanchego/pull/3145 +- P-Chain: Block-level fee Calculator by @abi87 in https://github.com/ava-labs/avalanchego/pull/3032 +- [ci] Allow antithesis test setups to be triggered independently by @marun in https://github.com/ava-labs/avalanchego/pull/3183 +- [antithesis] Fix image version separator in triggering workflows by @marun in https://github.com/ava-labs/avalanchego/pull/3191 +- Remove `block.Status` by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/3158 +- [antithesis] Refactor compose config generation to simplify reuse by @marun in https://github.com/ava-labs/avalanchego/pull/3184 +- [antithesis] Add schedule for workflows by @marun in https://github.com/ava-labs/avalanchego/pull/3192 +- Update `golangci-lint` to `v1.59.1` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/3195 +- [ci] Ensure monitoring action compatibility for other repos by @marun in https://github.com/ava-labs/avalanchego/pull/3193 +- chore: fix some comments for struct field by @linghuying in https://github.com/ava-labs/avalanchego/pull/3194 +- [antithesis] Configure workload history by @marun in https://github.com/ava-labs/avalanchego/pull/3196 +- [vms/proposervm] Set build block time correctly when anyone can propose by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/3197 +- chore: fix comment by @polymaer in https://github.com/ava-labs/avalanchego/pull/3201 +- Make math.Add64 and math.Mul64 generic by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/3205 +- Implement ACP-103 fee package by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/3203 +- [antithesis] Fix job duration by @marun in https://github.com/ava-labs/avalanchego/pull/3206 +- [vms/platformvm] `RegisterDUnsignedTxsTypes` -> `RegisterDurangoUnsignedTxsTypes` by @dhrubabasu in https://github.com/ava-labs/avalanchego/pull/3212 +- chore: fix some comments by @yingshanghuangqiao in https://github.com/ava-labs/avalanchego/pull/3213 +- Fix typos by @omahs in https://github.com/ava-labs/avalanchego/pull/3208 +- Cleanup fee.staticCalculator by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/3210 +- typo by @meaghanfitzgerald in https://github.com/ava-labs/avalanchego/pull/3220 +- add getSubnet to p-chain api reference by @felipemadero in https://github.com/ava-labs/avalanchego/pull/3204 +- [ci] Update fuzz workflows to target master branch by @marun in https://github.com/ava-labs/avalanchego/pull/3221 +- Cleanup wallet tests by @StephenButtolph in https://github.com/ava-labs/avalanchego/pull/3230 +- Update local validator start time by @ceyonur in https://github.com/ava-labs/avalanchego/pull/3224 + +### New Contributors + +- @feuGeneA made their first contribution in https://github.com/ava-labs/avalanchego/pull/3179 +- @linghuying made their first contribution in https://github.com/ava-labs/avalanchego/pull/3194 +- @polymaer made their first contribution in https://github.com/ava-labs/avalanchego/pull/3201 +- @yingshanghuangqiao made their first contribution in https://github.com/ava-labs/avalanchego/pull/3213 +- @omahs made their first contribution in https://github.com/ava-labs/avalanchego/pull/3208 + +**Full Changelog**: https://github.com/ava-labs/avalanchego/compare/v1.11.9...v1.11.10 + ## [v1.11.9](https://github.com/ava-labs/avalanchego/releases/tag/v1.11.9) This version is backwards compatible to [v1.11.0](https://github.com/ava-labs/avalanchego/releases/tag/v1.11.0). It is optional, but encouraged. diff --git a/go.mod b/go.mod index eaedf707a300..00458471b34e 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/DataDog/zstd v1.5.2 github.com/NYTimes/gziphandler v1.1.1 github.com/antithesishq/antithesis-sdk-go v0.3.8 - github.com/ava-labs/coreth v0.13.7-remove-status + github.com/ava-labs/coreth v0.13.7 github.com/ava-labs/ledger-avalanche/go v0.0.0-20240610153809-9c955cc90a95 github.com/btcsuite/btcd/btcutil v1.1.3 github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 diff --git a/go.sum b/go.sum index f265b48e620b..1887349b142c 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax github.com/antithesishq/antithesis-sdk-go v0.3.8 h1:OvGoHxIcOXFJLyn9IJQ5DzByZ3YVAWNBc394ObzDRb8= github.com/antithesishq/antithesis-sdk-go v0.3.8/go.mod h1:IUpT2DPAKh6i/YhSbt6Gl3v2yvUZjmKncl7U91fup7E= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/coreth v0.13.7-remove-status h1:NVHOcHcHpgiVbGYQ1TcnnAbf16tONluvVnYt/Gi+bOA= -github.com/ava-labs/coreth v0.13.7-remove-status/go.mod h1:lTa5PYte0AXBtUK866iQrURSuJLprubKjztbDrTWSrQ= +github.com/ava-labs/coreth v0.13.7 h1:k8T9u/ROifl8f7oXjHRc1KvSISRl9txvy7gGVmHEz6g= +github.com/ava-labs/coreth v0.13.7/go.mod h1:tXDujonxXFOF6oK5HS2EmgtSXJK3Gy6RpZxb5WzR9rM= github.com/ava-labs/ledger-avalanche/go v0.0.0-20240610153809-9c955cc90a95 h1:dOVbtdnZL++pENdTCNZ1nu41eYDQkTML4sWebDnnq8c= github.com/ava-labs/ledger-avalanche/go v0.0.0-20240610153809-9c955cc90a95/go.mod h1:pJxaT9bUgeRNVmNRgtCHb7sFDIRKy7CzTQVi8gGNT6g= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= diff --git a/proto/README.md b/proto/README.md index e1ef00f4e996..5bbf1b3fc7ee 100644 --- a/proto/README.md +++ b/proto/README.md @@ -1,6 +1,6 @@ # Avalanche gRPC -Now Serving: **Protocol Version 35** +Now Serving: **Protocol Version 36** Protobuf files are hosted at [https://buf.build/ava-labs/avalanche](https://buf.build/ava-labs/avalanche) and diff --git a/version/compatibility.json b/version/compatibility.json index cdcd18acd1fd..dba18fd78582 100644 --- a/version/compatibility.json +++ b/version/compatibility.json @@ -1,4 +1,7 @@ { + "36": [ + "v1.11.10" + ], "35": [ "v1.11.3", "v1.11.4", diff --git a/version/constants.go b/version/constants.go index a65d2a083ab2..9e294b981694 100644 --- a/version/constants.go +++ b/version/constants.go @@ -18,7 +18,7 @@ const ( // RPCChainVMProtocol should be bumped anytime changes are made which // require the plugin vm to upgrade to latest avalanchego release to be // compatible. - RPCChainVMProtocol uint = 35 + RPCChainVMProtocol uint = 36 ) // These are globals that describe network upgrades and node versions @@ -26,7 +26,7 @@ var ( Current = &Semantic{ Major: 1, Minor: 11, - Patch: 9, + Patch: 10, } CurrentApp = &Application{ Name: Client, From 1096c4f2fd5f3bc5192d4493c0c66c2c1bdc055d Mon Sep 17 00:00:00 2001 From: marun Date: Thu, 25 Jul 2024 16:03:13 -0700 Subject: [PATCH 07/15] [ci] Remove defunct network outage sim workflow (#3234) --- .github/actionlint.yml | 1 - .github/workflows/cleanup-net-outage-sim.sh | 13 --- .github/workflows/net-outage-sim.yml | 32 ------- .github/workflows/run-net-outage-sim.sh | 99 --------------------- 4 files changed, 145 deletions(-) delete mode 100755 .github/workflows/cleanup-net-outage-sim.sh delete mode 100644 .github/workflows/net-outage-sim.yml delete mode 100755 .github/workflows/run-net-outage-sim.sh diff --git a/.github/actionlint.yml b/.github/actionlint.yml index 2e6d753c2282..62bee747e6f0 100644 --- a/.github/actionlint.yml +++ b/.github/actionlint.yml @@ -2,4 +2,3 @@ self-hosted-runner: labels: - custom-arm64-focal - custom-arm64-jammy - - net-outage-sim diff --git a/.github/workflows/cleanup-net-outage-sim.sh b/.github/workflows/cleanup-net-outage-sim.sh deleted file mode 100755 index bcb9862f9efb..000000000000 --- a/.github/workflows/cleanup-net-outage-sim.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -### -# cleanup removes the docker instance and the network -echo "Cleaning up..." -# shellcheck disable=SC2046 -docker rm $(sudo docker stop $(sudo docker ps -a -q --filter ancestor=avaplatform/avalanchego:latest --format="{{.ID}}")) #if the filter returns nothing the command fails, so ignore errors -docker network rm controlled-net -rm /opt/mainnet-db-daily* 2>/dev/null -rm -rf /var/lib/avalanchego 2>/dev/null -echo "Done cleaning up" diff --git a/.github/workflows/net-outage-sim.yml b/.github/workflows/net-outage-sim.yml deleted file mode 100644 index af6af82fb4c1..000000000000 --- a/.github/workflows/net-outage-sim.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: network-outage-simulation - -on: - workflow_dispatch: - schedule: - # * is a special character in YAML so you have to quote this string - # Run every day at 7 AM. (The database backup is created around 5 AM.) - - cron: "0 7 * * *" - -jobs: - run_sim: - runs-on: [self-hosted, linux, x64, net-outage-sim] - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Cleanup docker (avoid conflicts with previous runs) - shell: bash - run: .github/workflows/cleanup-net-outage-sim.sh - - - name: Download avalanchego:latest - run: docker pull avaplatform/avalanchego:latest - - - name: Run the internet outage simulation - shell: bash - run: .github/workflows/run-net-outage-sim.sh - - - name: Cleanup again - if: always() # Always clean up - shell: bash - run: .github/workflows/cleanup-net-outage-sim.sh diff --git a/.github/workflows/run-net-outage-sim.sh b/.github/workflows/run-net-outage-sim.sh deleted file mode 100755 index 809d290e1d16..000000000000 --- a/.github/workflows/run-net-outage-sim.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -SUCCESS=1 - -# Polls AvalancheGo until it's healthy. When it is, -# sets SUCCESS to 0 and returns. If AvalancheGo -# doesn't become healthy within 3 hours, sets -# SUCCESS to 1 and returns. -wait_until_healthy () { - # timeout: if after 3 hours it is not healthy, return - stop=$(date -d "+ 3 hour" +%s) - # store the response code here - response=0 - # while the endpoint doesn't return 200 - while [ "$response" -ne 200 ] - do - echo "Checking if local node is healthy..." - # Ignore error in case of ephemeral failure to hit node's API - response=$(curl --write-out '%{http_code}' --silent --output /dev/null localhost:9650/ext/health) - echo "got status code $response from health endpoint" - # check that 3 hours haven't passed - now=$(date +%s) - if [ "$now" -ge "$stop" ]; - then - # timeout: exit - SUCCESS=1 - return - fi - # no timeout yet, wait 30s until retry - sleep 30 - done - # response returned 200, therefore exit - echo "Node became healthy" - SUCCESS=0 -} - -#remove any existing database files -echo "removing existing database files..." -rm /opt/mainnet-db-daily* 2>/dev/null || true # Do || true to ignore error if files dont exist yet -rm -rf /var/lib/avalanchego 2>/dev/null || true # Do || true to ignore error if files dont exist yet -echo "done existing database files" - -#download latest mainnet DB backup -FILENAME="mainnet-db-daily-" -DATE=$(date +'%m-%d-%Y') -DB_FILE="$FILENAME$DATE" -echo "Copying database file $DB_FILE from S3 to local..." -aws s3 cp s3://avalanche-db-daily/ /opt/ --no-progress --recursive --exclude "*" --include "$DB_FILE*" -echo "Done downloading database" - -# extract DB -echo "Extracting database..." -mkdir -p /var/lib/avalanchego/db -tar -zxf /opt/"$DB_FILE"*-tar.gz -C /var/lib/avalanchego/db -echo "Done extracting database" - -echo "Creating Docker network..." -docker network create controlled-net - -echo "Starting Docker container..." -containerID=$(docker run --name="net_outage_simulation" --memory="12g" --memory-reservation="11g" --cpus="6.0" --net=controlled-net -p 9650:9650 -p 9651:9651 -v /var/lib/avalanchego/db:/db -d avaplatform/avalanchego:latest /avalanchego/build/avalanchego --db-dir /db --http-host=0.0.0.0) - -echo "Waiting 30 seconds for node to start..." -sleep 30 -echo "Waiting until healthy..." -wait_until_healthy -if [ $SUCCESS -eq 1 ]; -then - echo "Timed out waiting for node to become healthy; exiting." - exit 1 -fi - -# To simulate internet outage, we will disable the docker network connection -echo "Disconnecting node from internet..." -docker network disconnect controlled-net "$containerID" -echo "Sleeping 60 minutes..." -sleep 3600 -echo "Reconnecting node to internet..." -docker network connect controlled-net "$containerID" -echo "Reconnected to internet. Waiting until healthy..." - -# now repeatedly check the node's health until it returns healthy -start=$(date +%s) -SUCCESS=-1 -wait_until_healthy -if [ $SUCCESS -eq 1 ]; -then - echo "Timed out waiting for node to become healthy after outage; exiting." - exit 1 -fi - -# The node returned healthy, print how long it took -end=$(date +%s) - -DELAY=$((end - start)) -echo "Node became healthy again after complete outage after $DELAY seconds." -echo "Test completed" From 7fdb6b6631148b87410a9e0a64eb105e4d5a5c14 Mon Sep 17 00:00:00 2001 From: Arran Schlosberg <519948+ARR4N@users.noreply.github.com> Date: Fri, 26 Jul 2024 00:06:50 +0100 Subject: [PATCH 08/15] chore: allow test-only imports in `*test` and `/tests/**` packages (#3229) --- scripts/lint.sh | 15 +++++++++++---- snow/consensus/snowman/snowmantest/block.go | 2 -- snow/consensus/snowman/snowmantest/engine.go | 2 -- snow/consensus/snowman/snowmantest/require.go | 2 -- snow/snowtest/context.go | 2 -- snow/snowtest/decidable.go | 2 -- snow/snowtest/status.go | 2 -- 7 files changed, 11 insertions(+), 16 deletions(-) diff --git a/scripts/lint.sh b/scripts/lint.sh index 74c5f47555f2..123ba982f0a5 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -88,25 +88,32 @@ function test_interface_compliance_nil { function test_import_testing_only_in_tests { ROOT=$( git rev-parse --show-toplevel ) - NON_TEST_GO_FILES=$( find "${ROOT}" -iname '*.go' ! -iname '*_test.go'); + NON_TEST_GO_FILES=$( find "${ROOT}" -iname '*.go' ! -iname '*_test.go' ! -path "${ROOT}/tests/*" ); IMPORT_TESTING=$( echo "${NON_TEST_GO_FILES}" | xargs grep -lP '^\s*(import\s+)?"testing"'); IMPORT_TESTIFY=$( echo "${NON_TEST_GO_FILES}" | xargs grep -l '"github.com/stretchr/testify'); + IMPORT_FROM_TESTS=$( echo "${NON_TEST_GO_FILES}" | xargs grep -l '"github.com/ava-labs/tests/'); + IMPORT_TEST_PKG=$( echo "${NON_TEST_GO_FILES}" | xargs grep -lP '"github.com/ava-labs/.*?test"'); + # TODO(arr4n): send a PR to add support for build tags in `mockgen` and then enable this. # IMPORT_GOMOCK=$( echo "${NON_TEST_GO_FILES}" | xargs grep -l '"go.uber.org/mock'); - HAVE_TEST_LOGIC=$( printf "%s\n%s" "${IMPORT_TESTING}" "${IMPORT_TESTIFY}" ); + HAVE_TEST_LOGIC=$( printf "%s\n%s\n%s\n%s" "${IMPORT_TESTING}" "${IMPORT_TESTIFY}" "${IMPORT_FROM_TESTS}" "${IMPORT_TEST_PKG}" ); TAGGED_AS_TEST=$( echo "${NON_TEST_GO_FILES}" | xargs grep -lP '^\/\/go:build\s+(.+(,|\s+))?test[,\s]?'); + IN_TEST_PKG=$( echo "${NON_TEST_GO_FILES}" | grep -P '.*test/[^/]+\.go$' ) # directory (hence package name) ends in "test" + + # Files in /tests/ are already excluded by the `find ... ! -path` + INTENDED_FOR_TESTING=$( printf "%s\n%s" "${TAGGED_AS_TEST}" "${IN_TEST_PKG}" ) # -3 suppresses files that have test logic and have the "test" build tag # -2 suppresses files that are tagged despite not having detectable test logic - UNTAGGED=$( comm -23 <( echo "${HAVE_TEST_LOGIC}" | sort -u ) <( echo "${TAGGED_AS_TEST}" | sort -u ) ); + UNTAGGED=$( comm -23 <( echo "${HAVE_TEST_LOGIC}" | sort -u ) <( echo "${INTENDED_FOR_TESTING}" | sort -u ) ); if [ -z "${UNTAGGED}" ]; then return 0; fi - echo "Non-test Go files importing test-only packages MUST have '//go:build test' tag:"; + echo 'Non-test Go files importing test-only packages MUST (a) have '//go:build test' tag; (b) be in *test package; or (c) be in /tests/ directory:'; echo "${UNTAGGED}"; return 1; } diff --git a/snow/consensus/snowman/snowmantest/block.go b/snow/consensus/snowman/snowmantest/block.go index 19348532e54f..4dba3d0cc697 100644 --- a/snow/consensus/snowman/snowmantest/block.go +++ b/snow/consensus/snowman/snowmantest/block.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package snowmantest import ( diff --git a/snow/consensus/snowman/snowmantest/engine.go b/snow/consensus/snowman/snowmantest/engine.go index 954b6bbe7075..ee7560eadc51 100644 --- a/snow/consensus/snowman/snowmantest/engine.go +++ b/snow/consensus/snowman/snowmantest/engine.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package snowmantest import ( diff --git a/snow/consensus/snowman/snowmantest/require.go b/snow/consensus/snowman/snowmantest/require.go index 5a5e5d09bf44..7b942740dfd1 100644 --- a/snow/consensus/snowman/snowmantest/require.go +++ b/snow/consensus/snowman/snowmantest/require.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package snowmantest import ( diff --git a/snow/snowtest/context.go b/snow/snowtest/context.go index be08ae75b21e..3cacc8e873bf 100644 --- a/snow/snowtest/context.go +++ b/snow/snowtest/context.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package snowtest import ( diff --git a/snow/snowtest/decidable.go b/snow/snowtest/decidable.go index 3cbdb2c1c9c2..691cc90120bc 100644 --- a/snow/snowtest/decidable.go +++ b/snow/snowtest/decidable.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package snowtest import ( diff --git a/snow/snowtest/status.go b/snow/snowtest/status.go index 36c26f83cbde..6fd90f856a3f 100644 --- a/snow/snowtest/status.go +++ b/snow/snowtest/status.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package snowtest type Status int From df27dfe38df9cfd1fe18c4297e92a295c72abf76 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 26 Jul 2024 02:17:18 +0200 Subject: [PATCH 09/15] Add benchmarks for add and sub fee dimensions (#3222) Co-authored-by: Stephen Buttolph --- vms/components/fee/dimensions.go | 4 +- vms/components/fee/dimensions_test.go | 77 ++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/vms/components/fee/dimensions.go b/vms/components/fee/dimensions.go index 3db1db01b3d2..b9e0a3449e0f 100644 --- a/vms/components/fee/dimensions.go +++ b/vms/components/fee/dimensions.go @@ -22,7 +22,7 @@ type ( // Add returns d + sum(os...). // // If overflow occurs, an error is returned. -func (d Dimensions) Add(os ...Dimensions) (Dimensions, error) { +func (d Dimensions) Add(os ...*Dimensions) (Dimensions, error) { var err error for _, o := range os { for i := range o { @@ -38,7 +38,7 @@ func (d Dimensions) Add(os ...Dimensions) (Dimensions, error) { // Sub returns d - sum(os...). // // If underflow occurs, an error is returned. -func (d Dimensions) Sub(os ...Dimensions) (Dimensions, error) { +func (d Dimensions) Sub(os ...*Dimensions) (Dimensions, error) { var err error for _, o := range os { for i := range o { diff --git a/vms/components/fee/dimensions_test.go b/vms/components/fee/dimensions_test.go index 3a0260934e75..0ca31a5818d6 100644 --- a/vms/components/fee/dimensions_test.go +++ b/vms/components/fee/dimensions_test.go @@ -16,7 +16,7 @@ func Test_Dimensions_Add(t *testing.T) { tests := []struct { name string lhs Dimensions - rhs []Dimensions + rhs []*Dimensions expected Dimensions expectedErr error }{ @@ -28,7 +28,7 @@ func Test_Dimensions_Add(t *testing.T) { DBWrite: 3, Compute: 4, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 10, DBRead: 20, @@ -52,7 +52,7 @@ func Test_Dimensions_Add(t *testing.T) { DBWrite: 3, Compute: 4, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 10, DBRead: 20, @@ -82,7 +82,7 @@ func Test_Dimensions_Add(t *testing.T) { DBWrite: 3, Compute: 4, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 10, DBRead: 20, @@ -106,7 +106,7 @@ func Test_Dimensions_Add(t *testing.T) { DBWrite: 3, Compute: 4, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 10, DBRead: 20, @@ -130,7 +130,7 @@ func Test_Dimensions_Add(t *testing.T) { DBWrite: math.MaxUint64, Compute: 4, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 10, DBRead: 20, @@ -154,7 +154,7 @@ func Test_Dimensions_Add(t *testing.T) { DBWrite: 3, Compute: math.MaxUint64, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 10, DBRead: 20, @@ -186,7 +186,7 @@ func Test_Dimensions_Sub(t *testing.T) { tests := []struct { name string lhs Dimensions - rhs []Dimensions + rhs []*Dimensions expected Dimensions expectedErr error }{ @@ -198,7 +198,7 @@ func Test_Dimensions_Sub(t *testing.T) { DBWrite: 33, Compute: 44, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 1, DBRead: 2, @@ -222,7 +222,7 @@ func Test_Dimensions_Sub(t *testing.T) { DBWrite: 33, Compute: 44, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 1, DBRead: 2, @@ -252,7 +252,7 @@ func Test_Dimensions_Sub(t *testing.T) { DBWrite: 33, Compute: 44, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: math.MaxUint64, DBRead: 2, @@ -276,7 +276,7 @@ func Test_Dimensions_Sub(t *testing.T) { DBWrite: 33, Compute: 44, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 1, DBRead: math.MaxUint64, @@ -300,7 +300,7 @@ func Test_Dimensions_Sub(t *testing.T) { DBWrite: 33, Compute: 44, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 1, DBRead: 2, @@ -324,7 +324,7 @@ func Test_Dimensions_Sub(t *testing.T) { DBWrite: 33, Compute: 44, }, - rhs: []Dimensions{ + rhs: []*Dimensions{ { Bandwidth: 1, DBRead: 2, @@ -426,3 +426,52 @@ func Test_Dimensions_ToGas(t *testing.T) { }) } } + +func Benchmark_Dimensions_Add(b *testing.B) { + lhs := Dimensions{600, 10, 10, 1000} + rhs := []*Dimensions{ + {1, 1, 1, 1}, + {10, 10, 10, 10}, + {100, 100, 100, 100}, + {200, 200, 200, 200}, + {500, 500, 500, 500}, + {1_000, 1_000, 1_000, 1_000}, + {10_000, 10_000, 10_000, 10_000}, + } + + b.Run("single", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = lhs.Add(rhs[0]) + } + }) + + b.Run("multiple", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = lhs.Add(rhs[0], rhs[1], rhs[2], rhs[3], rhs[4], rhs[5], rhs[6]) + } + }) +} + +func Benchmark_Dimensions_Sub(b *testing.B) { + lhs := Dimensions{10_000, 10_000, 10_000, 100_000} + rhs := []*Dimensions{ + {1, 1, 1, 1}, + {10, 10, 10, 10}, + {100, 100, 100, 100}, + {200, 200, 200, 200}, + {500, 500, 500, 500}, + {1_000, 1_000, 1_000, 1_000}, + } + + b.Run("single", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = lhs.Sub(rhs[0]) + } + }) + + b.Run("multiple", func(b *testing.B) { + for i := 0; i < b.N; i++ { + _, _ = lhs.Sub(rhs[0], rhs[1], rhs[2], rhs[3], rhs[4], rhs[5]) + } + }) +} From 5804bad887c57e7a723cd969f8b3eaa99e88411a Mon Sep 17 00:00:00 2001 From: Dhruba Basu <7675102+dhrubabasu@users.noreply.github.com> Date: Thu, 25 Jul 2024 20:26:36 -0400 Subject: [PATCH 10/15] Remove deadcode (#3086) --- database/helpers.go | 11 ----------- network/p2p/gossip/gossip.go | 23 ----------------------- utils/hashing/hashing.go | 16 ---------------- vms/rpcchainvm/grpcutils/util.go | 7 ------- 4 files changed, 57 deletions(-) diff --git a/database/helpers.go b/database/helpers.go index e2f4a1a3c15a..d17e6669e4fa 100644 --- a/database/helpers.go +++ b/database/helpers.go @@ -41,10 +41,6 @@ func GetID(db KeyValueReader, key []byte) (ids.ID, error) { return ids.ToID(b) } -func ParseID(b []byte) (ids.ID, error) { - return ids.ToID(b) -} - func PutUInt64(db KeyValueWriter, key []byte, val uint64) error { b := PackUInt64(val) return db.Put(key, b) @@ -163,13 +159,6 @@ func Size(db Iteratee) (int, error) { return size, iterator.Error() } -func IsEmpty(db Iteratee) (bool, error) { - iterator := db.NewIterator() - defer iterator.Release() - - return !iterator.Next(), iterator.Error() -} - func AtomicClear(readerDB Iteratee, deleterDB KeyValueDeleter) error { return AtomicClearPrefix(readerDB, deleterDB, nil) } diff --git a/network/p2p/gossip/gossip.go b/network/p2p/gossip/gossip.go index 1562093c41e2..b44201ca90ed 100644 --- a/network/p2p/gossip/gossip.go +++ b/network/p2p/gossip/gossip.go @@ -42,7 +42,6 @@ var ( _ Gossiper = (*PullGossiper[*testTx])(nil) _ Gossiper = (*NoOpGossiper)(nil) - _ Set[*testTx] = (*EmptySet[*testTx])(nil) _ Set[*testTx] = (*FullSet[*testTx])(nil) ioTypeLabels = []string{ioLabel, typeLabel} @@ -77,8 +76,6 @@ var ( ErrInvalidDiscardedSize = errors.New("discarded size cannot be negative") ErrInvalidTargetGossipSize = errors.New("target gossip size cannot be negative") ErrInvalidRegossipFrequency = errors.New("re-gossip frequency cannot be negative") - - errEmptySetCantAdd = errors.New("empty set can not add") ) // Gossiper gossips Gossipables to other nodes @@ -603,26 +600,6 @@ func (t *TestGossiper) Gossip(ctx context.Context) error { return t.GossipF(ctx) } -type EmptySet[T Gossipable] struct{} - -func (EmptySet[_]) Gossip(context.Context) error { - return nil -} - -func (EmptySet[T]) Add(T) error { - return errEmptySetCantAdd -} - -func (EmptySet[T]) Has(ids.ID) bool { - return false -} - -func (EmptySet[T]) Iterate(func(gossipable T) bool) {} - -func (EmptySet[_]) GetFilter() ([]byte, []byte) { - return bloom.EmptyFilter.Marshal(), ids.Empty[:] -} - type FullSet[T Gossipable] struct{} func (FullSet[_]) Gossip(context.Context) error { diff --git a/utils/hashing/hashing.go b/utils/hashing/hashing.go index 0d09fd457247..84e44a1da1fc 100644 --- a/utils/hashing/hashing.go +++ b/utils/hashing/hashing.go @@ -38,22 +38,6 @@ func ComputeHash256(buf []byte) []byte { return arr[:] } -// ComputeHash256Ranges computes a cryptographically strong 256 bit hash of the input -// byte slice in the ranges specified. -// Example: -// ComputeHash256Ranges({1, 2, 4, 8, 16}, {{1, 2}, {3, 5}}) is equivalent to -// ComputeHash256({2, 8, 16}). -func ComputeHash256Ranges(buf []byte, ranges [][2]int) []byte { - hashBuilder := sha256.New() - for _, r := range ranges { - _, err := hashBuilder.Write(buf[r[0]:r[1]]) - if err != nil { - panic(err) - } - } - return hashBuilder.Sum(nil) -} - // ComputeHash160Array computes a cryptographically strong 160 bit hash of the // input byte slice. func ComputeHash160Array(buf []byte) Hash160 { diff --git a/vms/rpcchainvm/grpcutils/util.go b/vms/rpcchainvm/grpcutils/util.go index 280ab5c1aa3b..f257cbb45d07 100644 --- a/vms/rpcchainvm/grpcutils/util.go +++ b/vms/rpcchainvm/grpcutils/util.go @@ -17,13 +17,6 @@ import ( tspb "google.golang.org/protobuf/types/known/timestamppb" ) -func Errorf(code int, tmpl string, args ...interface{}) error { - return GetGRPCErrorFromHTTPResponse(&httppb.HandleSimpleHTTPResponse{ - Code: int32(code), - Body: []byte(fmt.Sprintf(tmpl, args...)), - }) -} - // GetGRPCErrorFromHTTPResponse takes an HandleSimpleHTTPResponse as input and returns a gRPC error. func GetGRPCErrorFromHTTPResponse(resp *httppb.HandleSimpleHTTPResponse) error { a, err := anypb.New(resp) From 070aaac6e77c28dd293371bad3caffce313e8f10 Mon Sep 17 00:00:00 2001 From: yacovm Date: Fri, 26 Jul 2024 16:13:11 +0200 Subject: [PATCH 11/15] Parallelize BatchedParseBlock (#3227) Signed-off-by: Yacov Manevich --- vms/proposervm/batched_vm.go | 12 ++-- vms/proposervm/batched_vm_test.go | 106 ++++++++++++++++++++++++++++- vms/proposervm/block/parse.go | 26 +++++++ vms/proposervm/block/parse_test.go | 61 +++++++++++++++++ 4 files changed, 196 insertions(+), 9 deletions(-) diff --git a/vms/proposervm/batched_vm.go b/vms/proposervm/batched_vm.go index 86672bdc19ea..b8be112f7fcd 100644 --- a/vms/proposervm/batched_vm.go +++ b/vms/proposervm/batched_vm.go @@ -81,10 +81,6 @@ func (vm *VM) GetAncestors( } func (vm *VM) BatchedParseBlock(ctx context.Context, blks [][]byte) ([]snowman.Block, error) { - if vm.batchedVM == nil { - return nil, block.ErrRemoteVMNotImplemented - } - type partialData struct { index int block statelessblock.Block @@ -97,9 +93,11 @@ func (vm *VM) BatchedParseBlock(ctx context.Context, blks [][]byte) ([]snowman.B statelessBlockDescs = make([]partialData, 0, len(blks)) innerBlockBytes = make([][]byte, 0, len(blks)) ) + + parsingResults := statelessblock.ParseBlocks(blks, vm.ctx.ChainID) + for ; blocksIndex < len(blks); blocksIndex++ { - blkBytes := blks[blocksIndex] - statelessBlock, err := statelessblock.Parse(blkBytes, vm.ctx.ChainID) + statelessBlock, err := parsingResults[blocksIndex].Block, parsingResults[blocksIndex].Err if err != nil { break } @@ -120,7 +118,7 @@ func (vm *VM) BatchedParseBlock(ctx context.Context, blks [][]byte) ([]snowman.B innerBlockBytes = append(innerBlockBytes, blks[blocksIndex:]...) // parse all inner blocks at once - innerBlks, err := vm.batchedVM.BatchedParseBlock(ctx, innerBlockBytes) + innerBlks, err := block.BatchedParseBlock(ctx, vm.ChainVM, innerBlockBytes) if err != nil { return nil, err } diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 458aad628f1c..d3588cb7334f 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -6,6 +6,8 @@ package proposervm import ( "bytes" "context" + "crypto" + "encoding/binary" "testing" "time" @@ -23,7 +25,10 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/snow/snowtest" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils/timer/mockable" + + blockbuilder "github.com/ava-labs/avalanchego/vms/proposervm/block" ) func TestCoreVMNotRemote(t *testing.T) { @@ -52,8 +57,9 @@ func TestCoreVMNotRemote(t *testing.T) { require.ErrorIs(err, block.ErrRemoteVMNotImplemented) var blks [][]byte - _, err = proVM.BatchedParseBlock(context.Background(), blks) - require.ErrorIs(err, block.ErrRemoteVMNotImplemented) + shouldBeEmpty, err := proVM.BatchedParseBlock(context.Background(), blks) + require.NoError(err) + require.Empty(shouldBeEmpty) } func TestGetAncestorsPreForkOnly(t *testing.T) { @@ -583,6 +589,102 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { require.Equal(builtBlk3.ID(), res[2].ID()) } +func TestBatchedParseBlockParallel(t *testing.T) { + parentID := ids.ID{1} + timestamp := time.Unix(123, 0) + pChainHeight := uint64(2) + chainID := ids.GenerateTestID() + + vm := VM{ + ctx: &snow.Context{ChainID: chainID}, + ChainVM: &block.TestVM{ + ParseBlockF: func(_ context.Context, rawBlock []byte) (snowman.Block, error) { + return &snowmantest.Block{BytesV: rawBlock}, nil + }, + }, + } + + tlsCert, err := staking.NewTLSCert() + require.NoError(t, err) + + cert, err := staking.ParseCertificate(tlsCert.Leaf.Raw) + require.NoError(t, err) + key := tlsCert.PrivateKey.(crypto.Signer) + + blockThatCantBeParsed := snowmantest.BuildChild(snowmantest.Genesis) + + blocksWithUnparsable := makeParseableBlocks(t, parentID, timestamp, pChainHeight, cert, chainID, key) + blocksWithUnparsable[50] = blockThatCantBeParsed.Bytes() + + parsableBlocks := makeParseableBlocks(t, parentID, timestamp, pChainHeight, cert, chainID, key) + + for _, testCase := range []struct { + name string + preForkIndex int + rawBlocks [][]byte + }{ + { + name: "empty input", + rawBlocks: [][]byte{}, + }, + { + name: "pre-fork is somewhere in the middle", + rawBlocks: blocksWithUnparsable, + preForkIndex: 50, + }, + { + name: "all blocks are post fork", + rawBlocks: parsableBlocks, + preForkIndex: len(parsableBlocks), + }, + } { + t.Run(testCase.name, func(t *testing.T) { + require := require.New(t) + blocks, err := vm.BatchedParseBlock(context.Background(), testCase.rawBlocks) + require.NoError(err) + + returnedBlockBytes := make([][]byte, len(blocks)) + for i, block := range blocks { + returnedBlockBytes[i] = block.Bytes() + } + require.Equal(testCase.rawBlocks, returnedBlockBytes) + + for i, block := range blocks { + if i < testCase.preForkIndex { + require.IsType(&postForkBlock{}, block) + } else { + require.IsType(&preForkBlock{}, block) + } + } + }) + } +} + +func makeParseableBlocks(t *testing.T, parentID ids.ID, timestamp time.Time, pChainHeight uint64, cert *staking.Certificate, chainID ids.ID, key crypto.Signer) [][]byte { + makeSignedBlock := func(i int) []byte { + buff := binary.AppendVarint(nil, int64(i)) + + signedBlock, err := blockbuilder.Build( + parentID, + timestamp, + pChainHeight, + cert, + buff, + chainID, + key, + ) + require.NoError(t, err) + + return signedBlock.Bytes() + } + + blockBytes := make([][]byte, 100) + for i := range blockBytes { + blockBytes[i] = makeSignedBlock(i) + } + return blockBytes +} + func TestBatchedParseBlockPostForkOnly(t *testing.T) { require := require.New(t) var ( diff --git a/vms/proposervm/block/parse.go b/vms/proposervm/block/parse.go index f6bc63877166..fb0542af3f43 100644 --- a/vms/proposervm/block/parse.go +++ b/vms/proposervm/block/parse.go @@ -5,10 +5,36 @@ package block import ( "fmt" + "sync" "github.com/ava-labs/avalanchego/ids" ) +type ParseResult struct { + Block Block + Err error +} + +// ParseBlocks parses the given raw blocks into tuples of (Block, error). +// Each ParseResult is returned in the same order as its corresponding bytes in the input. +func ParseBlocks(blks [][]byte, chainID ids.ID) []ParseResult { + results := make([]ParseResult, len(blks)) + + var wg sync.WaitGroup + wg.Add(len(blks)) + + for i, blk := range blks { + go func(i int, blkBytes []byte) { + defer wg.Done() + results[i].Block, results[i].Err = Parse(blkBytes, chainID) + }(i, blk) + } + + wg.Wait() + + return results +} + // Parse a block and verify that the signature attached to the block is valid // for the certificate provided in the block. func Parse(bytes []byte, chainID ids.ID) (Block, error) { diff --git a/vms/proposervm/block/parse_test.go b/vms/proposervm/block/parse_test.go index ce1d5d97cbb8..9728b70794f7 100644 --- a/vms/proposervm/block/parse_test.go +++ b/vms/proposervm/block/parse_test.go @@ -14,8 +14,69 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/staking" + "github.com/ava-labs/avalanchego/utils/wrappers" ) +func TestParseBlocks(t *testing.T) { + parentID := ids.ID{1} + timestamp := time.Unix(123, 0) + pChainHeight := uint64(2) + innerBlockBytes := []byte{3} + chainID := ids.ID{4} + + tlsCert, err := staking.NewTLSCert() + require.NoError(t, err) + + cert, err := staking.ParseCertificate(tlsCert.Leaf.Raw) + require.NoError(t, err) + key := tlsCert.PrivateKey.(crypto.Signer) + + signedBlock, err := Build( + parentID, + timestamp, + pChainHeight, + cert, + innerBlockBytes, + chainID, + key, + ) + require.NoError(t, err) + + signedBlockBytes := signedBlock.Bytes() + malformedBlockBytes := make([]byte, len(signedBlockBytes)-1) + copy(malformedBlockBytes, signedBlockBytes) + + for _, testCase := range []struct { + name string + input [][]byte + output []ParseResult + }{ + { + name: "ValidThenInvalid", + input: [][]byte{signedBlockBytes, malformedBlockBytes}, + output: []ParseResult{{Block: &statelessBlock{bytes: signedBlockBytes}}, {Err: wrappers.ErrInsufficientLength}}, + }, + { + name: "InvalidThenValid", + input: [][]byte{malformedBlockBytes, signedBlockBytes}, + output: []ParseResult{{Err: wrappers.ErrInsufficientLength}, {Block: &statelessBlock{bytes: signedBlockBytes}}}, + }, + } { + t.Run(testCase.name, func(t *testing.T) { + results := ParseBlocks(testCase.input, chainID) + for i := range testCase.output { + if testCase.output[i].Block == nil { + require.Nil(t, results[i].Block) + require.ErrorIs(t, results[i].Err, testCase.output[i].Err) + } else { + require.Equal(t, testCase.output[i].Block.Bytes(), results[i].Block.Bytes()) + require.NoError(t, results[i].Err) + } + } + }) + } +} + func TestParse(t *testing.T) { parentID := ids.ID{1} timestamp := time.Unix(123, 0) From 5abdebdbe0b761062fafa7969681a0c8c36f692d Mon Sep 17 00:00:00 2001 From: marun Date: Fri, 26 Jul 2024 08:03:40 -0700 Subject: [PATCH 12/15] [ci] Lint on non-test code importing packages from /tests (#3214) --- scripts/lint.sh | 4 ++-- scripts/tests.e2e.existing.sh | 2 +- scripts/tests.e2e.sh | 4 ++-- scripts/tests.upgrade.sh | 2 +- tests/e2e/banff/suites.go | 2 -- tests/e2e/c/dynamic_fees.go | 2 -- tests/e2e/c/interchain_workflow.go | 2 -- tests/e2e/faultinjection/duplicate_node_id.go | 2 -- tests/e2e/p/interchain_workflow.go | 2 -- tests/e2e/p/permissionless_subnets.go | 2 -- tests/e2e/p/staking_rewards.go | 2 -- tests/e2e/p/validator_sets.go | 2 -- tests/e2e/p/workflow.go | 2 -- tests/e2e/vms/xsvm.go | 2 -- tests/e2e/x/interchain_workflow.go | 2 -- tests/e2e/x/transfer/virtuous.go | 2 -- tests/fixture/e2e/env.go | 2 -- tests/fixture/e2e/helpers.go | 2 -- 18 files changed, 6 insertions(+), 34 deletions(-) diff --git a/scripts/lint.sh b/scripts/lint.sh index 123ba982f0a5..96cd538926d8 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -92,8 +92,8 @@ function test_import_testing_only_in_tests { IMPORT_TESTING=$( echo "${NON_TEST_GO_FILES}" | xargs grep -lP '^\s*(import\s+)?"testing"'); IMPORT_TESTIFY=$( echo "${NON_TEST_GO_FILES}" | xargs grep -l '"github.com/stretchr/testify'); - IMPORT_FROM_TESTS=$( echo "${NON_TEST_GO_FILES}" | xargs grep -l '"github.com/ava-labs/tests/'); - IMPORT_TEST_PKG=$( echo "${NON_TEST_GO_FILES}" | xargs grep -lP '"github.com/ava-labs/.*?test"'); + IMPORT_FROM_TESTS=$( echo "${NON_TEST_GO_FILES}" | xargs grep -l '"github.com/ava-labs/avalanchego/tests/'); + IMPORT_TEST_PKG=$( echo "${NON_TEST_GO_FILES}" | xargs grep -lP '"github.com/ava-labs/avalanchego/.*?test"'); # TODO(arr4n): send a PR to add support for build tags in `mockgen` and then enable this. # IMPORT_GOMOCK=$( echo "${NON_TEST_GO_FILES}" | xargs grep -l '"go.uber.org/mock'); diff --git a/scripts/tests.e2e.existing.sh b/scripts/tests.e2e.existing.sh index dbe41ec003d1..4b28fc1ad271 100755 --- a/scripts/tests.e2e.existing.sh +++ b/scripts/tests.e2e.existing.sh @@ -22,7 +22,7 @@ function print_separator { function cleanup { print_separator echo "cleaning up reusable network" - ginkgo -v --tags test ./tests/e2e/e2e.test -- --stop-network + ginkgo -v ./tests/e2e/e2e.test -- --stop-network } trap cleanup EXIT diff --git a/scripts/tests.e2e.sh b/scripts/tests.e2e.sh index efc1889af5ac..564116b40fda 100755 --- a/scripts/tests.e2e.sh +++ b/scripts/tests.e2e.sh @@ -23,7 +23,7 @@ source ./scripts/constants.sh echo "building e2e.test" # to install the ginkgo binary (required for test build and run) go install -v github.com/onsi/ginkgo/v2/ginkgo@v2.13.1 -ACK_GINKGO_RC=true ginkgo build --tags test ./tests/e2e +ACK_GINKGO_RC=true ginkgo build ./tests/e2e ./tests/e2e/e2e.test --help # Enable subnet testing by building xsvm @@ -57,4 +57,4 @@ fi ################################# # - Execute in random order to identify unwanted dependency -ginkgo ${GINKGO_ARGS} -v --tags test --randomize-all ./tests/e2e/e2e.test -- "${E2E_ARGS[@]}" "${@}" +ginkgo ${GINKGO_ARGS} -v --randomize-all ./tests/e2e/e2e.test -- "${E2E_ARGS[@]}" "${@}" diff --git a/scripts/tests.upgrade.sh b/scripts/tests.upgrade.sh index 1adab23248b9..8cc158d87d49 100755 --- a/scripts/tests.upgrade.sh +++ b/scripts/tests.upgrade.sh @@ -66,7 +66,7 @@ source ./scripts/constants.sh echo "building upgrade.test" # to install the ginkgo binary (required for test build and run) go install -v github.com/onsi/ginkgo/v2/ginkgo@v2.13.1 -ACK_GINKGO_RC=true ginkgo build --tags test ./tests/upgrade +ACK_GINKGO_RC=true ginkgo build ./tests/upgrade ./tests/upgrade/upgrade.test --help ################################# diff --git a/tests/e2e/banff/suites.go b/tests/e2e/banff/suites.go index 1f61eaa7ad92..b6da324c98ea 100644 --- a/tests/e2e/banff/suites.go +++ b/tests/e2e/banff/suites.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - // Implements tests for the banff network upgrade. package banff diff --git a/tests/e2e/c/dynamic_fees.go b/tests/e2e/c/dynamic_fees.go index 8a65ca910667..c3dda77b985c 100644 --- a/tests/e2e/c/dynamic_fees.go +++ b/tests/e2e/c/dynamic_fees.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package c import ( diff --git a/tests/e2e/c/interchain_workflow.go b/tests/e2e/c/interchain_workflow.go index 89330ccd68a7..bfb342818a5f 100644 --- a/tests/e2e/c/interchain_workflow.go +++ b/tests/e2e/c/interchain_workflow.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package c import ( diff --git a/tests/e2e/faultinjection/duplicate_node_id.go b/tests/e2e/faultinjection/duplicate_node_id.go index 13daafad2b86..288583c7e09b 100644 --- a/tests/e2e/faultinjection/duplicate_node_id.go +++ b/tests/e2e/faultinjection/duplicate_node_id.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package faultinjection import ( diff --git a/tests/e2e/p/interchain_workflow.go b/tests/e2e/p/interchain_workflow.go index c74a7d6757eb..548c82ac1211 100644 --- a/tests/e2e/p/interchain_workflow.go +++ b/tests/e2e/p/interchain_workflow.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package p import ( diff --git a/tests/e2e/p/permissionless_subnets.go b/tests/e2e/p/permissionless_subnets.go index 4e91569e9256..dc92bdd60d5c 100644 --- a/tests/e2e/p/permissionless_subnets.go +++ b/tests/e2e/p/permissionless_subnets.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package p import ( diff --git a/tests/e2e/p/staking_rewards.go b/tests/e2e/p/staking_rewards.go index 7e8178c53a32..e988cf43c2c4 100644 --- a/tests/e2e/p/staking_rewards.go +++ b/tests/e2e/p/staking_rewards.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package p import ( diff --git a/tests/e2e/p/validator_sets.go b/tests/e2e/p/validator_sets.go index 6ecbe42d1452..a3f3e1e9f075 100644 --- a/tests/e2e/p/validator_sets.go +++ b/tests/e2e/p/validator_sets.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package p import ( diff --git a/tests/e2e/p/workflow.go b/tests/e2e/p/workflow.go index c4e597d27263..3708c6b82c0a 100644 --- a/tests/e2e/p/workflow.go +++ b/tests/e2e/p/workflow.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package p import ( diff --git a/tests/e2e/vms/xsvm.go b/tests/e2e/vms/xsvm.go index b7ac0dc0b0b9..5d3557acd405 100644 --- a/tests/e2e/vms/xsvm.go +++ b/tests/e2e/vms/xsvm.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package vms import ( diff --git a/tests/e2e/x/interchain_workflow.go b/tests/e2e/x/interchain_workflow.go index c096b6e39228..ecc52f41f032 100644 --- a/tests/e2e/x/interchain_workflow.go +++ b/tests/e2e/x/interchain_workflow.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package x import ( diff --git a/tests/e2e/x/transfer/virtuous.go b/tests/e2e/x/transfer/virtuous.go index 5e6ed2a90b98..58a0351ba123 100644 --- a/tests/e2e/x/transfer/virtuous.go +++ b/tests/e2e/x/transfer/virtuous.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - // Implements X-chain transfer tests. package transfer diff --git a/tests/fixture/e2e/env.go b/tests/fixture/e2e/env.go index f56b9e9bce03..05fbbd97ac86 100644 --- a/tests/fixture/e2e/env.go +++ b/tests/fixture/e2e/env.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package e2e import ( diff --git a/tests/fixture/e2e/helpers.go b/tests/fixture/e2e/helpers.go index 9bc773cbd6c1..6f6e5382dc7a 100644 --- a/tests/fixture/e2e/helpers.go +++ b/tests/fixture/e2e/helpers.go @@ -1,8 +1,6 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build test - package e2e import ( From 553179ed1743b7d95ac19eb1f01c6cdec28af58f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 26 Jul 2024 11:30:08 -0400 Subject: [PATCH 13/15] Merge unlocked stake outputs (#3231) Co-authored-by: Alberto Benegiamo --- wallet/chain/p/builder/builder.go | 32 ++++++++++++++++----------- wallet/chain/p/builder_test.go | 36 +++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/wallet/chain/p/builder/builder.go b/wallet/chain/p/builder/builder.go index 61e5e824f55c..ffe6f937b89c 100644 --- a/wallet/chain/p/builder/builder.go +++ b/wallet/chain/p/builder/builder.go @@ -1052,6 +1052,22 @@ func (b *builder) spend( } } + for assetID, amount := range amountsToStake { + if amount == 0 { + continue + } + + stakeOutputs = append(stakeOutputs, &avax.TransferableOutput{ + Asset: avax.Asset{ + ID: assetID, + }, + Out: &secp256k1fx.TransferOutput{ + Amt: amount, + OutputOwners: *changeOwner, + }, + }) + } + // Iterate over the unlocked UTXOs for _, utxo := range utxos { assetID := utxo.AssetID() @@ -1103,24 +1119,14 @@ func (b *builder) spend( ) amountsToBurn[assetID] -= amountToBurn - amountAvalibleToStake := out.Amt - amountToBurn + amountAvailableToStake := out.Amt - amountToBurn // Burn any value that should be burned amountToStake := min( remainingAmountToStake, // Amount we still need to stake - amountAvalibleToStake, // Amount available to stake + amountAvailableToStake, // Amount available to stake ) amountsToStake[assetID] -= amountToStake - if amountToStake > 0 { - // Some of this input was put for staking - stakeOutputs = append(stakeOutputs, &avax.TransferableOutput{ - Asset: utxo.Asset, - Out: &secp256k1fx.TransferOutput{ - Amt: amountToStake, - OutputOwners: *changeOwner, - }, - }) - } - if remainingAmount := amountAvalibleToStake - amountToStake; remainingAmount > 0 { + if remainingAmount := amountAvailableToStake - amountToStake; remainingAmount > 0 { // This input had extra value, so some of it must be returned changeOutputs = append(changeOutputs, &avax.TransferableOutput{ Asset: utxo.Asset, diff --git a/wallet/chain/p/builder_test.go b/wallet/chain/p/builder_test.go index 80164f052942..bba5644cbec6 100644 --- a/wallet/chain/p/builder_test.go +++ b/wallet/chain/p/builder_test.go @@ -544,8 +544,35 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { require = require.New(t) // backend - utxosKey = testKeys[1] - utxos = makeTestUTXOs(utxosKey) + utxosOffset uint64 = 2024 + utxosKey = testKeys[1] + utxosAddr = utxosKey.Address() + ) + makeUTXO := func(amount uint64) *avax.UTXO { + utxosOffset++ + return &avax.UTXO{ + UTXOID: avax.UTXOID{ + TxID: ids.Empty.Prefix(utxosOffset), + OutputIndex: uint32(utxosOffset), + }, + Asset: avax.Asset{ID: avaxAssetID}, + Out: &secp256k1fx.TransferOutput{ + Amt: amount, + OutputOwners: secp256k1fx.OutputOwners{ + Locktime: 0, + Addrs: []ids.ShortID{utxosAddr}, + Threshold: 1, + }, + }, + } + } + + var ( + utxos = []*avax.UTXO{ + makeUTXO(testContext.AddPrimaryNetworkValidatorFee), // UTXO to pay the fee + makeUTXO(1 * units.NanoAvax), // small UTXO + makeUTXO(9 * units.Avax), // large UTXO + } chainUTXOs = common.NewDeterministicChainUTXOs(require, map[ids.ID][]*avax.UTXO{ constants.PlatformChainID: utxos, }) @@ -611,6 +638,11 @@ func TestAddPermissionlessValidatorTx(t *testing.T) { ), addInputAmounts(utx.Ins), ) + + // Outputs should be merged if possible. For example, if there are two + // unlocked inputs consumed for staking, this should only produce one staked + // output. + require.Len(utx.StakeOuts, 1) } func TestAddPermissionlessDelegatorTx(t *testing.T) { From 321e727328a86bcfdb8f5bef164e7d50e698408b Mon Sep 17 00:00:00 2001 From: cam-schultz <78878559+cam-schultz@users.noreply.github.com> Date: Fri, 26 Jul 2024 18:11:15 -0500 Subject: [PATCH 14/15] ACP 118 reference implementation (#3218) --- network/p2p/handler.go | 8 ++ proto/pb/sdk/sdk.pb.go | 159 +++++++++++++++++++++++++-- proto/sdk/sdk.proto | 18 +++ vms/avm/network/network.go | 6 +- vms/platformvm/network/network.go | 6 +- vms/platformvm/vm_regression_test.go | 3 +- 6 files changed, 183 insertions(+), 17 deletions(-) diff --git a/network/p2p/handler.go b/network/p2p/handler.go index f3f4bebf4acc..3223ed362229 100644 --- a/network/p2p/handler.go +++ b/network/p2p/handler.go @@ -15,6 +15,14 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" ) +// Standardized identifiers for application protocol handlers +const ( + TxGossipHandlerID = iota + AtomicTxGossipHandlerID + // SignatureRequestHandlerID is specified in ACP-118: https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/118-warp-signature-request + SignatureRequestHandlerID +) + var ( _ Handler = (*NoOpHandler)(nil) _ Handler = (*TestHandler)(nil) diff --git a/proto/pb/sdk/sdk.pb.go b/proto/pb/sdk/sdk.pb.go index d6f458984a80..a1289d391032 100644 --- a/proto/pb/sdk/sdk.pb.go +++ b/proto/pb/sdk/sdk.pb.go @@ -169,6 +169,117 @@ func (x *PushGossip) GetGossip() [][]byte { return nil } +// SignatureRequest is an AppRequest message type for requesting +// a BLS signature over a Warp message, as defined in ACP-118: +// https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/118-warp-signature-request +type SignatureRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Warp message to be signed + Message []byte `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` + // Justification for the message + Justification []byte `protobuf:"bytes,2,opt,name=justification,proto3" json:"justification,omitempty"` +} + +func (x *SignatureRequest) Reset() { + *x = SignatureRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_sdk_sdk_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignatureRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignatureRequest) ProtoMessage() {} + +func (x *SignatureRequest) ProtoReflect() protoreflect.Message { + mi := &file_sdk_sdk_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignatureRequest.ProtoReflect.Descriptor instead. +func (*SignatureRequest) Descriptor() ([]byte, []int) { + return file_sdk_sdk_proto_rawDescGZIP(), []int{3} +} + +func (x *SignatureRequest) GetMessage() []byte { + if x != nil { + return x.Message + } + return nil +} + +func (x *SignatureRequest) GetJustification() []byte { + if x != nil { + return x.Justification + } + return nil +} + +// SignatureRespnose is an AppResponse message type for providing +// a requested BLS signature over a Warp message, as defined in ACP-118: +// https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/118-warp-signature-request +type SignatureResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // BLS signature over the Warp message + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` +} + +func (x *SignatureResponse) Reset() { + *x = SignatureResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_sdk_sdk_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SignatureResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SignatureResponse) ProtoMessage() {} + +func (x *SignatureResponse) ProtoReflect() protoreflect.Message { + mi := &file_sdk_sdk_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SignatureResponse.ProtoReflect.Descriptor instead. +func (*SignatureResponse) Descriptor() ([]byte, []int) { + return file_sdk_sdk_proto_rawDescGZIP(), []int{4} +} + +func (x *SignatureResponse) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + var File_sdk_sdk_proto protoreflect.FileDescriptor var file_sdk_sdk_proto_rawDesc = []byte{ @@ -182,11 +293,19 @@ var file_sdk_sdk_proto_rawDesc = []byte{ 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x22, 0x24, 0x0a, 0x0a, 0x50, 0x75, 0x73, 0x68, 0x47, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, - 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x64, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x0c, 0x52, 0x06, 0x67, 0x6f, 0x73, 0x73, 0x69, 0x70, 0x22, 0x52, 0x0a, 0x10, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6a, 0x75, 0x73, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, + 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x31, 0x0a, + 0x11, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, + 0x76, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x61, 0x76, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x68, + 0x65, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x64, 0x6b, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -201,11 +320,13 @@ func file_sdk_sdk_proto_rawDescGZIP() []byte { return file_sdk_sdk_proto_rawDescData } -var file_sdk_sdk_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_sdk_sdk_proto_msgTypes = make([]protoimpl.MessageInfo, 5) var file_sdk_sdk_proto_goTypes = []interface{}{ (*PullGossipRequest)(nil), // 0: sdk.PullGossipRequest (*PullGossipResponse)(nil), // 1: sdk.PullGossipResponse (*PushGossip)(nil), // 2: sdk.PushGossip + (*SignatureRequest)(nil), // 3: sdk.SignatureRequest + (*SignatureResponse)(nil), // 4: sdk.SignatureResponse } var file_sdk_sdk_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type @@ -257,6 +378,30 @@ func file_sdk_sdk_proto_init() { return nil } } + file_sdk_sdk_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignatureRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_sdk_sdk_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SignatureResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -264,7 +409,7 @@ func file_sdk_sdk_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_sdk_sdk_proto_rawDesc, NumEnums: 0, - NumMessages: 3, + NumMessages: 5, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/sdk/sdk.proto b/proto/sdk/sdk.proto index 3f91f23efdfe..d4eea3d5d085 100644 --- a/proto/sdk/sdk.proto +++ b/proto/sdk/sdk.proto @@ -16,3 +16,21 @@ message PullGossipResponse { message PushGossip { repeated bytes gossip = 1; } + +// SignatureRequest is an AppRequest message type for requesting +// a BLS signature over a Warp message, as defined in ACP-118: +// https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/118-warp-signature-request +message SignatureRequest { + // Warp message to be signed + bytes message = 1; + // Justification for the message + bytes justification = 2; +} + +// SignatureRespnose is an AppResponse message type for providing +// a requested BLS signature over a Warp message, as defined in ACP-118: +// https://github.com/avalanche-foundation/ACPs/tree/main/ACPs/118-warp-signature-request +message SignatureResponse { + // BLS signature over the Warp message + bytes signature = 1; +} diff --git a/vms/avm/network/network.go b/vms/avm/network/network.go index ed565b1bd578..15d3dc79d156 100644 --- a/vms/avm/network/network.go +++ b/vms/avm/network/network.go @@ -19,8 +19,6 @@ import ( "github.com/ava-labs/avalanchego/vms/avm/txs/mempool" ) -const txGossipHandlerID = 0 - var ( _ common.AppHandler = (*Network)(nil) _ validators.Connector = (*Network)(nil) @@ -68,7 +66,7 @@ func New( config.MaxValidatorSetStaleness, ) txGossipClient := p2pNetwork.NewClient( - txGossipHandlerID, + p2p.TxGossipHandlerID, p2p.WithValidatorSampling(validators), ) txGossipMetrics, err := gossip.NewMetrics(registerer, "tx") @@ -157,7 +155,7 @@ func New( appRequestHandler: validatorHandler, } - if err := p2pNetwork.AddHandler(txGossipHandlerID, txGossipHandler); err != nil { + if err := p2pNetwork.AddHandler(p2p.TxGossipHandlerID, txGossipHandler); err != nil { return nil, err } diff --git a/vms/platformvm/network/network.go b/vms/platformvm/network/network.go index a43bb4b99aa1..c821c8272511 100644 --- a/vms/platformvm/network/network.go +++ b/vms/platformvm/network/network.go @@ -21,8 +21,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool" ) -const TxGossipHandlerID = 0 - var errMempoolDisabledWithPartialSync = errors.New("mempool is disabled partial syncing") type Network struct { @@ -66,7 +64,7 @@ func New( config.MaxValidatorSetStaleness, ) txGossipClient := p2pNetwork.NewClient( - TxGossipHandlerID, + p2p.TxGossipHandlerID, p2p.WithValidatorSampling(validators), ) txGossipMetrics, err := gossip.NewMetrics(registerer, "tx") @@ -154,7 +152,7 @@ func New( appRequestHandler: validatorHandler, } - if err := p2pNetwork.AddHandler(TxGossipHandlerID, txGossipHandler); err != nil { + if err := p2pNetwork.AddHandler(p2p.TxGossipHandlerID, txGossipHandler); err != nil { return nil, err } diff --git a/vms/platformvm/vm_regression_test.go b/vms/platformvm/vm_regression_test.go index c505f9b1a9e1..035573fd8ae8 100644 --- a/vms/platformvm/vm_regression_test.go +++ b/vms/platformvm/vm_regression_test.go @@ -37,7 +37,6 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/ava-labs/avalanchego/vms/platformvm/config" "github.com/ava-labs/avalanchego/vms/platformvm/metrics" - "github.com/ava-labs/avalanchego/vms/platformvm/network" "github.com/ava-labs/avalanchego/vms/platformvm/reward" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/state" @@ -2441,7 +2440,7 @@ func TestValidatorSetRaceCondition(t *testing.T) { require.NoError(err) appRequestBytes := p2p.PrefixMessage( - p2p.ProtocolPrefix(network.TxGossipHandlerID), + p2p.ProtocolPrefix(p2p.TxGossipHandlerID), protocolAppRequestBytest, ) From ccf785c7c87c0126aed0354d11d91173c283031b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladimir=20T=C3=A1mara=20Pati=C3=B1o?= Date: Mon, 29 Jul 2024 12:06:02 -0400 Subject: [PATCH 15/15] Storage OpenBSD/adJ (#2809) --- .../tmpnet/detached_process_default.go | 2 +- utils/storage/storage_openbsd.go | 19 +++++++++++++++++++ utils/storage/storage_unix.go | 4 ++-- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 utils/storage/storage_openbsd.go diff --git a/tests/fixture/tmpnet/detached_process_default.go b/tests/fixture/tmpnet/detached_process_default.go index 0e4b20ddd8e3..ee27243824b4 100644 --- a/tests/fixture/tmpnet/detached_process_default.go +++ b/tests/fixture/tmpnet/detached_process_default.go @@ -1,7 +1,7 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build linux || darwin +//go:build linux || darwin || unix package tmpnet diff --git a/utils/storage/storage_openbsd.go b/utils/storage/storage_openbsd.go new file mode 100644 index 000000000000..4206cae7a2fe --- /dev/null +++ b/utils/storage/storage_openbsd.go @@ -0,0 +1,19 @@ +// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +//go:build openbsd +// +build openbsd + +package storage + +import "syscall" + +func AvailableBytes(storagePath string) (uint64, error) { + var stat syscall.Statfs_t + err := syscall.Statfs(storagePath, &stat) + if err != nil { + return 0, err + } + avail := uint64(stat.F_bavail) * uint64(stat.F_bsize) + return avail, nil +} diff --git a/utils/storage/storage_unix.go b/utils/storage/storage_unix.go index 247bc2448f36..d4d46e9557d4 100644 --- a/utils/storage/storage_unix.go +++ b/utils/storage/storage_unix.go @@ -1,8 +1,8 @@ // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -//go:build !windows -// +build !windows +//go:build !windows && !openbsd +// +build !windows,!openbsd package storage