diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 282c8b72..3894c2f5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,13 +7,13 @@ on: pull_request: env: - go_version: '~1.21.7' + go_version: '~1.22.10' jobs: Build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-go@v2 with: go-version: ${{ env.go_version }} @@ -21,18 +21,18 @@ jobs: Test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v4 with: go-version: ${{ env.go_version }} - run: make test Lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: golangci/golangci-lint-action@v2 + - uses: actions/checkout@v4 + - uses: golangci/golangci-lint-action@v6 with: - version: v1.56.1 + version: v1.62.2 check_mockgen: name: Up-to-date mocks runs-on: ubuntu-latest diff --git a/.golangci.yml b/.golangci.yml index 575e591e..30dfba4d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -120,6 +120,7 @@ linters-settings: gosec: excludes: - G107 # Url provided to HTTP request as taint input https://securego.io/docs/rules/g107 + - G115 # TODO: use typesafe conversion for uint64 -> int64 importas: # Do not allow unaliased imports of aliased packages. no-unaliased: false diff --git a/Dockerfile b/Dockerfile index 07c07c0a..b1efe9c2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ # ------------------------------------------------------------------------------ # Build avalanche # ------------------------------------------------------------------------------ -FROM golang:1.21.12 AS avalanche +FROM golang:1.22.10 AS avalanche ARG AVALANCHE_VERSION @@ -16,7 +16,7 @@ RUN git checkout $AVALANCHE_VERSION && \ # ------------------------------------------------------------------------------ # Build avalanche rosetta # ------------------------------------------------------------------------------ -FROM golang:1.21.12 AS rosetta +FROM golang:1.22.10 AS rosetta ARG ROSETTA_VERSION diff --git a/Dockerfile.arm64 b/Dockerfile.arm64 index 2c44bbe1..392f5e2e 100644 --- a/Dockerfile.arm64 +++ b/Dockerfile.arm64 @@ -1,7 +1,7 @@ # ------------------------------------------------------------------------------ # Build avalanche # ------------------------------------------------------------------------------ -FROM arm64v8/golang:1.21.7-bullseye AS avalanche +FROM arm64v8/golang:1.22.10-bullseye AS avalanche ARG AVALANCHE_VERSION @@ -16,7 +16,7 @@ RUN git checkout $AVALANCHE_VERSION && \ # ------------------------------------------------------------------------------ # Build avalanche rosetta # ------------------------------------------------------------------------------ -FROM arm64v8/golang:1.21.7-bullseye AS rosetta +FROM arm64v8/golang:1.22.10-bullseye AS rosetta ARG ROSETTA_VERSION diff --git a/client/info_client.go b/client/info_client.go index fc14507a..76c79b5f 100644 --- a/client/info_client.go +++ b/client/info_client.go @@ -13,5 +13,5 @@ import ( type InfoClient interface { GetBlockchainID(context.Context, string, ...rpc.Option) (ids.ID, error) IsBootstrapped(context.Context, string, ...rpc.Option) (bool, error) - Peers(context.Context, ...rpc.Option) ([]info.Peer, error) + Peers(context.Context, []ids.NodeID, ...rpc.Option) ([]info.Peer, error) } diff --git a/client/mock_client.go b/client/mock_client.go index 78429c89..46e8c9c6 100644 --- a/client/mock_client.go +++ b/client/mock_client.go @@ -13,6 +13,7 @@ import ( context "context" big "math/big" reflect "reflect" + time "time" api "github.com/ava-labs/avalanchego/api" info "github.com/ava-labs/avalanchego/api/info" @@ -20,6 +21,7 @@ import ( indexer "github.com/ava-labs/avalanchego/indexer" rpc "github.com/ava-labs/avalanchego/utils/rpc" avm "github.com/ava-labs/avalanchego/vms/avm" + gas "github.com/ava-labs/avalanchego/vms/components/gas" platformvm "github.com/ava-labs/avalanchego/vms/platformvm" signer "github.com/ava-labs/avalanchego/vms/platformvm/signer" types "github.com/ava-labs/coreth/core/types" @@ -300,10 +302,10 @@ func (mr *MockClientMockRecorder) NonceAt(arg0, arg1, arg2 any) *gomock.Call { } // Peers mocks base method. -func (m *MockClient) Peers(arg0 context.Context, arg1 ...rpc.Option) ([]info.Peer, error) { +func (m *MockClient) Peers(arg0 context.Context, arg1 []ids.NodeID, arg2 ...rpc.Option) ([]info.Peer, error) { m.ctrl.T.Helper() - varargs := []any{arg0} - for _, a := range arg1 { + varargs := []any{arg0, arg1} + for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Peers", varargs...) @@ -313,9 +315,9 @@ func (m *MockClient) Peers(arg0 context.Context, arg1 ...rpc.Option) ([]info.Pee } // Peers indicates an expected call of Peers. -func (mr *MockClientMockRecorder) Peers(arg0 any, arg1 ...any) *gomock.Call { +func (mr *MockClientMockRecorder) Peers(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0}, arg1...) + varargs := append([]any{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peers", reflect.TypeOf((*MockClient)(nil).Peers), varargs...) } @@ -591,6 +593,28 @@ func (mr *MockPChainClientMockRecorder) GetCurrentValidators(arg0, arg1, arg2 an return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentValidators", reflect.TypeOf((*MockPChainClient)(nil).GetCurrentValidators), varargs...) } +// GetFeeState mocks base method. +func (m *MockPChainClient) GetFeeState(arg0 context.Context, arg1 ...rpc.Option) (gas.State, gas.Price, time.Time, error) { + m.ctrl.T.Helper() + varargs := []any{arg0} + for _, a := range arg1 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetFeeState", varargs...) + ret0, _ := ret[0].(gas.State) + ret1, _ := ret[1].(gas.Price) + ret2, _ := ret[2].(time.Time) + ret3, _ := ret[3].(error) + return ret0, ret1, ret2, ret3 +} + +// GetFeeState indicates an expected call of GetFeeState. +func (mr *MockPChainClientMockRecorder) GetFeeState(arg0 any, arg1 ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0}, arg1...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeeState", reflect.TypeOf((*MockPChainClient)(nil).GetFeeState), varargs...) +} + // GetHeight mocks base method. func (m *MockPChainClient) GetHeight(arg0 context.Context, arg1 ...rpc.Option) (uint64, error) { m.ctrl.T.Helper() @@ -797,10 +821,10 @@ func (mr *MockPChainClientMockRecorder) IssueTx(arg0, arg1 any, arg2 ...any) *go } // Peers mocks base method. -func (m *MockPChainClient) Peers(arg0 context.Context, arg1 ...rpc.Option) ([]info.Peer, error) { +func (m *MockPChainClient) Peers(arg0 context.Context, arg1 []ids.NodeID, arg2 ...rpc.Option) ([]info.Peer, error) { m.ctrl.T.Helper() - varargs := []any{arg0} - for _, a := range arg1 { + varargs := []any{arg0, arg1} + for _, a := range arg2 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Peers", varargs...) @@ -810,8 +834,8 @@ func (m *MockPChainClient) Peers(arg0 context.Context, arg1 ...rpc.Option) ([]in } // Peers indicates an expected call of Peers. -func (mr *MockPChainClientMockRecorder) Peers(arg0 any, arg1 ...any) *gomock.Call { +func (mr *MockPChainClientMockRecorder) Peers(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - varargs := append([]any{arg0}, arg1...) + varargs := append([]any{arg0, arg1}, arg2...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Peers", reflect.TypeOf((*MockPChainClient)(nil).Peers), varargs...) } diff --git a/client/pchainclient.go b/client/pchainclient.go index d1117e88..7cb7362f 100644 --- a/client/pchainclient.go +++ b/client/pchainclient.go @@ -3,6 +3,7 @@ package client import ( "context" "strings" + "time" "github.com/ava-labs/avalanchego/api" "github.com/ava-labs/avalanchego/api/info" @@ -10,6 +11,7 @@ import ( "github.com/ava-labs/avalanchego/indexer" "github.com/ava-labs/avalanchego/utils/rpc" "github.com/ava-labs/avalanchego/vms/avm" + "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/avalanchego/vms/platformvm" "github.com/ava-labs/avalanchego/vms/platformvm/signer" @@ -61,6 +63,7 @@ type PChainClient interface { IssueTx(ctx context.Context, tx []byte, options ...rpc.Option) (ids.ID, error) GetStake(ctx context.Context, addrs []ids.ShortID, validatorsOnly bool, options ...rpc.Option) (map[ids.ID]uint64, [][]byte, error) GetCurrentValidators(ctx context.Context, subnetID ids.ID, nodeIDs []ids.NodeID, options ...rpc.Option) ([]platformvm.ClientPermissionlessValidator, error) + GetFeeState(ctx context.Context, options ...rpc.Option) (gas.State, gas.Price, time.Time, error) // avm.Client methods GetAssetDescription(ctx context.Context, assetID string, options ...rpc.Option) (*avm.GetAssetDescriptionReply, error) diff --git a/constants/network.go b/constants/network.go index ad1cc3d3..6c406154 100644 --- a/constants/network.go +++ b/constants/network.go @@ -1,8 +1,8 @@ package constants import ( + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/utils/constants" - "github.com/ava-labs/coreth/params" ) const ( @@ -16,6 +16,11 @@ const ( ) var ( - MainnetAP5Activation = *params.AvalancheMainnetChainConfig.ApricotPhase5BlockTimestamp - FujiAP5Activation = *params.AvalancheFujiChainConfig.ApricotPhase5BlockTimestamp + mainnetUpgrades = upgrade.GetConfig(constants.MainnetID) + fujiUpgrades = upgrade.GetConfig(constants.FujiID) +) + +var ( + MainnetAP5Activation = uint64(mainnetUpgrades.ApricotPhase5Time.Unix()) + FujiAP5Activation = uint64(fujiUpgrades.ApricotPhase5Time.Unix()) ) diff --git a/go.mod b/go.mod index ca923175..381e5104 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,16 @@ module github.com/ava-labs/avalanche-rosetta -go 1.21.12 +go 1.22.10 require ( - github.com/ava-labs/avalanchego v1.11.9 - github.com/ava-labs/coreth v0.13.6-rc.1 + github.com/ava-labs/avalanchego v1.12.0 + github.com/ava-labs/coreth v0.13.9-rc.1 github.com/coinbase/rosetta-sdk-go v0.6.5 - github.com/ethereum/go-ethereum v1.13.8 - github.com/stretchr/testify v1.8.4 + github.com/ethereum/go-ethereum v1.13.14 + github.com/stretchr/testify v1.9.0 go.uber.org/mock v0.4.0 - golang.org/x/crypto v0.21.0 - golang.org/x/sync v0.6.0 + golang.org/x/crypto v0.26.0 + golang.org/x/sync v0.8.0 ) require ( @@ -23,7 +23,7 @@ require ( github.com/btcsuite/btcd/btcutil v1.1.3 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect @@ -41,14 +41,13 @@ require ( github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.13.0 // indirect - github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect @@ -59,11 +58,11 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/rpc v1.2.0 // indirect - github.com/gorilla/websocket v1.4.2 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/hashicorp/go-bexpr v0.1.10 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect - github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 // indirect + github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect github.com/holiman/uint256 v1.2.4 // indirect github.com/klauspost/compress v1.15.15 // indirect @@ -82,19 +81,19 @@ require ( github.com/pires/go-proxyproto v0.6.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_golang v1.16.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.7.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/segmentio/fasthash v1.0.3 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/spf13/cast v1.5.0 // indirect github.com/status-im/keycard-go v0.2.0 // indirect - github.com/supranational/blst v0.3.11 // indirect + github.com/supranational/blst v0.3.13 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect @@ -110,18 +109,18 @@ require ( go.opentelemetry.io/otel/sdk v1.22.0 // indirect go.opentelemetry.io/otel/trace v1.22.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect - go.uber.org/multierr v1.10.0 // indirect + go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20231127185646-65229373498e // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.3.0 // indirect gonum.org/v1/gonum v0.11.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect - google.golang.org/grpc v1.62.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect + google.golang.org/grpc v1.66.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 6e4a7593..c005d572 100644 --- a/go.sum +++ b/go.sum @@ -41,10 +41,10 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/avalanchego v1.11.9 h1:hPmnPADhyl/cOp6WNJKfJNW8zA644RioIMcAXSXG3TA= -github.com/ava-labs/avalanchego v1.11.9/go.mod h1:1dpLzXIVhAmJeRpl59l5GgcCEO9bDdF6Y6qRDTo0QGY= -github.com/ava-labs/coreth v0.13.6-rc.1 h1:gRXRokmu0WOlPqyx+mTLWB655e8/w++u6qFcq9Mo7qA= -github.com/ava-labs/coreth v0.13.6-rc.1/go.mod h1:vm9T8qzP7RLo/jR2MKkliPfaiGgWeEpu/PG6fvvPmog= +github.com/ava-labs/avalanchego v1.12.0 h1:NBx0vSOY1dCT0PeJzojIhNhx0NMQNem4GgTEN+v8Sx4= +github.com/ava-labs/avalanchego v1.12.0/go.mod h1:yhD5dpZyStIVbxQ550EDi5w5SL7DQ/xGE6TIxosb7U0= +github.com/ava-labs/coreth v0.13.9-rc.1 h1:qIICpC/OZGYUP37QnLgIqqwGmxnLwLpZaUlqJNI85vU= +github.com/ava-labs/coreth v0.13.9-rc.1/go.mod h1:7aMsRIo/3GBE44qWZMjnfqdqfcfZ5yShTTm2LObLaYo= github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -90,8 +90,9 @@ github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -178,8 +179,8 @@ github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHj github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.9.24/go.mod h1:JIfVb6esrqALTExdz9hRYvrP0xBDf6wCncIu1hNwHpM= -github.com/ethereum/go-ethereum v1.13.8 h1:1od+thJel3tM52ZUNQwvpYOeRHlbkVFZ5S8fhi0Lgsg= -github.com/ethereum/go-ethereum v1.13.8/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= +github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= +github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= @@ -187,8 +188,6 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -220,8 +219,9 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= @@ -241,8 +241,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= -github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -298,8 +298,8 @@ github.com/gorilla/rpc v1.2.0 h1:WvvdC2lNeT1SP32zrIce5l0ECBfbAlmrmSBsuc57wfk= github.com/gorilla/rpc v1.2.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ= github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= @@ -310,8 +310,8 @@ github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7 h1:3JQNjnMRil1yD0IfZKHF9GxxWKDJGj8I0IqOUol//sw= -github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.1.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= @@ -470,8 +470,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= -github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= @@ -489,8 +489,8 @@ github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRr github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= @@ -529,8 +529,8 @@ github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8 github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -538,10 +538,10 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= -github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= @@ -614,8 +614,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= -go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= -go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -632,8 +632,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20231127185646-65229373498e h1:Gvh4YaCaXNs6dKTlfgismwWZKyjVZXwOPfIyUaqU3No= @@ -680,8 +680,8 @@ golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -693,8 +693,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -735,15 +735,16 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -751,8 +752,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= @@ -788,20 +789,18 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= -google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 h1:Lj5rbfG876hIAYFjqiJnPHfhXbv+nzTWfm04Fg/XSVU= -google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80/go.mod h1:4jWUdICTdgc3Ibxmr8nAJiiLHwQBY0UI0XZcEMaFKaA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s= +google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 h1:+rdxYoE3E5htTEWIe15GlN6IfvbURM//Jt0mmkmm6ZU= +google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117/go.mod h1:OimBR/bc1wPO9iV4NC2bpyjy3VnAwZh5EBPQdtaE5oo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk= -google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= +google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/mapper/pchain/tx_dependency.go b/mapper/pchain/tx_dependency.go index be7e23f4..80658740 100644 --- a/mapper/pchain/tx_dependency.go +++ b/mapper/pchain/tx_dependency.go @@ -53,6 +53,16 @@ func GetTxDependenciesIDs(tx txs.UnsignedTx) ([]ids.ID, error) { ins = unsignedTx.Ins case *txs.TransferSubnetOwnershipTx: ins = unsignedTx.Ins + case *txs.ConvertSubnetToL1Tx: + ins = unsignedTx.Ins + case *txs.RegisterL1ValidatorTx: + ins = unsignedTx.Ins + case *txs.IncreaseL1ValidatorBalanceTx: + ins = unsignedTx.Ins + case *txs.SetL1ValidatorWeightTx: + ins = unsignedTx.Ins + case *txs.DisableL1ValidatorTx: + ins = unsignedTx.Ins case *txs.BaseTx: ins = unsignedTx.Ins default: @@ -167,6 +177,16 @@ func (d *SingleTxDependency) GetUtxos() map[avax.UTXOID]*avax.UTXO { outsToAdd = append(outsToAdd, unsignedTx.Stake()...) case *txs.TransferSubnetOwnershipTx: outsToAdd = append(outsToAdd, unsignedTx.Outputs()...) + case *txs.ConvertSubnetToL1Tx: + outsToAdd = append(outsToAdd, unsignedTx.Outputs()...) + case *txs.RegisterL1ValidatorTx: + outsToAdd = append(outsToAdd, unsignedTx.Outputs()...) + case *txs.IncreaseL1ValidatorBalanceTx: + outsToAdd = append(outsToAdd, unsignedTx.Outputs()...) + case *txs.SetL1ValidatorWeightTx: + outsToAdd = append(outsToAdd, unsignedTx.Outputs()...) + case *txs.DisableL1ValidatorTx: + outsToAdd = append(outsToAdd, unsignedTx.Outputs()...) case *txs.BaseTx: outsToAdd = append(outsToAdd, unsignedTx.Outputs()...) default: diff --git a/mapper/pchain/tx_parser.go b/mapper/pchain/tx_parser.go index c8a4edae..0f0ad2e7 100644 --- a/mapper/pchain/tx_parser.go +++ b/mapper/pchain/tx_parser.go @@ -167,6 +167,21 @@ func (t *TxParser) Parse(signedTx *txs.Tx) (*types.Transaction, error) { case *txs.TransferSubnetOwnershipTx: txType = OpTransferSubnetOwnership ops, err = t.parseTransferSubnetOwnershipTx(txID, unsignedTx) + case *txs.ConvertSubnetToL1Tx: + txType = OpConvertSubnetToL1Tx + ops, err = t.parseConvertSubnetToL1Tx(txID, unsignedTx) + case *txs.RegisterL1ValidatorTx: + txType = OpRegisterL1ValidatorTx + ops, err = t.parseRegisterL1ValidatorTx(txID, unsignedTx) + case *txs.IncreaseL1ValidatorBalanceTx: + txType = OpIncreaseL1ValidatorBalanceTx + ops, err = t.parseIncreaseL1ValidatorBalanceTx(txID, unsignedTx) + case *txs.SetL1ValidatorWeightTx: + txType = OpSetL1ValidatorWeightTx + ops, err = t.parseSetL1ValidatorWeightTx(txID, unsignedTx) + case *txs.DisableL1ValidatorTx: + txType = OpDisableL1ValidatorTx + ops, err = t.parseDisableL1ValidatorTx(txID, unsignedTx) case *txs.BaseTx: txType = OpBase ops, err = t.parseBaseTx(txID, unsignedTx) @@ -420,6 +435,26 @@ func (t *TxParser) parseCreateChainTx(txID ids.ID, tx *txs.CreateChainTx) (*txOp return t.baseTxToCombinedOperations(txID, &tx.BaseTx, OpCreateChain) } +func (t *TxParser) parseConvertSubnetToL1Tx(txID ids.ID, tx *txs.ConvertSubnetToL1Tx) (*txOps, error) { + return t.baseTxToCombinedOperations(txID, &tx.BaseTx, OpConvertSubnetToL1Tx) +} + +func (t *TxParser) parseRegisterL1ValidatorTx(txID ids.ID, tx *txs.RegisterL1ValidatorTx) (*txOps, error) { + return t.baseTxToCombinedOperations(txID, &tx.BaseTx, OpRegisterL1ValidatorTx) +} + +func (t *TxParser) parseIncreaseL1ValidatorBalanceTx(txID ids.ID, tx *txs.IncreaseL1ValidatorBalanceTx) (*txOps, error) { + return t.baseTxToCombinedOperations(txID, &tx.BaseTx, OpIncreaseL1ValidatorBalanceTx) +} + +func (t *TxParser) parseSetL1ValidatorWeightTx(txID ids.ID, tx *txs.SetL1ValidatorWeightTx) (*txOps, error) { + return t.baseTxToCombinedOperations(txID, &tx.BaseTx, OpSetL1ValidatorWeightTx) +} + +func (t *TxParser) parseDisableL1ValidatorTx(txID ids.ID, tx *txs.DisableL1ValidatorTx) (*txOps, error) { + return t.baseTxToCombinedOperations(txID, &tx.BaseTx, OpDisableL1ValidatorTx) +} + func (t *TxParser) baseTxToCombinedOperations(txID ids.ID, tx *txs.BaseTx, txType string) (*txOps, error) { ops := newTxOps(t.cfg.IsConstruction) @@ -730,6 +765,13 @@ func (t *TxParser) isMultisig(utxoid avax.UTXOID) (bool, error) { utxoMap := dependencyTx.GetUtxos() utxo, ok := utxoMap[utxoid] if !ok { + // Consider the UTXO as multisig if it is not found in the dependency tx. + // Possible for dependency txs like [DisableL1ValidatorTx] or [SetL1ValidatorWeightTx]. + // These unfound UTXOs are generated by the network but are not included in the tx bytes. + switch dependencyTx.Tx.Unsigned.(type) { + case *txs.DisableL1ValidatorTx, *txs.SetL1ValidatorWeightTx: + return true, nil + } return false, errFailedToCheckMultisig } diff --git a/mapper/pchain/types.go b/mapper/pchain/types.go index 3c8c1789..cf65da9e 100644 --- a/mapper/pchain/types.go +++ b/mapper/pchain/types.go @@ -2,24 +2,30 @@ package pchain import ( "github.com/ava-labs/avalanchego/ids" + "github.com/coinbase/rosetta-sdk-go/parser" ) const ( - OpImportAvax = "IMPORT_AVAX" - OpExportAvax = "EXPORT_AVAX" - OpAddValidator = "ADD_VALIDATOR" - OpAddPermissionlessValidator = "ADD_PERMISSIONLESS_VALIDATOR" - OpAddDelegator = "ADD_DELEGATOR" - OpAddPermissionlessDelegator = "ADD_PERMISSIONLESS_DELEGATOR" - OpRewardValidator = "REWARD_VALIDATOR" - OpCreateChain = "CREATE_CHAIN" - OpCreateSubnet = "CREATE_SUBNET" - OpAddSubnetValidator = "ADD_SUBNET_VALIDATOR" - OpRemoveSubnetValidator = "REMOVE_SUBNET_VALIDATOR" - OpTransformSubnetValidator = "TRANSFORM_SUBNET_VALIDATOR" - OpAdvanceTime = "ADVANCE_TIME" - OpBase = "BASE" - OpTransferSubnetOwnership = "TRANSFER_SUBNET_OWNERSHIP" + OpImportAvax = "IMPORT_AVAX" + OpExportAvax = "EXPORT_AVAX" + OpAddValidator = "ADD_VALIDATOR" + OpAddPermissionlessValidator = "ADD_PERMISSIONLESS_VALIDATOR" + OpAddDelegator = "ADD_DELEGATOR" + OpAddPermissionlessDelegator = "ADD_PERMISSIONLESS_DELEGATOR" + OpRewardValidator = "REWARD_VALIDATOR" + OpCreateChain = "CREATE_CHAIN" + OpCreateSubnet = "CREATE_SUBNET" + OpAddSubnetValidator = "ADD_SUBNET_VALIDATOR" + OpRemoveSubnetValidator = "REMOVE_SUBNET_VALIDATOR" + OpTransformSubnetValidator = "TRANSFORM_SUBNET_VALIDATOR" + OpAdvanceTime = "ADVANCE_TIME" + OpBase = "BASE" + OpTransferSubnetOwnership = "TRANSFER_SUBNET_OWNERSHIP" + OpConvertSubnetToL1Tx = "CONVERT_SUBNET_TO_L1_TX" + OpRegisterL1ValidatorTx = "REGISTER_L1_VALIDATOR_TX" + OpIncreaseL1ValidatorBalanceTx = "INCREASE_L1_VALIDATOR_BALANCE_TX" + OpSetL1ValidatorWeightTx = "SET_L1_VALIDATOR_WEIGHT_TX" + OpDisableL1ValidatorTx = "DISABLE_L1_VALIDATOR_TX" OpTypeImport = "IMPORT" OpTypeExport = "EXPORT" @@ -37,6 +43,9 @@ const ( MetadataMessage = "message" MetadataSigner = "signer" + MetadataBaseFee = "base_fee" + MetadataMatches = "matches" + MetadataValidatorRewards = "validator_rewards" MetadataValidatorRewardsOwner = "validator_rewards_owner" MetadataDelegationRewardsOwner = "delegation_rewards_owner" @@ -72,10 +81,11 @@ var ( // OperationMetadata contains metadata fields specific to individual Rosetta operations as opposed to transactions type OperationMetadata struct { - Type string `json:"type"` - SigIndices []uint32 `json:"sig_indices,omitempty"` - Locktime uint64 `json:"locktime"` - Threshold uint32 `json:"threshold,omitempty"` + Type string `json:"type"` + SigIndices []uint32 `json:"sig_indices,omitempty"` + Locktime uint64 `json:"locktime"` + Threshold uint32 `json:"threshold,omitempty"` + Matches []*parser.Match `json:"matches,omitempty"` } // ImportExportOptions contain response fields returned by /construction/preprocess for P-chain Import/Export transactions diff --git a/service/backend/pchain/backend.go b/service/backend/pchain/backend.go index 6de21859..02efc1f1 100644 --- a/service/backend/pchain/backend.go +++ b/service/backend/pchain/backend.go @@ -2,7 +2,9 @@ package pchain import ( "github.com/ava-labs/avalanchego/codec" + "github.com/ava-labs/avalanchego/genesis" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/avalanchego/vms/platformvm/block" "github.com/coinbase/rosetta-sdk-go/types" @@ -34,6 +36,8 @@ type Backend struct { codecVersion uint16 avaxAssetID ids.ID txParserCfg pmapper.TxParserConfig + upgradeConfig upgrade.Config + feeConfig genesis.TxFeeConfig } // NewBackend creates a P-chain service backend @@ -54,6 +58,9 @@ func NewBackend( return nil, err } + upgradeConfig := upgrade.GetConfig(avalancheNetworkID) + feeConfig := genesis.GetTxFeeConfig(avalancheNetworkID) + return &Backend{ genesisHandler: genHandler, networkID: networkIdentifier, @@ -72,6 +79,8 @@ func NewBackend( AvaxAssetID: avaxAssetID, PChainClient: pClient, }, + upgradeConfig: upgradeConfig, + feeConfig: feeConfig, }, nil } diff --git a/service/backend/pchain/construction.go b/service/backend/pchain/construction.go index fbaba57c..dd3475f8 100644 --- a/service/backend/pchain/construction.go +++ b/service/backend/pchain/construction.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "math/big" + "time" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/rpc" @@ -19,6 +20,7 @@ import ( "github.com/ava-labs/avalanche-rosetta/service/backend/common" pmapper "github.com/ava-labs/avalanche-rosetta/mapper/pchain" + txfee "github.com/ava-labs/avalanchego/vms/platformvm/txs/fee" ) var ( @@ -45,7 +47,9 @@ func (*Backend) ConstructionPreprocess( if reqMetadata == nil { reqMetadata = make(map[string]interface{}) } + reqMetadata[pmapper.MetadataOpType] = matches[0].Operations[0].Type + reqMetadata[pmapper.MetadataMatches] = matches return &types.ConstructionPreprocessResponse{ Options: reqMetadata, @@ -62,15 +66,21 @@ func (b *Backend) ConstructionMetadata( return nil, service.WrapError(service.ErrInvalidInput, err) } - var suggestedFee *types.Amount + if opMetadata.Matches == nil { + return nil, service.WrapError(service.ErrInvalidInput, errors.New("matches not found in options")) + } + var metadata *pmapper.Metadata switch opMetadata.Type { case pmapper.OpImportAvax: - metadata, suggestedFee, err = b.buildImportMetadata(ctx, req.Options) + metadata, err = b.buildImportMetadata(ctx, req.Options) case pmapper.OpExportAvax: - metadata, suggestedFee, err = b.buildExportMetadata(ctx, req.Options) + metadata, err = b.buildExportMetadata(ctx, req.Options) case pmapper.OpAddValidator, pmapper.OpAddDelegator, pmapper.OpAddPermissionlessDelegator, pmapper.OpAddPermissionlessValidator: - metadata, suggestedFee, err = buildStakingMetadata(req.Options) + metadata, err = b.buildStakingMetadata(ctx, req.Options) + if err != nil { + return nil, service.WrapError(service.ErrInternalError, err) + } metadata.Threshold = opMetadata.Threshold metadata.Locktime = opMetadata.Locktime @@ -84,6 +94,22 @@ func (b *Backend) ConstructionMetadata( return nil, service.WrapError(service.ErrInternalError, err) } + // Suggested fee calculation + tx, _, err := pmapper.BuildTx( + opMetadata.Type, + opMetadata.Matches, + *metadata, + b.codec, + b.avaxAssetID, + ) + if err != nil { + return nil, service.WrapError(service.ErrInternalError, err) + } + suggestedFee, err := b.calculateFee(ctx, tx) + if err != nil { + return nil, service.WrapError(service.ErrInternalError, err) + } + pChainID, err := b.pClient.GetBlockchainID(ctx, constants.PChain.String()) if err != nil { return nil, service.WrapError(service.ErrInvalidInput, err) @@ -97,49 +123,46 @@ func (b *Backend) ConstructionMetadata( return nil, service.WrapError(service.ErrInternalError, err) } + suggestedFeeAvax := mapper.AtomicAvaxAmount(big.NewInt(int64(suggestedFee))) return &types.ConstructionMetadataResponse{ Metadata: metadataMap, - SuggestedFee: []*types.Amount{suggestedFee}, + SuggestedFee: []*types.Amount{suggestedFeeAvax}, }, nil } -func (b *Backend) buildImportMetadata(ctx context.Context, options map[string]interface{}) (*pmapper.Metadata, *types.Amount, error) { +func (b *Backend) buildImportMetadata( + ctx context.Context, + options map[string]interface{}, +) (*pmapper.Metadata, error) { var preprocessOptions pmapper.ImportExportOptions if err := mapper.UnmarshalJSONMap(options, &preprocessOptions); err != nil { - return nil, nil, err + return nil, err } sourceChainID, err := b.pClient.GetBlockchainID(ctx, preprocessOptions.SourceChain) if err != nil { - return nil, nil, err - } - - suggestedFee, err := b.getBaseTxFee(ctx) - if err != nil { - return nil, nil, err + return nil, err } importMetadata := &pmapper.ImportMetadata{ SourceChainID: sourceChainID, } - return &pmapper.Metadata{ImportMetadata: importMetadata}, suggestedFee, nil + return &pmapper.Metadata{ImportMetadata: importMetadata}, nil } -func (b *Backend) buildExportMetadata(ctx context.Context, options map[string]interface{}) (*pmapper.Metadata, *types.Amount, error) { +func (b *Backend) buildExportMetadata( + ctx context.Context, + options map[string]interface{}, +) (*pmapper.Metadata, error) { var preprocessOptions pmapper.ImportExportOptions if err := mapper.UnmarshalJSONMap(options, &preprocessOptions); err != nil { - return nil, nil, err + return nil, err } destinationChainID, err := b.pClient.GetBlockchainID(ctx, preprocessOptions.DestinationChain) if err != nil { - return nil, nil, err - } - - suggestedFee, err := b.getBaseTxFee(ctx) - if err != nil { - return nil, nil, err + return nil, err } exportMetadata := &pmapper.ExportMetadata{ @@ -147,17 +170,19 @@ func (b *Backend) buildExportMetadata(ctx context.Context, options map[string]in DestinationChainID: destinationChainID, } - return &pmapper.Metadata{ExportMetadata: exportMetadata}, suggestedFee, nil + return &pmapper.Metadata{ExportMetadata: exportMetadata}, nil } -func buildStakingMetadata(options map[string]interface{}) (*pmapper.Metadata, *types.Amount, error) { +func (*Backend) buildStakingMetadata( + _ context.Context, + options map[string]interface{}, +) (*pmapper.Metadata, error) { var preprocessOptions pmapper.StakingOptions if err := mapper.UnmarshalJSONMap(options, &preprocessOptions); err != nil { - return nil, nil, err + return nil, err } - zeroAvax := mapper.AtomicAvaxAmount(big.NewInt(0)) - return &pmapper.Metadata{ + stakingMetadata := &pmapper.Metadata{ StakingMetadata: &pmapper.StakingMetadata{ NodeID: preprocessOptions.NodeID, BLSPublicKey: preprocessOptions.BLSPublicKey, @@ -171,18 +196,9 @@ func buildStakingMetadata(options map[string]interface{}) (*pmapper.Metadata, *t Locktime: preprocessOptions.Locktime, Threshold: preprocessOptions.Threshold, }, - }, zeroAvax, nil -} - -func (b *Backend) getBaseTxFee(ctx context.Context) (*types.Amount, error) { - fees, err := b.pClient.GetTxFee(ctx) - if err != nil { - return nil, err } - feeAmount := new(big.Int).SetUint64(uint64(fees.TxFee)) - suggestedFee := mapper.AtomicAvaxAmount(feeAmount) - return suggestedFee, nil + return stakingMetadata, nil } // ConstructionPayloads implements /construction/payloads endpoint for P-chain @@ -261,6 +277,42 @@ func (*Backend) CombineTx(tx common.AvaxTx, signatures []*types.Signature) (comm return pTx, nil } +func (b *Backend) calculateFee(ctx context.Context, tx *txs.Tx) (uint64, error) { + feeCalculator, err := b.PickFeeCalculator(ctx, time.Now()) + if err != nil { + return 0, err + } + fee, err := feeCalculator.CalculateFee(tx.Unsigned) + if err != nil { + return 0, err + } + return fee, nil +} + +func (b *Backend) PickFeeCalculator(ctx context.Context, timestamp time.Time) (txfee.Calculator, error) { + if !b.upgradeConfig.IsEtnaActivated(timestamp) { + return b.NewStaticFeeCalculator(timestamp), nil + } + + _, gasPrice, _, err := b.pClient.GetFeeState(ctx) + if err != nil { + return nil, err + } + return txfee.NewDynamicCalculator( + b.feeConfig.DynamicFeeConfig.Weights, + gasPrice, + ), nil +} + +func (b *Backend) NewStaticFeeCalculator(timestamp time.Time) txfee.Calculator { + feeConfig := b.feeConfig.StaticFeeConfig + if !b.upgradeConfig.IsApricotPhase3Activated(timestamp) { + feeConfig.CreateSubnetTxFee = b.feeConfig.CreateAssetTxFee + feeConfig.CreateBlockchainTxFee = b.feeConfig.CreateAssetTxFee + } + return txfee.NewStaticCalculator(feeConfig) +} + // getTxInputs fetches tx inputs based on the tx type. func getTxInputs( unsignedTx txs.UnsignedTx, @@ -294,6 +346,16 @@ func getTxInputs( return utx.Ins, nil case *txs.TransferSubnetOwnershipTx: return utx.Ins, nil + case *txs.ConvertSubnetToL1Tx: + return utx.Ins, nil + case *txs.RegisterL1ValidatorTx: + return utx.Ins, nil + case *txs.IncreaseL1ValidatorBalanceTx: + return utx.Ins, nil + case *txs.SetL1ValidatorWeightTx: + return utx.Ins, nil + case *txs.DisableL1ValidatorTx: + return utx.Ins, nil case *txs.BaseTx: return utx.Ins, nil default: diff --git a/service/backend/pchain/construction_test.go b/service/backend/pchain/construction_test.go index 14921f3d..d9732570 100644 --- a/service/backend/pchain/construction_test.go +++ b/service/backend/pchain/construction_test.go @@ -7,9 +7,13 @@ import ( "fmt" "math/big" "testing" + "time" - "github.com/ava-labs/avalanchego/api/info" "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/upgrade" + "github.com/ava-labs/avalanchego/utils/formatting" + "github.com/ava-labs/avalanchego/vms/components/gas" + "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/coinbase/rosetta-sdk-go/types" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -23,7 +27,6 @@ import ( pmapper "github.com/ava-labs/avalanche-rosetta/mapper/pchain" avaconstants "github.com/ava-labs/avalanchego/utils/constants" - avajson "github.com/ava-labs/avalanchego/utils/json" ) var ( @@ -37,7 +40,11 @@ var ( cAccountIdentifier = &types.AccountIdentifier{Address: "C-fuji123zu6qwhtd9qdd45ryu3j0qtr325gjgddys6u8"} pAccountIdentifier = &types.AccountIdentifier{Address: "P-fuji123zu6qwhtd9qdd45ryu3j0qtr325gjgddys6u8"} - stakeRewardAccount = &types.AccountIdentifier{Address: "P-fuji1ea7dxk8zazpyf8tgc8yg3xyfatey0deqvg9pv2"} + + // ewok account identifiers + // Public Key (hex): 0327448e78ffa8cdb24cf19be0204ad954b1bdb4db8c51183534c1eecf2ebd094e + // Private Key: PrivateKey-ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN + ewoqAccountP = &types.AccountIdentifier{Address: "P-fuji18jma8ppw3nhx5r4ap8clazz0dps7rv5u6wmu4t"} cChainID, _ = ids.FromString("yH8D7ThNJkxmtkuv2jgBa4P1Rn3Qpr4pPr7QYNfcdoS6k6HWp") pChainID = ids.Empty @@ -48,11 +55,21 @@ var ( avaxAssetID, _ = ids.FromString("U8iRqJoiJm8xZHAacmvYyZVwqQx6uDNtQeP3CQ6fcgQk3JqnK") - txFee = 1_000_000 - coinID1 = "2ryRVCwNSjEinTViuvDkzX41uQzx3g4babXxZMD46ZV1a9X4Eg:0" + + gasPrice = gas.Price(1000) + + sampleBlsPublicKey = "0x90f8c7a0425d6b433fb1bd95b41ef76221cdd05d922247356912abfb14db1642ae410bd627052b023e1ea7fb49a909ff" + sampleProofOfPossession = "0x8df4c907d6d41db47fbe12834789c10572805e61d32d09411ccc3a1d10ea3a978496d6449eb802bc721fed1571ef251300e83bfd41573947b63d4ce631c8724d98b087d0f10ae05426f52e13656be277531fc459f82400e66822d514073bcb7b" ) +func shouldMockGetFeeState(clientMock *client.MockPChainClient) { + upgradeConfig := upgrade.GetConfig(avalancheNetworkID) + if upgradeConfig.IsEtnaActivated(time.Now()) { + clientMock.EXPECT().GetFeeState(context.Background()).Return(gas.State{}, gasPrice, time.Time{}, nil) + } +} + func buildRosettaSignerJSON(coinIdentifiers []string, signers []*types.AccountIdentifier) string { importSigners := []*common.Signer{} for i, s := range signers { @@ -136,6 +153,9 @@ func TestExportTxConstruction(t *testing.T) { }, } + matches, err := common.MatchOperations(exportOperations) + require.NoError(t, err) + preprocessMetadata := map[string]interface{}{ "destination_chain": constants.CChain.String(), } @@ -143,6 +163,7 @@ func TestExportTxConstruction(t *testing.T) { metadataOptions := map[string]interface{}{ "destination_chain": constants.CChain.String(), "type": pmapper.OpExportAvax, + "matches": matches, } payloadsMetadata := map[string]interface{}{ @@ -214,7 +235,7 @@ func TestExportTxConstruction(t *testing.T) { }) t.Run("metadata endpoint", func(t *testing.T) { - clientMock.EXPECT().GetTxFee(ctx).Return(&info.GetTxFeeResponse{TxFee: avajson.Uint64(txFee)}, nil) + shouldMockGetFeeState(clientMock) clientMock.EXPECT().GetBlockchainID(ctx, constants.PChain.String()).Return(pChainID, nil) clientMock.EXPECT().GetBlockchainID(ctx, constants.CChain.String()).Return(cChainID, nil) @@ -348,6 +369,9 @@ func TestImportTxConstruction(t *testing.T) { }, } + matches, err := common.MatchOperations(importOperations) + require.NoError(t, err) + preprocessMetadata := map[string]interface{}{ "source_chain": constants.CChain.String(), } @@ -355,6 +379,7 @@ func TestImportTxConstruction(t *testing.T) { metadataOptions := map[string]interface{}{ "source_chain": constants.CChain.String(), "type": pmapper.OpImportAvax, + "matches": matches, } payloadsMetadata := map[string]interface{}{ @@ -369,7 +394,7 @@ func TestImportTxConstruction(t *testing.T) { unsignedImportTx := "0x000000000011000000050000000000000000000000000000000000000000000000000000000000000000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000000003b8b87c0000000000000000000000001000000015445cd01d75b4a06b6b41939193c0b1c5544490d00000000000000007fc93d85c6d62c5b2ac0b519c87010ea5294012d1e407030d6acd0021cac10d500000001f52a5a6dd8f1b3fe05204bdab4f6bcb5a7059f88d0443c636f6c158f838dd1a8000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000000003b9aca000000000100000000000000004ce8b27d" unsignedImportTxHash, err := hex.DecodeString("e9114ae12065d1f8631bc40729c806a3a4793de714001bfee66482f520dc1865") require.NoError(t, err) - wrappedUnsignedImportTx := `{"tx":"` + unsignedImportTx + `","signers":` + importSigners + `}` //nolint:goconst + wrappedUnsignedImportTx := `{"tx":"` + unsignedImportTx + `","signers":` + importSigners + `}` signingPayloads := []*types.SigningPayload{ { @@ -424,7 +449,7 @@ func TestImportTxConstruction(t *testing.T) { }) t.Run("metadata endpoint", func(t *testing.T) { - clientMock.EXPECT().GetTxFee(ctx).Return(&info.GetTxFeeResponse{TxFee: avajson.Uint64(txFee)}, nil) + shouldMockGetFeeState(clientMock) clientMock.EXPECT().GetBlockchainID(ctx, constants.PChain.String()).Return(pChainID, nil) clientMock.EXPECT().GetBlockchainID(ctx, constants.CChain.String()).Return(cChainID, nil) @@ -531,13 +556,15 @@ func TestAddValidatorTxConstruction(t *testing.T) { startTime := uint64(1659592163) endTime := startTime + 14*86400 shares := uint32(200000) + pop, err := parsePoP(sampleBlsPublicKey, sampleProofOfPossession) + require.NoError(t, err) operations := []*types.Operation{ { OperationIdentifier: &types.OperationIdentifier{Index: 0}, RelatedOperations: nil, - Type: pmapper.OpAddValidator, - Account: pAccountIdentifier, + Type: pmapper.OpAddPermissionlessValidator, + Account: ewoqAccountP, Amount: mapper.AtomicAvaxAmount(big.NewInt(-2_000_000_000_000)), CoinChange: &types.CoinChange{ CoinIdentifier: &types.CoinIdentifier{Identifier: coinID1}, @@ -551,8 +578,8 @@ func TestAddValidatorTxConstruction(t *testing.T) { }, { OperationIdentifier: &types.OperationIdentifier{Index: 1}, - Type: pmapper.OpAddValidator, - Account: pAccountIdentifier, + Type: pmapper.OpAddPermissionlessValidator, + Account: ewoqAccountP, Amount: mapper.AtomicAvaxAmount(big.NewInt(2_000_000_000_000)), Metadata: map[string]interface{}{ "type": pmapper.OpTypeStakeOutput, @@ -564,27 +591,36 @@ func TestAddValidatorTxConstruction(t *testing.T) { "staking_end_time": endTime, "validator_node_id": nodeID, "subnet_id": pChainID.String(), - "delegation_rewards_owner": []string{stakeRewardAccount.Address}, - "validator_rewards_owner": []string{stakeRewardAccount.Address}, + "delegation_rewards_owner": []string{ewoqAccountP.Address}, + "validator_rewards_owner": []string{ewoqAccountP.Address}, + "signer": pop, }, }, } + matches, err := common.MatchOperations(operations) + require.NoError(t, err) + preprocessMetadata := map[string]interface{}{ - "node_id": nodeID, - "start": startTime, - "end": endTime, - "shares": shares, - "reward_addresses": []string{stakeRewardAccount.Address}, + "node_id": nodeID, + "start": startTime, + "end": endTime, + "shares": shares, + "reward_addresses": []string{ewoqAccountP.Address}, + "bls_public_key": sampleBlsPublicKey, + "bls_proof_of_possession": sampleProofOfPossession, } metadataOptions := map[string]interface{}{ - "type": pmapper.OpAddValidator, - "node_id": nodeID, - "start": startTime, - "end": endTime, - "shares": shares, - "reward_addresses": []string{stakeRewardAccount.Address}, + "type": pmapper.OpAddPermissionlessValidator, + "node_id": nodeID, + "start": startTime, + "end": endTime, + "shares": shares, + "reward_addresses": []string{ewoqAccountP.Address}, + "bls_public_key": sampleBlsPublicKey, + "bls_proof_of_possession": sampleProofOfPossession, + "matches": matches, } payloadsMetadata := map[string]interface{}{ @@ -597,38 +633,38 @@ func TestAddValidatorTxConstruction(t *testing.T) { "locktime": 0.0, "subnet": "", "threshold": 1.0, - "reward_addresses": []interface{}{stakeRewardAccount.Address}, + "reward_addresses": []interface{}{ewoqAccountP.Address}, "delegator_reward_addresses": nil, - "bls_proof_of_possession": "", - "bls_public_key": "", + "bls_proof_of_possession": sampleProofOfPossession, + "bls_public_key": sampleBlsPublicKey, } - signers := []*types.AccountIdentifier{pAccountIdentifier} + signers := []*types.AccountIdentifier{ewoqAccountP} stakeSigners := buildRosettaSignerJSON([]string{coinID1}, signers) - unsignedTx := "0x00000000000c0000000500000000000000000000000000000000000000000000000000000000000000000000000000000001f52a5a6dd8f1b3fe05204bdab4f6bcb5a7059f88d0443c636f6c158f838dd1a8000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000001d1a94a200000000001000000000000000077e1d5c6c289c49976f744749d54369d2129d7500000000062eb5de30000000062fdd2e3000001d1a94a2000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000001d1a94a2000000000000000000000000001000000015445cd01d75b4a06b6b41939193c0b1c5544490d0000000b00000000000000000000000100000001cf7cd358e2e882449d68c1c8889889eaf247b72000030d4000000000482f5298" - unsignedTxHash, err := hex.DecodeString("00c9e13de9f32b5808e54c024b15bdeee5925cbb918d90a272def046cedae800") + unsignedTx := "0x0000000000190000000500000000000000000000000000000000000000000000000000000000000000000000000000000001f52a5a6dd8f1b3fe05204bdab4f6bcb5a7059f88d0443c636f6c158f838dd1a8000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000001d1a94a200000000001000000000000000077e1d5c6c289c49976f744749d54369d2129d7500000000062eb5de30000000062fdd2e3000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001c90f8c7a0425d6b433fb1bd95b41ef76221cdd05d922247356912abfb14db1642ae410bd627052b023e1ea7fb49a909ff8df4c907d6d41db47fbe12834789c10572805e61d32d09411ccc3a1d10ea3a978496d6449eb802bc721fed1571ef251300e83bfd41573947b63d4ce631c8724d98b087d0f10ae05426f52e13656be277531fc459f82400e66822d514073bcb7b000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00030d4000000000354ff86b" + unsignedTxHash, err := hex.DecodeString("eb8d33435e683be27907d990c374e64680db91310f3c66e0220f404b5d2433a3") require.NoError(t, err) wrappedUnsignedTx := `{"tx":"` + unsignedTx + `","signers":` + stakeSigners + `}` signingPayloads := []*types.SigningPayload{ { - AccountIdentifier: pAccountIdentifier, + AccountIdentifier: ewoqAccountP, Bytes: unsignedTxHash, SignatureType: types.EcdsaRecovery, }, } - signedTx := "0x00000000000c0000000500000000000000000000000000000000000000000000000000000000000000000000000000000001f52a5a6dd8f1b3fe05204bdab4f6bcb5a7059f88d0443c636f6c158f838dd1a8000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000001d1a94a200000000001000000000000000077e1d5c6c289c49976f744749d54369d2129d7500000000062eb5de30000000062fdd2e3000001d1a94a2000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000001d1a94a2000000000000000000000000001000000015445cd01d75b4a06b6b41939193c0b1c5544490d0000000b00000000000000000000000100000001cf7cd358e2e882449d68c1c8889889eaf247b72000030d400000000100000009000000017403e32bb967e71902a988b7da635b4bca2475eedbfd23176610a88162f3a92f20b61f2185825b04b7f8ee8c76427c8dc80eb6091f9e594ef259a59856e5401b01e228f820" - signedTxSignature, err := hex.DecodeString("7403e32bb967e71902a988b7da635b4bca2475eedbfd23176610a88162f3a92f20b61f2185825b04b7f8ee8c76427c8dc80eb6091f9e594ef259a59856e5401b01") + signedTx := "0x0000000000190000000500000000000000000000000000000000000000000000000000000000000000000000000000000001f52a5a6dd8f1b3fe05204bdab4f6bcb5a7059f88d0443c636f6c158f838dd1a8000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000005000001d1a94a200000000001000000000000000077e1d5c6c289c49976f744749d54369d2129d7500000000062eb5de30000000062fdd2e3000001d1a94a200000000000000000000000000000000000000000000000000000000000000000000000001c90f8c7a0425d6b433fb1bd95b41ef76221cdd05d922247356912abfb14db1642ae410bd627052b023e1ea7fb49a909ff8df4c907d6d41db47fbe12834789c10572805e61d32d09411ccc3a1d10ea3a978496d6449eb802bc721fed1571ef251300e83bfd41573947b63d4ce631c8724d98b087d0f10ae05426f52e13656be277531fc459f82400e66822d514073bcb7b000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa00000007000001d1a94a2000000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00030d4000000001000000090000000137d7f04741b3492cb9ad8dbeda64513e569a049a5e5fb5d9c53e27bdfa428acb5b526a45fb9de09b38f1d2f4bb7c0a35bfa753e46c5cc339c0d9a0d9ed0aa415019f1a796e" + signedTxSignature, err := hex.DecodeString("37d7f04741b3492cb9ad8dbeda64513e569a049a5e5fb5d9c53e27bdfa428acb5b526a45fb9de09b38f1d2f4bb7c0a35bfa753e46c5cc339c0d9a0d9ed0aa41501") require.NoError(t, err) - signedTxHash := "2Exfhp6qjdNz8HvECFH2sQxvUxJsaygZjWriY8xh3BvBXWh7Nb" + signedTxHash := "7MgvKBj4pWRFoUosicfdzcJf3ejFnnE4LkSPNNfZDCzJ5SVwE" wrappedSignedTx := `{"tx":"` + signedTx + `","signers":` + stakeSigners + `}` signatures := []*types.Signature{{ SigningPayload: &types.SigningPayload{ - AccountIdentifier: cAccountIdentifier, + AccountIdentifier: ewoqAccountP, Bytes: unsignedTxHash, SignatureType: types.EcdsaRecovery, }, @@ -664,6 +700,7 @@ func TestAddValidatorTxConstruction(t *testing.T) { }) t.Run("metadata endpoint", func(t *testing.T) { + shouldMockGetFeeState(clientMock) clientMock.EXPECT().GetBlockchainID(ctx, constants.PChain.String()).Return(pChainID, nil) resp, err := backend.ConstructionMetadata( @@ -773,8 +810,8 @@ func TestAddDelegatorTxConstruction(t *testing.T) { { OperationIdentifier: &types.OperationIdentifier{Index: 0}, RelatedOperations: nil, - Type: pmapper.OpAddDelegator, - Account: pAccountIdentifier, + Type: pmapper.OpAddPermissionlessDelegator, + Account: ewoqAccountP, Amount: mapper.AtomicAvaxAmount(big.NewInt(-25_000_000_000)), CoinChange: &types.CoinChange{ CoinIdentifier: &types.CoinIdentifier{Identifier: coinID1}, @@ -788,8 +825,8 @@ func TestAddDelegatorTxConstruction(t *testing.T) { }, { OperationIdentifier: &types.OperationIdentifier{Index: 1}, - Type: pmapper.OpAddDelegator, - Account: pAccountIdentifier, + Type: pmapper.OpAddPermissionlessDelegator, + Account: ewoqAccountP, Amount: mapper.AtomicAvaxAmount(big.NewInt(25_000_000_000)), Metadata: map[string]interface{}{ "type": pmapper.OpTypeStakeOutput, @@ -801,24 +838,28 @@ func TestAddDelegatorTxConstruction(t *testing.T) { "staking_end_time": endTime, "validator_node_id": nodeID, "subnet_id": pChainID.String(), - "delegator_rewards_owner": []string{stakeRewardAccount.Address}, + "delegator_rewards_owner": []string{ewoqAccountP.Address}, }, }, } + matches, err := common.MatchOperations(operations) + require.NoError(t, err) + preprocessMetadata := map[string]interface{}{ "node_id": nodeID, "start": startTime, "end": endTime, - "reward_addresses": []string{stakeRewardAccount.Address}, + "reward_addresses": []string{ewoqAccountP.Address}, } metadataOptions := map[string]interface{}{ - "type": pmapper.OpAddDelegator, + "type": pmapper.OpAddPermissionlessDelegator, "node_id": nodeID, "start": startTime, "end": endTime, - "reward_addresses": []string{stakeRewardAccount.Address}, + "reward_addresses": []string{ewoqAccountP.Address}, + "matches": matches, } payloadsMetadata := map[string]interface{}{ @@ -830,39 +871,39 @@ func TestAddDelegatorTxConstruction(t *testing.T) { "shares": 0.0, "locktime": 0.0, "threshold": 1.0, - "reward_addresses": []interface{}{stakeRewardAccount.Address}, + "reward_addresses": []interface{}{ewoqAccountP.Address}, "bls_proof_of_possession": "", "bls_public_key": "", "delegator_reward_addresses": nil, "subnet": "", } - signers := []*types.AccountIdentifier{pAccountIdentifier} + signers := []*types.AccountIdentifier{ewoqAccountP} stakeSigners := buildRosettaSignerJSON([]string{coinID1}, signers) - unsignedTx := "0x00000000000e0000000500000000000000000000000000000000000000000000000000000000000000000000000000000001f52a5a6dd8f1b3fe05204bdab4f6bcb5a7059f88d0443c636f6c158f838dd1a8000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000500000005d21dba0000000001000000000000000077e1d5c6c289c49976f744749d54369d2129d7500000000062eb5de30000000062fdd2e300000005d21dba00000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000700000005d21dba00000000000000000000000001000000015445cd01d75b4a06b6b41939193c0b1c5544490d0000000b00000000000000000000000100000001cf7cd358e2e882449d68c1c8889889eaf247b72000000000eece5b91" - unsignedTxHash, err := hex.DecodeString("832a55223ef63d8e39d85025df08c9ae82d0f185d4a0f60b14dec360d721b9f4") + unsignedTx := "0x00000000001a0000000500000000000000000000000000000000000000000000000000000000000000000000000000000001f52a5a6dd8f1b3fe05204bdab4f6bcb5a7059f88d0443c636f6c158f838dd1a8000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000500000005d21dba0000000001000000000000000077e1d5c6c289c49976f744749d54369d2129d7500000000062eb5de30000000062fdd2e300000005d21dba000000000000000000000000000000000000000000000000000000000000000000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000700000005d21dba00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c00000000ebba4acb" + unsignedTxHash, err := hex.DecodeString("b7c169b5608c1b625e9bb0d487ae350f7f4fccb8e9a7ce39ba472aff69c9e175") require.NoError(t, err) wrappedUnsignedTx := `{"tx":"` + unsignedTx + `","signers":` + stakeSigners + `}` signingPayloads := []*types.SigningPayload{ { - AccountIdentifier: pAccountIdentifier, + AccountIdentifier: ewoqAccountP, Bytes: unsignedTxHash, SignatureType: types.EcdsaRecovery, }, } - signedTx := "0x00000000000e0000000500000000000000000000000000000000000000000000000000000000000000000000000000000001f52a5a6dd8f1b3fe05204bdab4f6bcb5a7059f88d0443c636f6c158f838dd1a8000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000500000005d21dba0000000001000000000000000077e1d5c6c289c49976f744749d54369d2129d7500000000062eb5de30000000062fdd2e300000005d21dba00000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000700000005d21dba00000000000000000000000001000000015445cd01d75b4a06b6b41939193c0b1c5544490d0000000b00000000000000000000000100000001cf7cd358e2e882449d68c1c8889889eaf247b7200000000100000009000000017403e32bb967e71902a988b7da635b4bca2475eedbfd23176610a88162f3a92f20b61f2185825b04b7f8ee8c76427c8dc80eb6091f9e594ef259a59856e5401b0143d545c4" - signedTxSignature, err := hex.DecodeString("7403e32bb967e71902a988b7da635b4bca2475eedbfd23176610a88162f3a92f20b61f2185825b04b7f8ee8c76427c8dc80eb6091f9e594ef259a59856e5401b01") + signedTx := "0x00000000001a0000000500000000000000000000000000000000000000000000000000000000000000000000000000000001f52a5a6dd8f1b3fe05204bdab4f6bcb5a7059f88d0443c636f6c158f838dd1a8000000003d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000500000005d21dba0000000001000000000000000077e1d5c6c289c49976f744749d54369d2129d7500000000062eb5de30000000062fdd2e300000005d21dba000000000000000000000000000000000000000000000000000000000000000000000000013d9bdac0ed1d761330cf680efdeb1a42159eb387d6d2950c96f7d28f61bbe2aa0000000700000005d21dba00000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c0000000b000000000000000000000001000000013cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c000000010000000900000001ec8550b25b2a82364ae4944b52ed16c645fc51fa3f239fd9430912760a70f6795381ea7d76a59e22443934e015f695a418c30666415773206e1a8e96bc0ff9bb01a538423f" + signedTxSignature, err := hex.DecodeString("ec8550b25b2a82364ae4944b52ed16c645fc51fa3f239fd9430912760a70f6795381ea7d76a59e22443934e015f695a418c30666415773206e1a8e96bc0ff9bb01") require.NoError(t, err) - signedTxHash := "2eppnnog3TwkBTyQKMh44wz5bUy4geDETEeZVCz7m7uMnjGeCP" + signedTxHash := "2qiPWNr3TgsWbiZLWMyVRQQqgLiq4cmvg7e7gsUjgmVZZwtgsD" wrappedSignedTx := `{"tx":"` + signedTx + `","signers":` + stakeSigners + `}` signatures := []*types.Signature{{ SigningPayload: &types.SigningPayload{ - AccountIdentifier: cAccountIdentifier, + AccountIdentifier: ewoqAccountP, Bytes: unsignedTxHash, SignatureType: types.EcdsaRecovery, }, @@ -898,6 +939,7 @@ func TestAddDelegatorTxConstruction(t *testing.T) { }) t.Run("metadata endpoint", func(t *testing.T) { + shouldMockGetFeeState(clientMock) clientMock.EXPECT().GetBlockchainID(ctx, constants.PChain.String()).Return(pChainID, nil) resp, err := backend.ConstructionMetadata( @@ -1007,3 +1049,18 @@ func marshalSigningPayloads(payloads []*types.SigningPayload) string { return string(bytes) } + +func parsePoP(blsPublicKey, blsProofOfPossession string) (*signer.ProofOfPossession, error) { + publicKeyBytes, err := formatting.Decode(formatting.HexNC, blsPublicKey) + if err != nil { + return nil, err + } + popBytes, err := formatting.Decode(formatting.HexNC, blsProofOfPossession) + if err != nil { + return nil, err + } + pop := &signer.ProofOfPossession{} + copy(pop.PublicKey[:], publicKeyBytes) + copy(pop.ProofOfPossession[:], popBytes) + return pop, nil +} diff --git a/service/backend/pchain/network.go b/service/backend/pchain/network.go index ba68dbb0..7bb6cd27 100644 --- a/service/backend/pchain/network.go +++ b/service/backend/pchain/network.go @@ -3,6 +3,7 @@ package pchain import ( "context" + "github.com/ava-labs/avalanchego/ids" "github.com/coinbase/rosetta-sdk-go/types" "github.com/ava-labs/avalanche-rosetta/constants" @@ -21,7 +22,7 @@ func (b *Backend) NetworkIdentifier() *types.NetworkIdentifier { // NetworkStatus implements /network/status endpoint for P-chain func (b *Backend) NetworkStatus(ctx context.Context, _ *types.NetworkRequest) (*types.NetworkStatusResponse, *types.Error) { // Fetch peers - infoPeers, err := b.pClient.Peers(ctx) + infoPeers, err := b.pClient.Peers(ctx, []ids.NodeID{}) if err != nil { return nil, service.WrapError(service.ErrClientError, err) } diff --git a/service/config.go b/service/config.go index addfadf2..69e018c5 100644 --- a/service/config.go +++ b/service/config.go @@ -3,6 +3,8 @@ package service import ( "math/big" + "github.com/ava-labs/avalanchego/upgrade" + "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/coreth/params" "github.com/coinbase/rosetta-sdk-go/types" @@ -61,13 +63,13 @@ func (c Config) IsTokenListEmpty() bool { func (c Config) Signer() ethtypes.Signer { if c.ChainID != nil { if c.ChainID.Cmp(params.AvalancheMainnetChainID) == 0 { - return ethtypes.LatestSigner(params.AvalancheMainnetChainConfig) + return ethtypes.LatestSigner(params.GetChainConfig(upgrade.GetConfig(constants.MainnetID), params.AvalancheMainnetChainID)) } if c.ChainID.Cmp(params.AvalancheFujiChainID) == 0 { - return ethtypes.LatestSigner(params.AvalancheFujiChainConfig) + return ethtypes.LatestSigner(params.GetChainConfig(upgrade.GetConfig(constants.FujiID), params.AvalancheFujiChainID)) } if c.ChainID.Cmp(params.AvalancheLocalChainID) == 0 { - return ethtypes.LatestSigner(params.AvalancheLocalChainConfig) + return ethtypes.LatestSigner(params.GetChainConfig(upgrade.GetConfig(constants.LocalID), params.AvalancheLocalChainID)) } } return ethtypes.LatestSignerForChainID(c.ChainID) diff --git a/service/service_network.go b/service/service_network.go index 1bad248f..49ba6384 100644 --- a/service/service_network.go +++ b/service/service_network.go @@ -4,6 +4,7 @@ import ( "context" "math/big" + "github.com/ava-labs/avalanchego/ids" "github.com/coinbase/rosetta-sdk-go/server" "github.com/coinbase/rosetta-sdk-go/types" "github.com/coinbase/rosetta-sdk-go/utils" @@ -81,7 +82,7 @@ func (s *NetworkService) NetworkStatus( } // Fetch peers - infoPeers, err := s.client.Peers(ctx) + infoPeers, err := s.client.Peers(ctx, []ids.NodeID{}) if err != nil { return nil, WrapError(ErrClientError, err) }