Skip to content

Commit

Permalink
Make stake token address as mandatory in certain use cases (#1914)
Browse files Browse the repository at this point in the history
* Stake token address is mandatory if not run in test mode

* Mandatory stake token in rootchain fund command (in case those are minted)

* Add unit tests
  • Loading branch information
Stefan-Ethernal committed Sep 19, 2023
1 parent 38efd92 commit 4fbe4ba
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 8 deletions.
12 changes: 12 additions & 0 deletions command/rootchain/fund/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package fund

import (
"errors"
"fmt"
"math/big"

cmdhelper "github.com/0xPolygon/polygon-edge/command/helper"
rootHelper "github.com/0xPolygon/polygon-edge/command/rootchain/helper"
"github.com/0xPolygon/polygon-edge/types"
)

Expand Down Expand Up @@ -56,5 +58,15 @@ func (fp *fundParams) validateFlags() error {
fp.amountValues[i] = amountValue
}

if fp.mintStakeToken {
if fp.stakeTokenAddr == "" {
return rootHelper.ErrMandatoryStakeToken
}

if err := types.IsValidAddress(fp.stakeTokenAddr); err != nil {
return fmt.Errorf("invalid stake token address is provided: %w", err)
}
}

return nil
}
105 changes: 105 additions & 0 deletions command/rootchain/fund/params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package fund

import (
"fmt"
"testing"

"github.com/stretchr/testify/require"

rootHelper "github.com/0xPolygon/polygon-edge/command/rootchain/helper"
"github.com/0xPolygon/polygon-edge/types"
)

func Test_validateFlags(t *testing.T) {
t.Parallel()

cases := []struct {
buildParamsFn func() *fundParams
err string
}{
{
// no addresses provided
buildParamsFn: func() *fundParams {
return &fundParams{}
},
err: errNoAddressesProvided.Error(),
},
{
// inconsistent length (addresses vs amounts)
buildParamsFn: func() *fundParams {
return &fundParams{
addresses: []string{"0x1", "0x2"},
amounts: []string{"10"},
}
},
err: errInconsistentLength.Error(),
},
{
// address contains invalid characters
buildParamsFn: func() *fundParams {
return &fundParams{
addresses: []string{"0x10", "0x20"},
amounts: []string{"10", "20"},
}
},
err: "address \x10 has invalid length",
},
{
// stake token address omitted
buildParamsFn: func() *fundParams {
return &fundParams{
mintStakeToken: true,
addresses: []string{
types.StringToAddress("0x10").String(),
types.StringToAddress("0x20").String()},
amounts: []string{"10", "20"},
}
},
err: rootHelper.ErrMandatoryStakeToken.Error(),
},
{
// stake token address omitted
buildParamsFn: func() *fundParams {
return &fundParams{
mintStakeToken: true,
stakeTokenAddr: "0xA",
addresses: []string{
types.StringToAddress("0x10").String(),
types.StringToAddress("0x20").String()},
amounts: []string{"10", "20"},
}
},
err: "invalid stake token address is provided",
},
{
// valid scenario
buildParamsFn: func() *fundParams {
return &fundParams{
addresses: []string{
types.StringToAddress("0x10").String(),
types.StringToAddress("0x20").String()},
amounts: []string{"10", "20"},
}
},
err: "",
},
}

for i, c := range cases {
c := c
i := i

t.Run(fmt.Sprintf("case#%d", i+1), func(t *testing.T) {
t.Parallel()

fp := c.buildParamsFn()

err := fp.validateFlags()
if c.err != "" {
require.ErrorContains(t, err, c.err)
} else {
require.NoError(t, err)
}
})
}
}
7 changes: 4 additions & 3 deletions command/rootchain/helper/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ const (
)

