From 8744bd5eae560c61a9fa729dfee2a690ba277844 Mon Sep 17 00:00:00 2001 From: fm Date: Wed, 24 Jan 2024 11:33:46 -0300 Subject: [PATCH 01/15] add wallet function to support generating and issue TransferSubnetOwnership --- wallet/chain/p/builder.go | 46 ++++++++++++++++++++++++++ wallet/chain/p/builder_with_options.go | 12 +++++++ wallet/chain/p/wallet.go | 24 ++++++++++++++ wallet/chain/p/wallet_with_options.go | 12 +++++++ 4 files changed, 94 insertions(+) diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 9a8189c4db6b..de95b75db1c9 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -134,6 +134,17 @@ type Builder interface { options ...common.Option, ) (*txs.CreateSubnetTx, error) + // NewTransferSubnetOwnershipTx changes the owner of the named subnet. + // + // - [subnetID] specifies the subnet to be modified + // - [owner] specifies who has the ability to create new chains and add new + // validators to the subnet. + NewTransferSubnetOwnershipTx( + subnetID ids.ID, + owner *secp256k1fx.OutputOwners, + options ...common.Option, + ) (*txs.TransferSubnetOwnershipTx, error) + // NewImportTx creates an import transaction that attempts to consume all // the available UTXOs and import the funds to [to]. // @@ -532,6 +543,41 @@ func (b *builder) NewCreateSubnetTx( return tx, b.initCtx(tx) } +func (b *builder) NewTransferSubnetOwnershipTx( + subnetID ids.ID, + owner *secp256k1fx.OutputOwners, + options ...common.Option, +) (*txs.TransferSubnetOwnershipTx, error) { + toBurn := map[ids.ID]uint64{ + b.backend.AVAXAssetID(): b.backend.BaseTxFee(), + } + toStake := map[ids.ID]uint64{} + ops := common.NewOptions(options) + inputs, outputs, _, err := b.spend(toBurn, toStake, ops) + if err != nil { + return nil, err + } + + subnetAuth, err := b.authorizeSubnet(subnetID, ops) + if err != nil { + return nil, err + } + + tx := &txs.TransferSubnetOwnershipTx{ + BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ + NetworkID: b.backend.NetworkID(), + BlockchainID: constants.PlatformChainID, + Ins: inputs, + Outs: outputs, + Memo: ops.Memo(), + }}, + Subnet: subnetID, + Owner: owner, + SubnetAuth: subnetAuth, + } + return tx, b.initCtx(tx) +} + func (b *builder) NewImportTx( sourceChainID ids.ID, to *secp256k1fx.OutputOwners, diff --git a/wallet/chain/p/builder_with_options.go b/wallet/chain/p/builder_with_options.go index 46deab976577..a402355b9e01 100644 --- a/wallet/chain/p/builder_with_options.go +++ b/wallet/chain/p/builder_with_options.go @@ -129,6 +129,18 @@ func (b *builderWithOptions) NewCreateSubnetTx( ) } +func (b *builderWithOptions) NewTransferSubnetOwnershipTx( + subnetID ids.ID, + owner *secp256k1fx.OutputOwners, + options ...common.Option, +) (*txs.TransferSubnetOwnershipTx, error) { + return b.Builder.NewTransferSubnetOwnershipTx( + subnetID, + owner, + common.UnionOptions(b.options, options)..., + ) +} + func (b *builderWithOptions) NewImportTx( sourceChainID ids.ID, to *secp256k1fx.OutputOwners, diff --git a/wallet/chain/p/wallet.go b/wallet/chain/p/wallet.go index e982a204a9f8..c5b9ecb0604b 100644 --- a/wallet/chain/p/wallet.go +++ b/wallet/chain/p/wallet.go @@ -122,6 +122,18 @@ type Wallet interface { options ...common.Option, ) (*txs.Tx, error) + // IssueTransferSubnetOwnershipTx creates, signs, and issues a transaction that + // changes the owner of the named subnet. + // + // - [subnetID] specifies the subnet to be modified + // - [owner] specifies who has the ability to create new chains and add new + // validators to the subnet. + IssueTransferSubnetOwnershipTx( + subnetID ids.ID, + owner *secp256k1fx.OutputOwners, + options ...common.Option, + ) (*txs.Tx, error) + // IssueImportTx creates, signs, and issues an import transaction that // attempts to consume all the available UTXOs and import the funds to [to]. // @@ -359,6 +371,18 @@ func (w *wallet) IssueCreateSubnetTx( return w.IssueUnsignedTx(utx, options...) } +func (w *wallet) IssueTransferSubnetOwnershipTx( + subnetID ids.ID, + owner *secp256k1fx.OutputOwners, + options ...common.Option, +) (*txs.Tx, error) { + utx, err := w.builder.NewTransferSubnetOwnershipTx(subnetID, owner, options...) + if err != nil { + return nil, err + } + return w.IssueUnsignedTx(utx, options...) +} + func (w *wallet) IssueImportTx( sourceChainID ids.ID, to *secp256k1fx.OutputOwners, diff --git a/wallet/chain/p/wallet_with_options.go b/wallet/chain/p/wallet_with_options.go index 33faa1a86bb0..4982e77f8a51 100644 --- a/wallet/chain/p/wallet_with_options.go +++ b/wallet/chain/p/wallet_with_options.go @@ -124,6 +124,18 @@ func (w *walletWithOptions) IssueCreateSubnetTx( ) } +func (w *walletWithOptions) IssueTransferSubnetOwnershipTx( + subnetID ids.ID, + owner *secp256k1fx.OutputOwners, + options ...common.Option, +) (*txs.Tx, error) { + return w.Wallet.IssueTransferSubnetOwnershipTx( + subnetID, + owner, + common.UnionOptions(w.options, options)..., + ) +} + func (w *walletWithOptions) IssueImportTx( sourceChainID ids.ID, to *secp256k1fx.OutputOwners, From c1890a324179727e693e6d04b9d785b09691fb40 Mon Sep 17 00:00:00 2001 From: fm Date: Wed, 24 Jan 2024 13:34:18 -0300 Subject: [PATCH 02/15] keep tracking subnet owner changes at wallet --- wallet/chain/p/backend.go | 19 +++++++++++++++++++ wallet/chain/p/backend_visitor.go | 11 ++++++++++- wallet/chain/p/builder.go | 5 +++++ wallet/chain/p/signer.go | 2 ++ wallet/chain/p/signer_visitor.go | 4 ++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index d06c7a1f9cf9..fa05388c0139 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -14,6 +14,7 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -35,6 +36,10 @@ type backend struct { txsLock sync.RWMutex // txID -> tx txs map[ids.ID]*txs.Tx + + subnetOwnerTransferLock sync.RWMutex + // subnetID -> owner + subnetOwnerTransfer map[ids.ID]*secp256k1fx.OutputOwners } func NewBackend(ctx Context, utxos common.ChainUTXOs, txs map[ids.ID]*txs.Tx) Backend { @@ -97,3 +102,17 @@ func (b *backend) GetTx(_ stdcontext.Context, txID ids.ID) (*txs.Tx, error) { } return tx, nil } + +func (b *backend) setSubnetOwnerTransfer(_ stdcontext.Context, subnetID ids.ID, owner *secp256k1fx.OutputOwners) { + b.subnetOwnerTransferLock.Lock() + defer b.subnetOwnerTransferLock.Unlock() + + b.subnetOwnerTransfer[subnetID] = owner +} + +func (b *backend) GetSubnetOwnerTransfer(_ stdcontext.Context, subnetID ids.ID) *secp256k1fx.OutputOwners { + b.subnetOwnerTransferLock.RLock() + defer b.subnetOwnerTransferLock.RUnlock() + + return b.subnetOwnerTransfer[subnetID] +} diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index 1a0c8e39e8da..e45799d11f2b 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) var _ txs.Visitor = (*backendVisitor)(nil) @@ -54,7 +55,15 @@ func (b *backendVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx } func (b *backendVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { - // TODO: Correctly track subnet owners in [getSubnetSigners] + owner, ok := tx.Owner.(*secp256k1fx.OutputOwners) + if !ok { + return errUnknownOwnerType + } + b.b.setSubnetOwnerTransfer( + b.ctx, + tx.Subnet, + owner, + ) return b.baseTx(&tx.BaseTx) } diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index de95b75db1c9..b9bef2851488 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -262,6 +262,7 @@ type BuilderBackend interface { Context UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) GetTx(ctx stdcontext.Context, txID ids.ID) (*txs.Tx, error) + GetSubnetOwnerTransfer(ctx stdcontext.Context, subnetID ids.ID) *secp256k1fx.OutputOwners } type builder struct { @@ -1163,6 +1164,10 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se if !ok { return nil, errUnknownOwnerType } + ownerTransfer := b.backend.GetSubnetOwnerTransfer(options.Context(), subnetID) + if ownerTransfer != nil { + owner = ownerTransfer + } addrs := options.Addresses(b.addrs) minIssuanceTime := options.MinIssuanceTime() diff --git a/wallet/chain/p/signer.go b/wallet/chain/p/signer.go index be2db8ddd2c0..545786a79fb2 100644 --- a/wallet/chain/p/signer.go +++ b/wallet/chain/p/signer.go @@ -10,6 +10,7 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" + "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) var _ Signer = (*txSigner)(nil) @@ -22,6 +23,7 @@ type Signer interface { type SignerBackend interface { GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) GetTx(ctx stdcontext.Context, txID ids.ID) (*txs.Tx, error) + GetSubnetOwnerTransfer(ctx stdcontext.Context, subnetID ids.ID) *secp256k1fx.OutputOwners } type txSigner struct { diff --git a/wallet/chain/p/signer_visitor.go b/wallet/chain/p/signer_visitor.go index c5c444a97f13..13d06e095717 100644 --- a/wallet/chain/p/signer_visitor.go +++ b/wallet/chain/p/signer_visitor.go @@ -263,6 +263,10 @@ func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Veri if !ok { return nil, errUnknownOwnerType } + ownerTransfer := s.backend.GetSubnetOwnerTransfer(s.ctx, subnetID) + if ownerTransfer != nil { + owner = ownerTransfer + } authSigners := make([]keychain.Signer, len(subnetInput.SigIndices)) for sigIndex, addrIndex := range subnetInput.SigIndices { From 5218d46b32f33944fd995b9cca711434bad57252 Mon Sep 17 00:00:00 2001 From: fm Date: Wed, 24 Jan 2024 18:27:29 -0300 Subject: [PATCH 03/15] enable wallet users to also pass in previous owner transfer txs --- wallet/chain/p/backend.go | 68 ++++++++++++++++++++++++------- wallet/chain/p/backend_visitor.go | 2 +- wallet/chain/p/builder.go | 17 +------- wallet/chain/p/signer.go | 2 +- wallet/chain/p/signer_visitor.go | 15 +------ 5 files changed, 58 insertions(+), 46 deletions(-) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index fa05388c0139..c25c4f26437b 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -37,17 +37,22 @@ type backend struct { // txID -> tx txs map[ids.ID]*txs.Tx - subnetOwnerTransferLock sync.RWMutex + subnetOwnerLock sync.RWMutex // subnetID -> owner - subnetOwnerTransfer map[ids.ID]*secp256k1fx.OutputOwners + subnetOwner map[ids.ID]*secp256k1fx.OutputOwners } -func NewBackend(ctx Context, utxos common.ChainUTXOs, txs map[ids.ID]*txs.Tx) Backend { - return &backend{ - Context: ctx, - ChainUTXOs: utxos, - txs: txs, +func NewBackend(ctx Context, utxos common.ChainUTXOs, txs map[ids.ID]*txs.Tx) (Backend, error) { + subnetOwner, err := getSubnetOwnerMap(txs) + if err != nil { + return nil, err } + return &backend{ + Context: ctx, + ChainUTXOs: utxos, + txs: txs, + subnetOwner: subnetOwner, + }, nil } func (b *backend) AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error { @@ -103,16 +108,49 @@ func (b *backend) GetTx(_ stdcontext.Context, txID ids.ID) (*txs.Tx, error) { return tx, nil } -func (b *backend) setSubnetOwnerTransfer(_ stdcontext.Context, subnetID ids.ID, owner *secp256k1fx.OutputOwners) { - b.subnetOwnerTransferLock.Lock() - defer b.subnetOwnerTransferLock.Unlock() +func (b *backend) setSubnetOwner(_ stdcontext.Context, subnetID ids.ID, owner *secp256k1fx.OutputOwners) { + b.subnetOwnerLock.Lock() + defer b.subnetOwnerLock.Unlock() - b.subnetOwnerTransfer[subnetID] = owner + b.subnetOwner[subnetID] = owner } -func (b *backend) GetSubnetOwnerTransfer(_ stdcontext.Context, subnetID ids.ID) *secp256k1fx.OutputOwners { - b.subnetOwnerTransferLock.RLock() - defer b.subnetOwnerTransferLock.RUnlock() +func (b *backend) GetSubnetOwner(_ stdcontext.Context, subnetID ids.ID) (*secp256k1fx.OutputOwners, error) { + b.subnetOwnerLock.RLock() + defer b.subnetOwnerLock.RUnlock() + + owner, exists := b.subnetOwner[subnetID] + if !exists { + return nil, database.ErrNotFound + } + return owner, nil +} - return b.subnetOwnerTransfer[subnetID] +func getSubnetOwnerMap(pChainTxs map[ids.ID]*txs.Tx) (map[ids.ID]*secp256k1fx.OutputOwners, error) { + subnetOwner := map[ids.ID]*secp256k1fx.OutputOwners{} + // first get owners from original CreateSubnetTx + for txID, tx := range pChainTxs { + createSubnetTx, ok := tx.Unsigned.(*txs.CreateSubnetTx) + if !ok { + continue + } + owner, ok := createSubnetTx.Owner.(*secp256k1fx.OutputOwners) + if !ok { + return nil, errUnknownOwnerType + } + subnetOwner[txID] = owner + } + // then check TransferSubnetOwnershipTx + for txID, tx := range pChainTxs { + transferSubnetOwnershipTx, ok := tx.Unsigned.(*txs.TransferSubnetOwnershipTx) + if !ok { + continue + } + owner, ok := transferSubnetOwnershipTx.Owner.(*secp256k1fx.OutputOwners) + if !ok { + return nil, errUnknownOwnerType + } + subnetOwner[txID] = owner + } + return subnetOwner, nil } diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index e45799d11f2b..70fffb071397 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -59,7 +59,7 @@ func (b *backendVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnersh if !ok { return errUnknownOwnerType } - b.b.setSubnetOwnerTransfer( + b.b.setSubnetOwner( b.ctx, tx.Subnet, owner, diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index b9bef2851488..2e636a29d18f 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -262,7 +262,7 @@ type BuilderBackend interface { Context UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) GetTx(ctx stdcontext.Context, txID ids.ID) (*txs.Tx, error) - GetSubnetOwnerTransfer(ctx stdcontext.Context, subnetID ids.ID) *secp256k1fx.OutputOwners + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (*secp256k1fx.OutputOwners, error) } type builder struct { @@ -1147,7 +1147,7 @@ func (b *builder) spend( } func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*secp256k1fx.Input, error) { - subnetTx, err := b.backend.GetTx(options.Context(), subnetID) + owner, err := b.backend.GetSubnetOwner(options.Context(), subnetID) if err != nil { return nil, fmt.Errorf( "failed to fetch subnet %q: %w", @@ -1155,19 +1155,6 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se err, ) } - subnet, ok := subnetTx.Unsigned.(*txs.CreateSubnetTx) - if !ok { - return nil, errWrongTxType - } - - owner, ok := subnet.Owner.(*secp256k1fx.OutputOwners) - if !ok { - return nil, errUnknownOwnerType - } - ownerTransfer := b.backend.GetSubnetOwnerTransfer(options.Context(), subnetID) - if ownerTransfer != nil { - owner = ownerTransfer - } addrs := options.Addresses(b.addrs) minIssuanceTime := options.MinIssuanceTime() diff --git a/wallet/chain/p/signer.go b/wallet/chain/p/signer.go index 545786a79fb2..cbe26151352f 100644 --- a/wallet/chain/p/signer.go +++ b/wallet/chain/p/signer.go @@ -23,7 +23,7 @@ type Signer interface { type SignerBackend interface { GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) GetTx(ctx stdcontext.Context, txID ids.ID) (*txs.Tx, error) - GetSubnetOwnerTransfer(ctx stdcontext.Context, subnetID ids.ID) *secp256k1fx.OutputOwners + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (*secp256k1fx.OutputOwners, error) } type txSigner struct { diff --git a/wallet/chain/p/signer_visitor.go b/wallet/chain/p/signer_visitor.go index 13d06e095717..1b5524e7069d 100644 --- a/wallet/chain/p/signer_visitor.go +++ b/wallet/chain/p/signer_visitor.go @@ -246,7 +246,7 @@ func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Veri return nil, errUnknownSubnetAuthType } - subnetTx, err := s.backend.GetTx(s.ctx, subnetID) + owner, err := s.backend.GetSubnetOwner(s.ctx, subnetID) if err != nil { return nil, fmt.Errorf( "failed to fetch subnet %q: %w", @@ -254,19 +254,6 @@ func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Veri err, ) } - subnet, ok := subnetTx.Unsigned.(*txs.CreateSubnetTx) - if !ok { - return nil, errWrongTxType - } - - owner, ok := subnet.Owner.(*secp256k1fx.OutputOwners) - if !ok { - return nil, errUnknownOwnerType - } - ownerTransfer := s.backend.GetSubnetOwnerTransfer(s.ctx, subnetID) - if ownerTransfer != nil { - owner = ownerTransfer - } authSigners := make([]keychain.Signer, len(subnetInput.SigIndices)) for sigIndex, addrIndex := range subnetInput.SigIndices { From f549e6167c0936451c9503696b8fe4d3ba31ad4b Mon Sep 17 00:00:00 2001 From: fm Date: Wed, 24 Jan 2024 18:53:05 -0300 Subject: [PATCH 04/15] fix lint --- scripts/lint.sh | 24 ++++++++++++------------ wallet/chain/p/builder.go | 1 - 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/scripts/lint.sh b/scripts/lint.sh index 110a719d38d6..252718370328 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -11,7 +11,7 @@ fi # default on macos. Since `-o errexit` is ignored in an if # conditional, triggering the problem here ensures script failure when # using an unsupported version of grep. -grep -P 'lint.sh' scripts/lint.sh &> /dev/null || (\ +ggrep -P 'lint.sh' scripts/lint.sh &> /dev/null || (\ >&2 echo "error: This script requires a recent version of gnu grep.";\ >&2 echo " On macos, gnu grep can be installed with 'brew install grep'.";\ >&2 echo " It will also be necessary to ensure that gnu grep is available in the path.";\ @@ -53,14 +53,14 @@ function test_license_header { } function test_single_import { - if grep -R -zo -P 'import \(\n\t".*"\n\)' .; then + if ggrep -R -zo -P 'import \(\n\t".*"\n\)' .; then echo "" return 1 fi } function test_require_error_is_no_funcs_as_params { - if grep -R -zo -P 'require.ErrorIs\(.+?\)[^\n]*\)\n' .; then + if ggrep -R -zo -P 'require.ErrorIs\(.+?\)[^\n]*\)\n' .; then echo "" return 1 fi @@ -68,7 +68,7 @@ function test_require_error_is_no_funcs_as_params { function test_require_equal_zero { # check if the first arg, other than t, is 0 - if grep -R -o -P 'require\.Equal\((t, )?(u?int\d*\(0\)|0)' .; then + if ggrep -R -o -P 'require\.Equal\((t, )?(u?int\d*\(0\)|0)' .; then echo "" echo "Use require.Zero instead of require.Equal when testing for 0." echo "" @@ -76,7 +76,7 @@ function test_require_equal_zero { fi # check if the last arg is 0 - if grep -R -zo -P 'require\.Equal\(.+?, (u?int\d*\(0\)|0)\)\n' .; then + if ggrep -R -zo -P 'require\.Equal\(.+?, (u?int\d*\(0\)|0)\)\n' .; then echo "" echo "Use require.Zero instead of require.Equal when testing for 0." echo "" @@ -85,7 +85,7 @@ function test_require_equal_zero { } function test_require_len_zero { - if grep -R -o -P 'require\.Len\((t, )?.+, 0(,|\))' .; then + if ggrep -R -o -P 'require\.Len\((t, )?.+, 0(,|\))' .; then echo "" echo "Use require.Empty instead of require.Len when testing for 0 length." echo "" @@ -103,7 +103,7 @@ function test_require_equal_len { # These should match: # - require.Equal(2, len(foo)) # - require.Equal(t, 2, len(foo)) - if grep -R -o -P --exclude-dir='scripts' 'require\.Equal\((t, )?.*, len\([^,]*$' .; then + if ggrep -R -o -P --exclude-dir='scripts' 'require\.Equal\((t, )?.*, len\([^,]*$' .; then echo "" echo "Use require.Len instead of require.Equal when testing for length." echo "" @@ -112,21 +112,21 @@ function test_require_equal_len { } function test_require_nil { - if grep -R -o -P 'require\..+?!= nil' .; then + if ggrep -R -o -P 'require\..+?!= nil' .; then echo "" echo "Use require.NotNil when testing for nil inequality." echo "" return 1 fi - if grep -R -o -P 'require\..+?== nil' .; then + if ggrep -R -o -P 'require\..+?== nil' .; then echo "" echo "Use require.Nil when testing for nil equality." echo "" return 1 fi - if grep -R -o -P 'require\.ErrorIs.+?nil\)' .; then + if ggrep -R -o -P 'require\.ErrorIs.+?nil\)' .; then echo "" echo "Use require.NoError instead of require.ErrorIs when testing for nil error." echo "" @@ -135,7 +135,7 @@ function test_require_nil { } function test_require_no_error_inline_func { - if grep -R -zo -P '\t+err :?= ((?!require|if).|\n)*require\.NoError\((t, )?err\)' .; then + if ggrep -R -zo -P '\t+err :?= ((?!require|if).|\n)*require\.NoError\((t, )?err\)' .; then echo "" echo "Checking that a function with a single error return doesn't error should be done in-line." echo "" @@ -145,7 +145,7 @@ function test_require_no_error_inline_func { # Ref: https://go.dev/doc/effective_go#blank_implements function test_interface_compliance_nil { - if grep -R -o -P '_ .+? = &.+?\{\}' .; then + if ggrep -R -o -P '_ .+? = &.+?\{\}' .; then echo "" echo "Interface compliance checks need to be of the form:" echo " var _ json.Marshaler = (*RawMessage)(nil)" diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 2e636a29d18f..43c2360fa041 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -25,7 +25,6 @@ import ( var ( errNoChangeAddress = errors.New("no possible change address") - errWrongTxType = errors.New("wrong tx type") errUnknownOwnerType = errors.New("unknown owner type") errInsufficientAuthorization = errors.New("insufficient authorization") errInsufficientFunds = errors.New("insufficient funds") From 5e69ecc2b36248db91c2c29af12e5c9b28e634b1 Mon Sep 17 00:00:00 2001 From: fm Date: Wed, 24 Jan 2024 19:01:15 -0300 Subject: [PATCH 05/15] restore scripts/lint --- scripts/lint.sh | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/scripts/lint.sh b/scripts/lint.sh index 252718370328..110a719d38d6 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -11,7 +11,7 @@ fi # default on macos. Since `-o errexit` is ignored in an if # conditional, triggering the problem here ensures script failure when # using an unsupported version of grep. -ggrep -P 'lint.sh' scripts/lint.sh &> /dev/null || (\ +grep -P 'lint.sh' scripts/lint.sh &> /dev/null || (\ >&2 echo "error: This script requires a recent version of gnu grep.";\ >&2 echo " On macos, gnu grep can be installed with 'brew install grep'.";\ >&2 echo " It will also be necessary to ensure that gnu grep is available in the path.";\ @@ -53,14 +53,14 @@ function test_license_header { } function test_single_import { - if ggrep -R -zo -P 'import \(\n\t".*"\n\)' .; then + if grep -R -zo -P 'import \(\n\t".*"\n\)' .; then echo "" return 1 fi } function test_require_error_is_no_funcs_as_params { - if ggrep -R -zo -P 'require.ErrorIs\(.+?\)[^\n]*\)\n' .; then + if grep -R -zo -P 'require.ErrorIs\(.+?\)[^\n]*\)\n' .; then echo "" return 1 fi @@ -68,7 +68,7 @@ function test_require_error_is_no_funcs_as_params { function test_require_equal_zero { # check if the first arg, other than t, is 0 - if ggrep -R -o -P 'require\.Equal\((t, )?(u?int\d*\(0\)|0)' .; then + if grep -R -o -P 'require\.Equal\((t, )?(u?int\d*\(0\)|0)' .; then echo "" echo "Use require.Zero instead of require.Equal when testing for 0." echo "" @@ -76,7 +76,7 @@ function test_require_equal_zero { fi # check if the last arg is 0 - if ggrep -R -zo -P 'require\.Equal\(.+?, (u?int\d*\(0\)|0)\)\n' .; then + if grep -R -zo -P 'require\.Equal\(.+?, (u?int\d*\(0\)|0)\)\n' .; then echo "" echo "Use require.Zero instead of require.Equal when testing for 0." echo "" @@ -85,7 +85,7 @@ function test_require_equal_zero { } function test_require_len_zero { - if ggrep -R -o -P 'require\.Len\((t, )?.+, 0(,|\))' .; then + if grep -R -o -P 'require\.Len\((t, )?.+, 0(,|\))' .; then echo "" echo "Use require.Empty instead of require.Len when testing for 0 length." echo "" @@ -103,7 +103,7 @@ function test_require_equal_len { # These should match: # - require.Equal(2, len(foo)) # - require.Equal(t, 2, len(foo)) - if ggrep -R -o -P --exclude-dir='scripts' 'require\.Equal\((t, )?.*, len\([^,]*$' .; then + if grep -R -o -P --exclude-dir='scripts' 'require\.Equal\((t, )?.*, len\([^,]*$' .; then echo "" echo "Use require.Len instead of require.Equal when testing for length." echo "" @@ -112,21 +112,21 @@ function test_require_equal_len { } function test_require_nil { - if ggrep -R -o -P 'require\..+?!= nil' .; then + if grep -R -o -P 'require\..+?!= nil' .; then echo "" echo "Use require.NotNil when testing for nil inequality." echo "" return 1 fi - if ggrep -R -o -P 'require\..+?== nil' .; then + if grep -R -o -P 'require\..+?== nil' .; then echo "" echo "Use require.Nil when testing for nil equality." echo "" return 1 fi - if ggrep -R -o -P 'require\.ErrorIs.+?nil\)' .; then + if grep -R -o -P 'require\.ErrorIs.+?nil\)' .; then echo "" echo "Use require.NoError instead of require.ErrorIs when testing for nil error." echo "" @@ -135,7 +135,7 @@ function test_require_nil { } function test_require_no_error_inline_func { - if ggrep -R -zo -P '\t+err :?= ((?!require|if).|\n)*require\.NoError\((t, )?err\)' .; then + if grep -R -zo -P '\t+err :?= ((?!require|if).|\n)*require\.NoError\((t, )?err\)' .; then echo "" echo "Checking that a function with a single error return doesn't error should be done in-line." echo "" @@ -145,7 +145,7 @@ function test_require_no_error_inline_func { # Ref: https://go.dev/doc/effective_go#blank_implements function test_interface_compliance_nil { - if ggrep -R -o -P '_ .+? = &.+?\{\}' .; then + if grep -R -o -P '_ .+? = &.+?\{\}' .; then echo "" echo "Interface compliance checks need to be of the form:" echo " var _ json.Marshaler = (*RawMessage)(nil)" From 9c754fd1f328d18530303ce6bdec6e34d613a832 Mon Sep 17 00:00:00 2001 From: fm Date: Wed, 24 Jan 2024 19:10:48 -0300 Subject: [PATCH 06/15] fix lint --- wallet/subnet/primary/examples/get-p-chain-balance/main.go | 5 ++++- wallet/subnet/primary/wallet.go | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/wallet/subnet/primary/examples/get-p-chain-balance/main.go b/wallet/subnet/primary/examples/get-p-chain-balance/main.go index fd14eb4ea588..7cb85e36fb31 100644 --- a/wallet/subnet/primary/examples/get-p-chain-balance/main.go +++ b/wallet/subnet/primary/examples/get-p-chain-balance/main.go @@ -38,7 +38,10 @@ func main() { log.Printf("fetched state of %s in %s\n", addrStr, time.Since(fetchStartTime)) pUTXOs := primary.NewChainUTXOs(constants.PlatformChainID, state.UTXOs) - pBackend := p.NewBackend(state.PCTX, pUTXOs, make(map[ids.ID]*txs.Tx)) + pBackend, err := p.NewBackend(state.PCTX, pUTXOs, make(map[ids.ID]*txs.Tx)) + if err != nil { + log.Fatalf("failed to create wallet backend: %s\n", err) + } pBuilder := p.NewBuilder(addresses, pBackend) currentBalances, err := pBuilder.GetBalance() diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 3bb3e9965684..7fdaa89893a8 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -117,7 +117,10 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { } pUTXOs := NewChainUTXOs(constants.PlatformChainID, avaxState.UTXOs) - pBackend := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) + pBackend, err := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) + if err != nil { + return nil, err + } pBuilder := p.NewBuilder(avaxAddrs, pBackend) pSigner := p.NewSigner(config.AVAXKeychain, pBackend) From b39ac98e2910f12b16b1dbdf0384a514cae6c89f Mon Sep 17 00:00:00 2001 From: fm Date: Wed, 24 Jan 2024 19:33:15 -0300 Subject: [PATCH 07/15] fix e2e --- wallet/chain/p/backend_visitor.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index 70fffb071397..112a3a38da65 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -47,6 +47,15 @@ func (b *backendVisitor) CreateChainTx(tx *txs.CreateChainTx) error { } func (b *backendVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { + owner, ok := tx.Owner.(*secp256k1fx.OutputOwners) + if !ok { + return errUnknownOwnerType + } + b.b.setSubnetOwner( + b.ctx, + b.txID, + owner, + ) return b.baseTx(&tx.BaseTx) } From 4ae90f7bca2f019d09d61a09af21452beaa42ab8 Mon Sep 17 00:00:00 2001 From: fm Date: Thu, 25 Jan 2024 06:13:41 -0300 Subject: [PATCH 08/15] sort owners --- wallet/chain/p/builder.go | 1 + 1 file changed, 1 insertion(+) diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 43c2360fa041..e8421cd27e81 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -563,6 +563,7 @@ func (b *builder) NewTransferSubnetOwnershipTx( return nil, err } + utils.Sort(owner.Addrs) tx := &txs.TransferSubnetOwnershipTx{ BaseTx: txs.BaseTx{BaseTx: avax.BaseTx{ NetworkID: b.backend.NetworkID(), From a9bc73ad40f6ff5ba0761b559d34c6a561fe5b8c Mon Sep 17 00:00:00 2001 From: fm Date: Thu, 25 Jan 2024 09:20:37 -0300 Subject: [PATCH 09/15] correctly set the subnet ID for an owner of a transfer --- wallet/chain/p/backend.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index c25c4f26437b..ad6258c3e1bd 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -141,7 +141,7 @@ func getSubnetOwnerMap(pChainTxs map[ids.ID]*txs.Tx) (map[ids.ID]*secp256k1fx.Ou subnetOwner[txID] = owner } // then check TransferSubnetOwnershipTx - for txID, tx := range pChainTxs { + for _, tx := range pChainTxs { transferSubnetOwnershipTx, ok := tx.Unsigned.(*txs.TransferSubnetOwnershipTx) if !ok { continue @@ -150,7 +150,7 @@ func getSubnetOwnerMap(pChainTxs map[ids.ID]*txs.Tx) (map[ids.ID]*secp256k1fx.Ou if !ok { return nil, errUnknownOwnerType } - subnetOwner[txID] = owner + subnetOwner[transferSubnetOwnershipTx.Subnet] = owner } return subnetOwner, nil } From bf452f9b6f0bc35739411f3c15f38443c1bee79f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 30 Jan 2024 16:49:23 -0500 Subject: [PATCH 10/15] nits --- wallet/chain/p/backend.go | 94 +++++-------------- wallet/chain/p/backend_visitor.go | 13 +-- wallet/chain/p/builder.go | 10 +- wallet/chain/p/signer.go | 5 +- wallet/chain/p/signer_visitor.go | 6 +- .../examples/get-p-chain-balance/main.go | 7 +- wallet/subnet/primary/wallet.go | 5 +- 7 files changed, 43 insertions(+), 97 deletions(-) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index ad6258c3e1bd..c46743a0b6bf 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -13,8 +13,8 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" "github.com/ava-labs/avalanchego/wallet/subnet/primary/common" ) @@ -33,26 +33,31 @@ type backend struct { Context common.ChainUTXOs - txsLock sync.RWMutex - // txID -> tx - txs map[ids.ID]*txs.Tx - subnetOwnerLock sync.RWMutex - // subnetID -> owner - subnetOwner map[ids.ID]*secp256k1fx.OutputOwners + subnetOwner map[ids.ID]fx.Owner // subnetID -> owner } -func NewBackend(ctx Context, utxos common.ChainUTXOs, txs map[ids.ID]*txs.Tx) (Backend, error) { - subnetOwner, err := getSubnetOwnerMap(txs) - if err != nil { - return nil, err +func NewBackend(ctx Context, utxos common.ChainUTXOs, subnetTxs map[ids.ID]*txs.Tx) Backend { + subnetOwner := make(map[ids.ID]fx.Owner) + for txID, tx := range subnetTxs { // first get owners from original CreateSubnetTx + createSubnetTx, ok := tx.Unsigned.(*txs.CreateSubnetTx) + if !ok { + continue + } + subnetOwner[txID] = createSubnetTx.Owner + } + for _, tx := range subnetTxs { // then check TransferSubnetOwnershipTx + transferSubnetOwnershipTx, ok := tx.Unsigned.(*txs.TransferSubnetOwnershipTx) + if !ok { + continue + } + subnetOwner[transferSubnetOwnershipTx.Subnet] = transferSubnetOwnershipTx.Owner } return &backend{ Context: ctx, ChainUTXOs: utxos, - txs: txs, subnetOwner: subnetOwner, - }, nil + } } func (b *backend) AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error { @@ -67,16 +72,7 @@ func (b *backend) AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error { } producedUTXOSlice := tx.UTXOs() - err = b.addUTXOs(ctx, constants.PlatformChainID, producedUTXOSlice) - if err != nil { - return err - } - - b.txsLock.Lock() - defer b.txsLock.Unlock() - - b.txs[txID] = tx - return nil + return b.addUTXOs(ctx, constants.PlatformChainID, producedUTXOSlice) } func (b *backend) addUTXOs(ctx stdcontext.Context, destinationChainID ids.ID, utxos []*avax.UTXO) error { @@ -97,25 +93,7 @@ func (b *backend) removeUTXOs(ctx stdcontext.Context, sourceChain ids.ID, utxoID return nil } -func (b *backend) GetTx(_ stdcontext.Context, txID ids.ID) (*txs.Tx, error) { - b.txsLock.RLock() - defer b.txsLock.RUnlock() - - tx, exists := b.txs[txID] - if !exists { - return nil, database.ErrNotFound - } - return tx, nil -} - -func (b *backend) setSubnetOwner(_ stdcontext.Context, subnetID ids.ID, owner *secp256k1fx.OutputOwners) { - b.subnetOwnerLock.Lock() - defer b.subnetOwnerLock.Unlock() - - b.subnetOwner[subnetID] = owner -} - -func (b *backend) GetSubnetOwner(_ stdcontext.Context, subnetID ids.ID) (*secp256k1fx.OutputOwners, error) { +func (b *backend) GetSubnetOwner(_ stdcontext.Context, subnetID ids.ID) (fx.Owner, error) { b.subnetOwnerLock.RLock() defer b.subnetOwnerLock.RUnlock() @@ -126,31 +104,9 @@ func (b *backend) GetSubnetOwner(_ stdcontext.Context, subnetID ids.ID) (*secp25 return owner, nil } -func getSubnetOwnerMap(pChainTxs map[ids.ID]*txs.Tx) (map[ids.ID]*secp256k1fx.OutputOwners, error) { - subnetOwner := map[ids.ID]*secp256k1fx.OutputOwners{} - // first get owners from original CreateSubnetTx - for txID, tx := range pChainTxs { - createSubnetTx, ok := tx.Unsigned.(*txs.CreateSubnetTx) - if !ok { - continue - } - owner, ok := createSubnetTx.Owner.(*secp256k1fx.OutputOwners) - if !ok { - return nil, errUnknownOwnerType - } - subnetOwner[txID] = owner - } - // then check TransferSubnetOwnershipTx - for _, tx := range pChainTxs { - transferSubnetOwnershipTx, ok := tx.Unsigned.(*txs.TransferSubnetOwnershipTx) - if !ok { - continue - } - owner, ok := transferSubnetOwnershipTx.Owner.(*secp256k1fx.OutputOwners) - if !ok { - return nil, errUnknownOwnerType - } - subnetOwner[transferSubnetOwnershipTx.Subnet] = owner - } - return subnetOwner, nil +func (b *backend) setSubnetOwner(_ stdcontext.Context, subnetID ids.ID, owner fx.Owner) { + b.subnetOwnerLock.Lock() + defer b.subnetOwnerLock.Unlock() + + b.subnetOwner[subnetID] = owner } diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index 112a3a38da65..955bc25c658c 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -10,7 +10,6 @@ import ( "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) var _ txs.Visitor = (*backendVisitor)(nil) @@ -47,14 +46,10 @@ func (b *backendVisitor) CreateChainTx(tx *txs.CreateChainTx) error { } func (b *backendVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { - owner, ok := tx.Owner.(*secp256k1fx.OutputOwners) - if !ok { - return errUnknownOwnerType - } b.b.setSubnetOwner( b.ctx, b.txID, - owner, + tx.Owner, ) return b.baseTx(&tx.BaseTx) } @@ -64,14 +59,10 @@ func (b *backendVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx } func (b *backendVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { - owner, ok := tx.Owner.(*secp256k1fx.OutputOwners) - if !ok { - return errUnknownOwnerType - } b.b.setSubnetOwner( b.ctx, tx.Subnet, - owner, + tx.Owner, ) return b.baseTx(&tx.BaseTx) } diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index e8421cd27e81..9fd68f4e96ec 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/signer" "github.com/ava-labs/avalanchego/vms/platformvm/stakeable" "github.com/ava-labs/avalanchego/vms/platformvm/txs" @@ -260,8 +261,7 @@ type Builder interface { type BuilderBackend interface { Context UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error) - GetTx(ctx stdcontext.Context, txID ids.ID) (*txs.Tx, error) - GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (*secp256k1fx.OutputOwners, error) + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) } type builder struct { @@ -1147,7 +1147,7 @@ func (b *builder) spend( } func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*secp256k1fx.Input, error) { - owner, err := b.backend.GetSubnetOwner(options.Context(), subnetID) + ownerIntf, err := b.backend.GetSubnetOwner(options.Context(), subnetID) if err != nil { return nil, fmt.Errorf( "failed to fetch subnet %q: %w", @@ -1155,6 +1155,10 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se err, ) } + owner, ok := ownerIntf.(*secp256k1fx.OutputOwners) + if !ok { + return nil, errUnknownOwnerType + } addrs := options.Addresses(b.addrs) minIssuanceTime := options.MinIssuanceTime() diff --git a/wallet/chain/p/signer.go b/wallet/chain/p/signer.go index cbe26151352f..331d8056c111 100644 --- a/wallet/chain/p/signer.go +++ b/wallet/chain/p/signer.go @@ -9,8 +9,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/crypto/keychain" "github.com/ava-labs/avalanchego/vms/components/avax" + "github.com/ava-labs/avalanchego/vms/platformvm/fx" "github.com/ava-labs/avalanchego/vms/platformvm/txs" - "github.com/ava-labs/avalanchego/vms/secp256k1fx" ) var _ Signer = (*txSigner)(nil) @@ -22,8 +22,7 @@ type Signer interface { type SignerBackend interface { GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error) - GetTx(ctx stdcontext.Context, txID ids.ID) (*txs.Tx, error) - GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (*secp256k1fx.OutputOwners, error) + GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error) } type txSigner struct { diff --git a/wallet/chain/p/signer_visitor.go b/wallet/chain/p/signer_visitor.go index 1b5524e7069d..06b05cf4b7f5 100644 --- a/wallet/chain/p/signer_visitor.go +++ b/wallet/chain/p/signer_visitor.go @@ -246,7 +246,7 @@ func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Veri return nil, errUnknownSubnetAuthType } - owner, err := s.backend.GetSubnetOwner(s.ctx, subnetID) + ownerIntf, err := s.backend.GetSubnetOwner(s.ctx, subnetID) if err != nil { return nil, fmt.Errorf( "failed to fetch subnet %q: %w", @@ -254,6 +254,10 @@ func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Veri err, ) } + owner, ok := ownerIntf.(*secp256k1fx.OutputOwners) + if !ok { + return nil, errUnknownOwnerType + } authSigners := make([]keychain.Signer, len(subnetInput.SigIndices)) for sigIndex, addrIndex := range subnetInput.SigIndices { diff --git a/wallet/subnet/primary/examples/get-p-chain-balance/main.go b/wallet/subnet/primary/examples/get-p-chain-balance/main.go index 7cb85e36fb31..336c25d2dd1b 100644 --- a/wallet/subnet/primary/examples/get-p-chain-balance/main.go +++ b/wallet/subnet/primary/examples/get-p-chain-balance/main.go @@ -8,11 +8,9 @@ import ( "log" "time" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/formatting/address" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/avalanchego/vms/platformvm/txs" "github.com/ava-labs/avalanchego/wallet/chain/p" "github.com/ava-labs/avalanchego/wallet/subnet/primary" ) @@ -38,10 +36,7 @@ func main() { log.Printf("fetched state of %s in %s\n", addrStr, time.Since(fetchStartTime)) pUTXOs := primary.NewChainUTXOs(constants.PlatformChainID, state.UTXOs) - pBackend, err := p.NewBackend(state.PCTX, pUTXOs, make(map[ids.ID]*txs.Tx)) - if err != nil { - log.Fatalf("failed to create wallet backend: %s\n", err) - } + pBackend := p.NewBackend(state.PCTX, pUTXOs, nil) pBuilder := p.NewBuilder(addresses, pBackend) currentBalances, err := pBuilder.GetBalance() diff --git a/wallet/subnet/primary/wallet.go b/wallet/subnet/primary/wallet.go index 7fdaa89893a8..3bb3e9965684 100644 --- a/wallet/subnet/primary/wallet.go +++ b/wallet/subnet/primary/wallet.go @@ -117,10 +117,7 @@ func MakeWallet(ctx context.Context, config *WalletConfig) (Wallet, error) { } pUTXOs := NewChainUTXOs(constants.PlatformChainID, avaxState.UTXOs) - pBackend, err := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) - if err != nil { - return nil, err - } + pBackend := p.NewBackend(avaxState.PCTX, pUTXOs, pChainTxs) pBuilder := p.NewBuilder(avaxAddrs, pBackend) pSigner := p.NewSigner(config.AVAXKeychain, pBackend) From 5f5241b7eb0b83438f8d3ceb968e56c8fd791a07 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 30 Jan 2024 16:50:17 -0500 Subject: [PATCH 11/15] nit --- wallet/chain/p/backend.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index c46743a0b6bf..10de46d4249f 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -39,14 +39,14 @@ type backend struct { func NewBackend(ctx Context, utxos common.ChainUTXOs, subnetTxs map[ids.ID]*txs.Tx) Backend { subnetOwner := make(map[ids.ID]fx.Owner) - for txID, tx := range subnetTxs { // first get owners from original CreateSubnetTx + for txID, tx := range subnetTxs { // first get owners from the CreateSubnetTx createSubnetTx, ok := tx.Unsigned.(*txs.CreateSubnetTx) if !ok { continue } subnetOwner[txID] = createSubnetTx.Owner } - for _, tx := range subnetTxs { // then check TransferSubnetOwnershipTx + for _, tx := range subnetTxs { // then check for TransferSubnetOwnershipTx transferSubnetOwnershipTx, ok := tx.Unsigned.(*txs.TransferSubnetOwnershipTx) if !ok { continue From 6c12c0836f3d2df5da8817175cd3555793330910 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 30 Jan 2024 16:51:19 -0500 Subject: [PATCH 12/15] nit --- wallet/chain/p/backend_visitor.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/wallet/chain/p/backend_visitor.go b/wallet/chain/p/backend_visitor.go index 955bc25c658c..c5b8951c70f6 100644 --- a/wallet/chain/p/backend_visitor.go +++ b/wallet/chain/p/backend_visitor.go @@ -47,7 +47,6 @@ func (b *backendVisitor) CreateChainTx(tx *txs.CreateChainTx) error { func (b *backendVisitor) CreateSubnetTx(tx *txs.CreateSubnetTx) error { b.b.setSubnetOwner( - b.ctx, b.txID, tx.Owner, ) @@ -60,7 +59,6 @@ func (b *backendVisitor) RemoveSubnetValidatorTx(tx *txs.RemoveSubnetValidatorTx func (b *backendVisitor) TransferSubnetOwnershipTx(tx *txs.TransferSubnetOwnershipTx) error { b.b.setSubnetOwner( - b.ctx, tx.Subnet, tx.Owner, ) From 9590787da601023849b92f25518b6cc6e506606a Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 30 Jan 2024 16:51:37 -0500 Subject: [PATCH 13/15] nit --- wallet/chain/p/backend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wallet/chain/p/backend.go b/wallet/chain/p/backend.go index 10de46d4249f..6bc4bc64909d 100644 --- a/wallet/chain/p/backend.go +++ b/wallet/chain/p/backend.go @@ -104,7 +104,7 @@ func (b *backend) GetSubnetOwner(_ stdcontext.Context, subnetID ids.ID) (fx.Owne return owner, nil } -func (b *backend) setSubnetOwner(_ stdcontext.Context, subnetID ids.ID, owner fx.Owner) { +func (b *backend) setSubnetOwner(subnetID ids.ID, owner fx.Owner) { b.subnetOwnerLock.Lock() defer b.subnetOwnerLock.Unlock() From 440e5cf7bcb819753bead305f3437e1e2db05d0e Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 30 Jan 2024 16:53:18 -0500 Subject: [PATCH 14/15] nit --- wallet/chain/p/signer_visitor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wallet/chain/p/signer_visitor.go b/wallet/chain/p/signer_visitor.go index 06b05cf4b7f5..d4475427fc95 100644 --- a/wallet/chain/p/signer_visitor.go +++ b/wallet/chain/p/signer_visitor.go @@ -249,7 +249,7 @@ func (s *signerVisitor) getSubnetSigners(subnetID ids.ID, subnetAuth verify.Veri ownerIntf, err := s.backend.GetSubnetOwner(s.ctx, subnetID) if err != nil { return nil, fmt.Errorf( - "failed to fetch subnet %q: %w", + "failed to fetch subnet owner for %q: %w", subnetID, err, ) From 14815129072950d7cd350564c114f608a6dfc41e Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 30 Jan 2024 16:53:38 -0500 Subject: [PATCH 15/15] nit --- wallet/chain/p/builder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wallet/chain/p/builder.go b/wallet/chain/p/builder.go index 9fd68f4e96ec..a2c7208ffe8a 100644 --- a/wallet/chain/p/builder.go +++ b/wallet/chain/p/builder.go @@ -1150,7 +1150,7 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se ownerIntf, err := b.backend.GetSubnetOwner(options.Context(), subnetID) if err != nil { return nil, fmt.Errorf( - "failed to fetch subnet %q: %w", + "failed to fetch subnet owner for %q: %w", subnetID, err, )