Skip to content

Commit

Permalink
feat: add migrate collect-morse-account subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanchriswhite committed Jan 27, 2025
1 parent b225150 commit 20aa71d
Show file tree
Hide file tree
Showing 8 changed files with 5,473 additions and 0 deletions.
3,374 changes: 3,374 additions & 0 deletions api/poktroll/migration/types.pulsar.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions cmd/poktrolld/cmd/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"github.com/spf13/viper"

"github.com/pokt-network/poktroll/app"
"github.com/pokt-network/poktroll/cmd/poktrolld/cmd/migrate"

Check failure on line 29 in cmd/poktrolld/cmd/commands.go

View workflow job for this annotation

GitHub Actions / go-test

could not import github.com/pokt-network/poktroll/cmd/poktrolld/cmd/migrate (-: # github.com/pokt-network/poktroll/cmd/poktrolld/cmd/migrate
)

func initRootCmd(
Expand All @@ -52,6 +53,7 @@ func initRootCmd(
queryCommand(),
txCommand(),
keys.Commands(),
migrate.MigrateCmd(),
)
}

Expand Down
188 changes: 188 additions & 0 deletions cmd/poktrolld/cmd/migrate/migrate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package migrate

import (
"fmt"
"os"

cosmosmath "cosmossdk.io/math"
cmtjson "github.com/cometbft/cometbft/libs/json"
"github.com/spf13/cobra"

"github.com/pokt-network/poktroll/app/volatile"
migrationtypes "github.com/pokt-network/poktroll/x/migration/types"
)

var collectMorseAccountsCmd = &cobra.Command{
Use: "collect-morse-accounts [morse-state-path] [morse-accounts-path]",
Args: cobra.ExactArgs(2),
Short: "Collect all account balances and corresponding stakes from the JSON file at [morse-state-path] and outputs them as JSON to [morse-accounts-path]",
Long: `Collects the account balances and corresponding stakes from the MorseStateExport JSON file at morse-state-path
and outputs them as a MorseAccountState JSON to morse-accounts-path for use with
Shannon's MsgUploadMorseState. The Morse state export is generated via the Morse CLI:
pocket util export-genesis-for-reset [height] [new-chain-id] > morse-state-export.json`,
RunE: runCollectMorseAccounts,
}

func MigrateCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "migrate",
Short: "Migration commands",
}
cmd.AddCommand(collectMorseAccountsCmd)

return cmd
}

// runCollectedMorseAccounts is run by the `poktrolld migrate collect-morse-accounts` command.
func runCollectMorseAccounts(cmd *cobra.Command, args []string) error {
inputPath := args[0]
outputPath := args[1]

return collectMorseAccounts(inputPath, outputPath)
}

// collectMorseAccounts transforms the JSON serialized MorseStateExport at
// inputStatePath into a JSON serialized MorseAccountState at outputStatePath.
func collectMorseAccounts(inputStatePath, outputStatePath string) error {
if err := validatePathIsFile(inputStatePath); err != nil {
return err
}

inputStateJSON, err := os.ReadFile(inputStatePath)
if err != nil {
return err
}

inputState := new(migrationtypes.MorseStateExport)

Check failure on line 56 in cmd/poktrolld/cmd/migrate/migrate.go

View workflow job for this annotation

GitHub Actions / go-test

undefined: migrationtypes.MorseStateExport

Check failure on line 56 in cmd/poktrolld/cmd/migrate/migrate.go

View workflow job for this annotation

GitHub Actions / go-test

undefined: migrationtypes.MorseStateExport
if err = cmtjson.Unmarshal(inputStateJSON, inputState); err != nil {
return err
}

outputStateJSON, err := transformMorseState(inputState)
if err != nil {
return err
}

if err = os.WriteFile(outputStatePath, outputStateJSON, 0644); err != nil {
return err
}

return nil
}

// validatePathIsFile returns an error if the given path does not exist or is not a file.
func validatePathIsFile(path string) error {
info, err := os.Stat(path)
if err != nil {
return err
}

if info.IsDir() {
return fmt.Errorf("[morse-JSON-input-path] cannot be a directory")
}

return nil
}

