Skip to content

Commit

Permalink
Add partial-sync support to the wallet (#3567)
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenButtolph authored Dec 2, 2024
1 parent f9d4e39 commit 912f6f9
Show file tree
Hide file tree
Showing 18 changed files with 153 additions and 120 deletions.
12 changes: 4 additions & 8 deletions vms/example/xsvm/cmd/chain/create/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,13 @@ func createFunc(c *cobra.Command, args []string) error {
ctx := c.Context()
kc := secp256k1fx.NewKeychain(config.PrivateKey)

// NewWalletFromURI fetches the available UTXOs owned by [kc] on the network
// that [uri] is hosting.
// MakePWallet fetches the available UTXOs owned by [kc] on the P-chain that
// [uri] is hosting.
walletSyncStartTime := time.Now()
wallet, err := primary.MakeWallet(
wallet, err := primary.MakePWallet(
ctx,
config.URI,
kc,
kc,
primary.WalletConfig{
SubnetIDs: []ids.ID{config.SubnetID},
},
Expand All @@ -55,9 +54,6 @@ func createFunc(c *cobra.Command, args []string) error {
}
log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime))

// Get the P-chain wallet
pWallet := wallet.P()

genesisBytes, err := genesis.Codec.Marshal(genesis.CodecVersion, &genesis.Genesis{
Timestamp: 0,
Allocations: []genesis.Allocation{
Expand All @@ -72,7 +68,7 @@ func createFunc(c *cobra.Command, args []string) error {
}

createChainStartTime := time.Now()
createChainTxID, err := pWallet.IssueCreateChainTx(
createChainTxID, err := wallet.IssueCreateChainTx(
config.SubnetID,
genesisBytes,
constants.XSVMID,
Expand Down
26 changes: 26 additions & 0 deletions vms/platformvm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,3 +687,29 @@ func GetDeactivationOwners(
}
return deactivationOwners, nil
}

// GetOwners returns the union of GetSubnetOwners and GetDeactivationOwners.
func GetOwners(
c Client,
ctx context.Context,
subnetIDs []ids.ID,
validationIDs []ids.ID,
) (map[ids.ID]fx.Owner, error) {
subnetOwners, err := GetSubnetOwners(c, ctx, subnetIDs...)
if err != nil {
return nil, err
}
deactivationOwners, err := GetDeactivationOwners(c, ctx, validationIDs...)
if err != nil {
return nil, err
}

owners := make(map[ids.ID]fx.Owner, len(subnetOwners)+len(deactivationOwners))
for id, owner := range subnetOwners {
owners[id] = owner
}
for id, owner := range deactivationOwners {
owners[id] = owner
}
return owners, nil
}
20 changes: 9 additions & 11 deletions wallet/chain/p/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"context"

"github.com/ava-labs/avalanchego/api/info"
"github.com/ava-labs/avalanchego/vms/avm"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/vms/platformvm"
"github.com/ava-labs/avalanchego/vms/platformvm/txs/fee"
"github.com/ava-labs/avalanchego/wallet/chain/p/builder"
Expand All @@ -21,42 +21,40 @@ const gasPriceMultiplier = 2

func NewContextFromURI(ctx context.Context, uri string) (*builder.Context, error) {
infoClient := info.NewClient(uri)
xChainClient := avm.NewClient(uri, "X")
pChainClient := platformvm.NewClient(uri)
return NewContextFromClients(ctx, infoClient, xChainClient, pChainClient)
chainClient := platformvm.NewClient(uri)
return NewContextFromClients(ctx, infoClient, chainClient)
}

func NewContextFromClients(
ctx context.Context,
infoClient info.Client,
xChainClient avm.Client,
pChainClient platformvm.Client,
chainClient platformvm.Client,
) (*builder.Context, error) {
networkID, err := infoClient.GetNetworkID(ctx)
if err != nil {
return nil, err
}

asset, err := xChainClient.GetAssetDescription(ctx, "AVAX")
avaxAssetID, err := chainClient.GetStakingAssetID(ctx, constants.PrimaryNetworkID)
if err != nil {
return nil, err
}

dynamicFeeConfig, err := pChainClient.GetFeeConfig(ctx)
dynamicFeeConfig, err := chainClient.GetFeeConfig(ctx)
if err != nil {
return nil, err
}

// TODO: After Etna is activated, assume the gas price is always non-zero.
if dynamicFeeConfig.MinPrice != 0 {
_, gasPrice, _, err := pChainClient.GetFeeState(ctx)
_, gasPrice, _, err := chainClient.GetFeeState(ctx)
if err != nil {
return nil, err
}

return &builder.Context{
NetworkID: networkID,
AVAXAssetID: asset.AssetID,
AVAXAssetID: avaxAssetID,
ComplexityWeights: dynamicFeeConfig.Weights,
GasPrice: gasPriceMultiplier * gasPrice,
}, nil
Expand All @@ -69,7 +67,7 @@ func NewContextFromClients(

return &builder.Context{
NetworkID: networkID,
AVAXAssetID: asset.AssetID,
AVAXAssetID: avaxAssetID,
StaticFeeConfig: fee.StaticConfig{
TxFee: uint64(staticFeeConfig.TxFee),
CreateSubnetTxFee: uint64(staticFeeConfig.CreateSubnetTxFee),
Expand Down
34 changes: 33 additions & 1 deletion wallet/subnet/primary/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func FetchState(
xClient := avm.NewClient(uri, "X")
cClient := evm.NewCChainClient(uri)

pCTX, err := p.NewContextFromClients(ctx, infoClient, xClient, pClient)
pCTX, err := p.NewContextFromClients(ctx, infoClient, pClient)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -145,6 +145,38 @@ func FetchState(
}, nil
}

func FetchPState(
ctx context.Context,
uri string,
addrs set.Set[ids.ShortID],
) (
platformvm.Client,
*pbuilder.Context,
walletcommon.UTXOs,
error,
) {
infoClient := info.NewClient(uri)
chainClient := platformvm.NewClient(uri)

context, err := p.NewContextFromClients(ctx, infoClient, chainClient)
if err != nil {
return nil, nil, nil, err
}

utxos := walletcommon.NewUTXOs()
addrList := addrs.List()
err = AddAllUTXOs(
ctx,
utxos,
chainClient,
txs.Codec,
constants.PlatformChainID,
constants.PlatformChainID,
addrList,
)
return chainClient, context, utxos, err
}

type EthState struct {
Client ethclient.Client
Accounts map[ethcommon.Address]*c.Account
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,13 @@ func main() {
}
log.Printf("fetched node ID %s in %s\n", nodeID, time.Since(nodeInfoStartTime))

// MakeWallet fetches the available UTXOs owned by [kc] on the network that
// MakePWallet fetches the available UTXOs owned by [kc] on the P-chain that
// [uri] is hosting and registers [subnetID].
walletSyncStartTime := time.Now()
wallet, err := primary.MakeWallet(
wallet, err := primary.MakePWallet(
ctx,
uri,
kc,
kc,
primary.WalletConfig{
SubnetIDs: []ids.ID{subnetID},
},
Expand All @@ -58,11 +57,8 @@ func main() {
}
log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime))

// Get the P-chain wallet
pWallet := wallet.P()

addValidatorStartTime := time.Now()
addValidatorTx, err := pWallet.IssueAddSubnetValidatorTx(&txs.SubnetValidator{
addValidatorTx, err := wallet.IssueAddSubnetValidatorTx(&txs.SubnetValidator{
Validator: txs.Validator{
NodeID: nodeID,
Start: uint64(startTime.Unix()),
Expand Down
16 changes: 6 additions & 10 deletions wallet/subnet/primary/examples/add-primary-validator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,37 +39,33 @@ func main() {
}
log.Printf("fetched node ID %s in %s\n", nodeID, time.Since(nodeInfoStartTime))

// MakeWallet fetches the available UTXOs owned by [kc] on the network that
// MakePWallet fetches the available UTXOs owned by [kc] on the P-chain that
// [uri] is hosting.
walletSyncStartTime := time.Now()
wallet, err := primary.MakeWallet(
wallet, err := primary.MakePWallet(
ctx,
uri,
kc,
kc,
primary.WalletConfig{},
)
if err != nil {
log.Fatalf("failed to initialize wallet: %s\n", err)
}
log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime))

// Get the P-chain wallet
pWallet := wallet.P()
pBuilder := pWallet.Builder()
pContext := pBuilder.Context()
avaxAssetID := pContext.AVAXAssetID
// Get the chain context
context := wallet.Builder().Context()

addValidatorStartTime := time.Now()
addValidatorTx, err := pWallet.IssueAddPermissionlessValidatorTx(
addValidatorTx, err := wallet.IssueAddPermissionlessValidatorTx(
&txs.SubnetValidator{Validator: txs.Validator{
NodeID: nodeID,
Start: uint64(startTime.Unix()),
End: uint64(startTime.Add(duration).Unix()),
Wght: weight,
}},
nodePOP,
avaxAssetID,
context.AVAXAssetID,
&secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{validatorRewardAddr},
Expand Down
2 changes: 1 addition & 1 deletion wallet/subnet/primary/examples/c-chain-export/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func main() {
}
log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime))

// Get the P-chain wallet
// Get the chain wallets
pWallet := wallet.P()
cWallet := wallet.C()

Expand Down
2 changes: 1 addition & 1 deletion wallet/subnet/primary/examples/c-chain-import/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func main() {
}
log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime))

// Get the P-chain wallet
// Get the chain wallets
pWallet := wallet.P()
cWallet := wallet.C()

Expand Down
10 changes: 3 additions & 7 deletions wallet/subnet/primary/examples/convert-subnet-to-l1/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,13 @@ func main() {
log.Fatalf("failed to calculate conversionID: %s\n", err)
}

// MakeWallet fetches the available UTXOs owned by [kc] on the network that
// MakePWallet fetches the available UTXOs owned by [kc] on the P-chain that
// [uri] is hosting and registers [subnetID].
walletSyncStartTime := time.Now()
wallet, err := primary.MakeWallet(
wallet, err := primary.MakePWallet(
ctx,
uri,
kc,
kc,
primary.WalletConfig{
SubnetIDs: []ids.ID{subnetID},
},
Expand All @@ -77,11 +76,8 @@ func main() {
}
log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime))

// Get the P-chain wallet
pWallet := wallet.P()

convertSubnetToL1StartTime := time.Now()
convertSubnetToL1Tx, err := pWallet.IssueConvertSubnetToL1Tx(
convertSubnetToL1Tx, err := wallet.IssueConvertSubnetToL1Tx(
subnetID,
chainID,
address,
Expand Down
10 changes: 3 additions & 7 deletions wallet/subnet/primary/examples/create-chain/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,13 @@ func main() {

ctx := context.Background()

// MakeWallet fetches the available UTXOs owned by [kc] on the network that
// MakePWallet fetches the available UTXOs owned by [kc] on the P-chain that
// [uri] is hosting and registers [subnetID].
walletSyncStartTime := time.Now()
wallet, err := primary.MakeWallet(
wallet, err := primary.MakePWallet(
ctx,
uri,
kc,
kc,
primary.WalletConfig{
SubnetIDs: []ids.ID{subnetID},
},
Expand All @@ -64,11 +63,8 @@ func main() {
}
log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime))

// Get the P-chain wallet
pWallet := wallet.P()

createChainStartTime := time.Now()
createChainTx, err := pWallet.IssueCreateChainTx(
createChainTx, err := wallet.IssueCreateChainTx(
subnetID,
genesisBytes,
vmID,
Expand Down
16 changes: 6 additions & 10 deletions wallet/subnet/primary/examples/create-locked-stakeable/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,28 @@ func main() {

ctx := context.Background()

// MakeWallet fetches the available UTXOs owned by [kc] on the network that
// MakePWallet fetches the available UTXOs owned by [kc] on the P-chain that
// [uri] is hosting.
walletSyncStartTime := time.Now()
wallet, err := primary.MakeWallet(
wallet, err := primary.MakePWallet(
ctx,
uri,
kc,
kc,
primary.WalletConfig{},
)
if err != nil {
log.Fatalf("failed to initialize wallet: %s\n", err)
}
log.Printf("synced wallet in %s\n", time.Since(walletSyncStartTime))

// Get the P-chain wallet
pWallet := wallet.P()
pBuilder := pWallet.Builder()
pContext := pBuilder.Context()
avaxAssetID := pContext.AVAXAssetID
// Get the chain context
context := wallet.Builder().Context()

issueTxStartTime := time.Now()
tx, err := pWallet.IssueBaseTx([]*avax.TransferableOutput{
tx, err := wallet.IssueBaseTx([]*avax.TransferableOutput{
{
Asset: avax.Asset{
ID: avaxAssetID,
ID: context.AVAXAssetID,
},
Out: &stakeable.LockOut{
Locktime: locktime,
Expand Down
Loading

0 comments on commit 912f6f9

Please sign in to comment.