Skip to content

Commit

Permalink
repackaged wallet backend for P-chain
Browse files Browse the repository at this point in the history
  • Loading branch information
abi87 committed Feb 21, 2024
1 parent 4ee5f19 commit 911b326
Show file tree
Hide file tree
Showing 15 changed files with 248 additions and 215 deletions.
9 changes: 4 additions & 5 deletions wallet/chain/p/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"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/wallet/chain/p/backends"
"github.com/ava-labs/avalanchego/wallet/subnet/primary/common"

stdcontext "context"
Expand All @@ -22,22 +23,20 @@ var _ Backend = (*backend)(nil)

// Backend defines the full interface required to support a P-chain wallet.
type Backend interface {
common.ChainUTXOs
BuilderBackend
SignerBackend
backends.Backend

AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error
}

type backend struct {
Context
backends.Context
common.ChainUTXOs

subnetOwnerLock sync.RWMutex
subnetOwner map[ids.ID]fx.Owner // subnetID -> owner
}

func NewBackend(ctx Context, utxos common.ChainUTXOs, subnetTxs map[ids.ID]*txs.Tx) Backend {
func NewBackend(ctx backends.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 the CreateSubnetTx
createSubnetTx, ok := tx.Unsigned.(*txs.CreateSubnetTx)
Expand Down
5 changes: 3 additions & 2 deletions wallet/chain/p/backend_visitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,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/wallet/chain/p/backends"

stdcontext "context"
)
Expand All @@ -22,11 +23,11 @@ type backendVisitor struct {
}

func (*backendVisitor) AdvanceTimeTx(*txs.AdvanceTimeTx) error {
return errUnsupportedTxType
return backends.ErrUnsupportedTxType
}

func (*backendVisitor) RewardValidatorTx(*txs.RewardValidatorTx) error {
return errUnsupportedTxType
return backends.ErrUnsupportedTxType
}

func (b *backendVisitor) AddValidatorTx(tx *txs.AddValidatorTx) error {
Expand Down
35 changes: 35 additions & 0 deletions wallet/chain/p/backends/backends.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package backends

import (
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/vms/components/avax"
"github.com/ava-labs/avalanchego/vms/platformvm/fx"

stdcontext "context"
)

var (
_ BuilderBackend = Backend(nil)
_ SignerBackend = Backend(nil)
)

type Backend interface {
Context
UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error)
GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error)
GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error)
}

type SignerBackend interface {
GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error)
GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error)
}

type BuilderBackend interface {
Context
UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error)
GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error)
}
29 changes: 9 additions & 20 deletions wallet/chain/p/builder.go → wallet/chain/p/backends/builder.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package p
package backends

import (
"errors"
Expand All @@ -14,21 +14,18 @@ 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"
"github.com/ava-labs/avalanchego/vms/secp256k1fx"
"github.com/ava-labs/avalanchego/wallet/subnet/primary/common"

stdcontext "context"
)

var (
errNoChangeAddress = errors.New("no possible change address")
errUnknownOwnerType = errors.New("unknown owner type")
errInsufficientAuthorization = errors.New("insufficient authorization")
errInsufficientFunds = errors.New("insufficient funds")
ErrInsufficientFunds = errors.New("insufficient funds")

_ Builder = (*builder)(nil)
)
Expand Down Expand Up @@ -256,14 +253,6 @@ type Builder interface {
) (*txs.AddPermissionlessDelegatorTx, error)
}

// BuilderBackend specifies the required information needed to build unsigned
// P-chain transactions.
type BuilderBackend interface {
Context
UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error)
GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error)
}