// transformMorseState consolidates the Morse account balance, application stake,
// and supplier stake for each account as an entry in the resulting MorseAccountState.
//
// TODO_IN_THIS_COMMIT: benchmark and consider at what point (i.e. number of accounts) does asynchronous import processing matter?
func transformMorseState(inputState *migrationtypes.MorseStateExport) ([]byte, error) {

Check failure on line 91 in cmd/poktrolld/cmd/migrate/migrate.go

View workflow job for this annotation

GitHub Actions / go-test

undefined: migrationtypes.MorseStateExport

Check failure on line 91 in cmd/poktrolld/cmd/migrate/migrate.go

View workflow job for this annotation

GitHub Actions / go-test

undefined: migrationtypes.MorseStateExport
morseWorkspace := &morseImportWorkspace{
addressToIdx: make(map[string]uint64),
accounts: make([]*migrationtypes.MorseAccount, 0),
}

// Iterate over accounts and copy the balances.
if err := collectInputAccountBalances(inputState, morseWorkspace); err != nil {
return nil, err
}

// Iterate over applications and add the stakes to the corresponding account balances.
if err := collectInputApplicationStakes(inputState, morseWorkspace); err != nil {
return nil, err
}

// Iterate over suppliers and add the stakes to the corresponding account balances.
err := collectInputSupplierStakes(inputState, morseWorkspace)
if err != nil {
return nil, err
}

morseAccountState := &migrationtypes.MorseAccountState{Accounts: morseWorkspace.accounts}
return cmtjson.Marshal(morseAccountState)
}

// collectInputAccountBalances iterates over the accounts in the inputState and
// adds the balances to the corresponding account balances in the morseWorkspace.
func collectInputAccountBalances(inputState *migrationtypes.MorseStateExport, morseWorkspace *morseImportWorkspace) error {

Check failure on line 119 in cmd/poktrolld/cmd/migrate/migrate.go

View workflow job for this annotation

GitHub Actions / go-test

undefined: migrationtypes.MorseStateExport

Check failure on line 119 in cmd/poktrolld/cmd/migrate/migrate.go

View workflow job for this annotation

GitHub Actions / go-test

undefined: migrationtypes.MorseStateExport
for _, exportAccount := range inputState.AppState.Auth.Accounts {
// DEV_NOTE: Ignore module accounts.
if exportAccount.Type != "posmint/Account" {
continue
}

addr := exportAccount.Value.Address.String()
morseWorkspace.ensureAccount(addr, exportAccount)

// TODO_IN_THIS_COMMIT: comment... SHOULD ONLY be one denom (upokt).
coin := exportAccount.Value.Coins[0]
if coin.Denom != volatile.DenomuPOKT {
return fmt.Errorf("unsupported denom %q", coin.Denom)
}

if err := morseWorkspace.addUpokt(addr, coin.Amount); err != nil {
return err
}
}
return nil
}

// collectInputApplicationStakes iterates over the applications in the inputState and
// adds the stake to the corresponding account balances in the morseWorkspace.
func collectInputApplicationStakes(inputState *migrationtypes.MorseStateExport, morseWorkspace *morseImportWorkspace) error {

Check failure on line 144 in cmd/poktrolld/cmd/migrate/migrate.go

View workflow job for this annotation

GitHub Actions / go-test

undefined: migrationtypes.MorseStateExport
for _, exportApplication := range inputState.AppState.Application.Applications {
addr := exportApplication.Address.String()

// DEV_NOTE: An account SHOULD exist for each actor.
if !morseWorkspace.hasAccount(addr) {
// TODO_IN_THIS_COMMIT: consolidate error types...
return fmt.Errorf("account %q not found", addr)
}

appStakeAmtUpokt, ok := cosmosmath.NewIntFromString(exportApplication.StakedTokens)
if !ok {
return fmt.Errorf("failed to parse application stake amount %q", exportApplication.StakedTokens)
}

if err := morseWorkspace.addUpokt(addr, appStakeAmtUpokt); err != nil {
return err
}
}
return nil
}

// collectInputSupplierStakes iterates over the suppliers in the inputState and
// adds the stake to the corresponding account balances in the morseWorkspace.
func collectInputSupplierStakes(inputState *migrationtypes.MorseStateExport, morseWorkspace *morseImportWorkspace) error {

Check failure on line 168 in cmd/poktrolld/cmd/migrate/migrate.go

View workflow job for this annotation

GitHub Actions / go-test

undefined: migrationtypes.MorseStateExport
for _, exportSupplier := range inputState.AppState.Pos.Validators {
addr := exportSupplier.Address.String()

// DEV_NOTE: An account SHOULD exist for each actor.
if !morseWorkspace.hasAccount(addr) {
// TODO_IN_THIS_COMMIT: consolidate error types...
return fmt.Errorf("account %q not found", addr)
}

supplierStakeAmtUpokt, ok := cosmosmath.NewIntFromString(exportSupplier.StakedTokens)
if !ok {
return fmt.Errorf("failed to parse supplier stake amount %q", exportSupplier.StakedTokens)
}

if err := morseWorkspace.addUpokt(addr, supplierStakeAmtUpokt); err != nil {
return err
}
}
return nil
}
Loading

0 comments on commit 20aa71d

Please sign in to comment.