var (
ErrRootchainNotFound = errors.New("rootchain not found")
ErrRootchainPortBind = errors.New("port 8545 is not bind with localhost")
errTestModeSecrets = errors.New("rootchain test mode does not imply specifying secrets parameters")
ErrRootchainNotFound = errors.New("rootchain not found")
ErrRootchainPortBind = errors.New("port 8545 is not bind with localhost")
ErrMandatoryStakeToken = errors.New("stake token address is mandatory")
errTestModeSecrets = errors.New("rootchain test mode does not imply specifying secrets parameters")

rootchainAccountKey *wallet.Key
)
Expand Down
19 changes: 17 additions & 2 deletions command/rootchain/supernet/stakemanager/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"os"

"github.com/0xPolygon/polygon-edge/command/helper"
rootHelper "github.com/0xPolygon/polygon-edge/command/rootchain/helper"
sidechainHelper "github.com/0xPolygon/polygon-edge/command/sidechain"
"github.com/0xPolygon/polygon-edge/types"
)

type stakeManagerDeployParams struct {
Expand All @@ -19,10 +21,23 @@ type stakeManagerDeployParams struct {
}

func (s *stakeManagerDeployParams) validateFlags() error {
if !s.isTestMode && s.privateKey == "" {
return sidechainHelper.ValidateSecretFlags(s.accountDir, s.accountConfig)
if !s.isTestMode {
// private key is mandatory
if s.privateKey == "" {
return sidechainHelper.ValidateSecretFlags(s.accountDir, s.accountConfig)
}

// stake token address is mandatory
if s.stakeTokenAddress == "" {
return rootHelper.ErrMandatoryStakeToken
}

if err := types.IsValidAddress(s.stakeTokenAddress); err != nil {
return fmt.Errorf("invalid stake token address is provided: %w", err)
}
}

// check if provided genesis path is valid
if _, err := os.Stat(s.genesisPath); err != nil {
return fmt.Errorf("provided genesis path '%s' is invalid. Error: %w ", s.genesisPath, err)
}
Expand Down
48 changes: 48 additions & 0 deletions command/rootchain/supernet/stakemanager/params_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package stakemanager

import (
"fmt"
"testing"

"github.com/stretchr/testify/require"

rootHelper "github.com/0xPolygon/polygon-edge/command/rootchain/helper"
)

func TestValidateFlags(t *testing.T) {
t.Parallel()

testCases := []struct {
params *stakeManagerDeployParams
errMsg string
}{
{
params: &stakeManagerDeployParams{
isTestMode: false,
privateKey: rootHelper.TestAccountPrivKey,
stakeTokenAddress: "",
},
errMsg: rootHelper.ErrMandatoryStakeToken.Error(),
},
{
params: &stakeManagerDeployParams{
isTestMode: false,
privateKey: rootHelper.TestAccountPrivKey,
stakeTokenAddress: "0x1B",
},
errMsg: "invalid stake token address is provided",
},
}

for i, tc := range testCases {
i := i
tc := tc

t.Run(fmt.Sprintf("case#%d", i+1), func(t *testing.T) {
t.Parallel()

err := tc.params.validateFlags()
require.ErrorContains(t, err, tc.errMsg)
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func GetCommand() *cobra.Command {
stakeMgrDeployCmd := &cobra.Command{
Use: "stake-manager-deploy",
Short: "Command for deploying stake manager contract on rootchain",
PreRunE: runPreRun,
PreRunE: preRunCommand,
RunE: runCommand,
}

Expand All @@ -33,7 +33,7 @@ func GetCommand() *cobra.Command {
return stakeMgrDeployCmd
}

func runPreRun(cmd *cobra.Command, _ []string) error {
func preRunCommand(cmd *cobra.Command, _ []string) error {
params.jsonRPC = helper.GetJSONRPCAddress(cmd)

return params.validateFlags()
Expand Down
2 changes: 1 addition & 1 deletion types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func IsValidAddress(address string) error {

// check if the address has the correct length
if len(decodedAddress) != AddressLength {
return fmt.Errorf("address %s has invalid length", address)
return fmt.Errorf("address %s has invalid length", string(decodedAddress))
}

return nil
Expand Down

0 comments on commit 4fbe4ba

Please sign in to comment.