type builder struct {
addrs set.Set[ids.ShortID]
backend BuilderBackend
Expand Down Expand Up @@ -635,7 +624,7 @@ func (b *builder) NewImportTx(
if len(importedInputs) == 0 {
return nil, fmt.Errorf(
"%w: no UTXOs available to import",
errInsufficientFunds,
ErrInsufficientFunds,
)
}

Expand Down Expand Up @@ -900,7 +889,7 @@ func (b *builder) getBalance(

out, ok := outIntf.(*secp256k1fx.TransferOutput)
if !ok {
return nil, errUnknownOutputType
return nil, ErrUnknownOutputType
}

_, ok = common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime)
Expand Down Expand Up @@ -982,7 +971,7 @@ func (b *builder) spend(

out, ok := lockedOut.TransferableOut.(*secp256k1fx.TransferOutput)
if !ok {
return nil, nil, nil, errUnknownOutputType
return nil, nil, nil, ErrUnknownOutputType
}

inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime)
Expand Down Expand Up @@ -1063,7 +1052,7 @@ func (b *builder) spend(

out, ok := outIntf.(*secp256k1fx.TransferOutput)
if !ok {
return nil, nil, nil, errUnknownOutputType
return nil, nil, nil, ErrUnknownOutputType
}

inputSigIndices, ok := common.MatchOwners(&out.OutputOwners, addrs, minIssuanceTime)
Expand Down Expand Up @@ -1123,7 +1112,7 @@ func (b *builder) spend(
if amount != 0 {
return nil, nil, nil, fmt.Errorf(
"%w: provided UTXOs need %d more units of asset %q to stake",
errInsufficientFunds,
ErrInsufficientFunds,
amount,
assetID,
)
Expand All @@ -1133,7 +1122,7 @@ func (b *builder) spend(
if amount != 0 {
return nil, nil, nil, fmt.Errorf(
"%w: provided UTXOs need %d more units of asset %q",
errInsufficientFunds,
ErrInsufficientFunds,
amount,
assetID,
)
Expand Down Expand Up @@ -1173,7 +1162,7 @@ func (b *builder) authorizeSubnet(subnetID ids.ID, options *common.Options) (*se
}

func (b *builder) initCtx(tx txs.UnsignedTx) error {
ctx, err := newSnowContext(b.backend)
ctx, err := NewSnowContext(b.backend.NetworkID(), b.backend.AVAXAssetID())
if err != nil {
return err
}
Expand Down
119 changes: 119 additions & 0 deletions wallet/chain/p/backends/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package backends

import (
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/snow"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/logging"
)

const Alias = "P"

var _ Context = (*builderCtx)(nil)

type Context interface {
NetworkID() uint32
AVAXAssetID() ids.ID
BaseTxFee() uint64
CreateSubnetTxFee() uint64
TransformSubnetTxFee() uint64
CreateBlockchainTxFee() uint64
AddPrimaryNetworkValidatorFee() uint64
AddPrimaryNetworkDelegatorFee() uint64
AddSubnetValidatorFee() uint64
AddSubnetDelegatorFee() uint64
}

type builderCtx struct {
networkID uint32
avaxAssetID ids.ID
baseTxFee uint64
createSubnetTxFee uint64
transformSubnetTxFee uint64
createBlockchainTxFee uint64
addPrimaryNetworkValidatorFee uint64
addPrimaryNetworkDelegatorFee uint64
addSubnetValidatorFee uint64
addSubnetDelegatorFee uint64
}

func NewContext(
networkID uint32,
avaxAssetID ids.ID,
baseTxFee uint64,
createSubnetTxFee uint64,
transformSubnetTxFee uint64,
createBlockchainTxFee uint64,
addPrimaryNetworkValidatorFee uint64,
addPrimaryNetworkDelegatorFee uint64,
addSubnetValidatorFee uint64,
addSubnetDelegatorFee uint64,
) Context {
return &builderCtx{
networkID: networkID,
avaxAssetID: avaxAssetID,
baseTxFee: baseTxFee,
createSubnetTxFee: createSubnetTxFee,
transformSubnetTxFee: transformSubnetTxFee,
createBlockchainTxFee: createBlockchainTxFee,
addPrimaryNetworkValidatorFee: addPrimaryNetworkValidatorFee,
addPrimaryNetworkDelegatorFee: addPrimaryNetworkDelegatorFee,
addSubnetValidatorFee: addSubnetValidatorFee,
addSubnetDelegatorFee: addSubnetDelegatorFee,
}
}

func (c *builderCtx) NetworkID() uint32 {
return c.networkID
}

func (c *builderCtx) AVAXAssetID() ids.ID {
return c.avaxAssetID
}

func (c *builderCtx) BaseTxFee() uint64 {
return c.baseTxFee
}

func (c *builderCtx) CreateSubnetTxFee() uint64 {
return c.createSubnetTxFee
}

func (c *builderCtx) TransformSubnetTxFee() uint64 {
return c.transformSubnetTxFee
}

func (c *builderCtx) CreateBlockchainTxFee() uint64 {
return c.createBlockchainTxFee
}

func (c *builderCtx) AddPrimaryNetworkValidatorFee() uint64 {
return c.addPrimaryNetworkValidatorFee
}

func (c *builderCtx) AddPrimaryNetworkDelegatorFee() uint64 {
return c.addPrimaryNetworkDelegatorFee
}

func (c *builderCtx) AddSubnetValidatorFee() uint64 {
return c.addSubnetValidatorFee
}

func (c *builderCtx) AddSubnetDelegatorFee() uint64 {
return c.addSubnetDelegatorFee
}

func NewSnowContext(networkID uint32, avaxAssetID ids.ID) (*snow.Context, error) {
lookup := ids.NewAliaser()
return &snow.Context{
NetworkID: networkID,
SubnetID: constants.PrimaryNetworkID,
ChainID: constants.PlatformChainID,
AVAXAssetID: avaxAssetID,
Log: logging.NoLog{},
BCLookup: lookup,
}, lookup.Alias(constants.PlatformChainID, Alias)
}
18 changes: 5 additions & 13 deletions wallet/chain/p/signer.go → wallet/chain/p/backends/signer.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package p
package backends

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"

stdcontext "context"
Expand All @@ -27,25 +24,20 @@ type Signer interface {
Sign(ctx stdcontext.Context, tx *txs.Tx) error
}

type SignerBackend interface {
GetUTXO(ctx stdcontext.Context, chainID, utxoID ids.ID) (*avax.UTXO, error)
GetSubnetOwner(ctx stdcontext.Context, subnetID ids.ID) (fx.Owner, error)
}

type txSigner struct {
kc keychain.Keychain
backend SignerBackend
}

func NewSigner(kc keychain.Keychain, backend SignerBackend) Signer {
func New(kc keychain.Keychain, backend SignerBackend) Signer {
return &txSigner{
kc: kc,
backend: backend,
}
}

func (s *txSigner) Sign(ctx stdcontext.Context, tx *txs.Tx) error {
return tx.Unsigned.Visit(&signerVisitor{
return tx.Unsigned.Visit(&Visitor{
kc: s.kc,
backend: s.backend,
ctx: ctx,
Expand All @@ -55,9 +47,9 @@ func (s *txSigner) Sign(ctx stdcontext.Context, tx *txs.Tx) error {

func SignUnsigned(
ctx stdcontext.Context,
signer Signer,
s Signer,
utx txs.UnsignedTx,
) (*txs.Tx, error) {
tx := &txs.Tx{Unsigned: utx}
return tx, signer.Sign(ctx, tx)
return tx, s.Sign(ctx, tx)
}
Loading

0 comments on commit 911b326

Please sign in to comment.