Skip to content

Commit

Permalink
fix the issue regarding the return value and input address parsing in…
Browse files Browse the repository at this point in the history
… the precompile (#164)
  • Loading branch information
TimmyExogenous authored Aug 27, 2024
1 parent 702832d commit 5a59729
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 29 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ require (
github.com/armon/go-metrics v0.4.1
github.com/cometbft/cometbft v0.37.4
github.com/cometbft/cometbft-db v0.8.0
github.com/cosmos/btcutil v1.0.5
github.com/cosmos/cosmos-proto v1.0.0-beta.3
github.com/cosmos/cosmos-sdk v0.47.8
github.com/cosmos/go-bip39 v1.0.0
Expand Down Expand Up @@ -92,6 +91,7 @@ require (
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/coinbase/rosetta-sdk-go/types v1.0.0 // indirect
github.com/confio/ics23/go v0.9.0 // indirect
github.com/cosmos/btcutil v1.0.5 // indirect
github.com/cosmos/gogogateway v1.2.0 // indirect
github.com/cosmos/iavl v0.20.1 // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions precompiles/assets/assets.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (p Precompile) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) (bz [
// this is a workaround because the error returned by precompile can not be caught in EVM
// see https://github.com/ExocoreNetwork/exocore/issues/70
// TODO: we should figure out root cause and fix this issue to make precompiles work normally
bz, err = method.Outputs.Pack(false) // Adjust based on actual needs
bz, err = method.Outputs.Pack(false, false) // Adjust based on actual needs
}
case MethodRegisterOrUpdateTokens:
bz, err = p.RegisterOrUpdateTokens(ctx, contract, method, args)
Expand All @@ -116,7 +116,7 @@ func (p Precompile) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) (bz [
// this is a workaround because the error returned by precompile can not be caught in EVM
// see https://github.com/ExocoreNetwork/exocore/issues/70
// TODO: we should figure out root cause and fix this issue to make precompiles work normally
bz, err = method.Outputs.Pack(false) // Adjust based on actual needs
bz, err = method.Outputs.Pack(false, false) // Adjust based on actual needs
}
// queries
case MethodGetClientChains:
Expand Down
30 changes: 20 additions & 10 deletions precompiles/delegation/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,20 @@ func (p Precompile) AssociateOperatorWithStaker(
if !ok {
return nil, fmt.Errorf(exocmn.ErrContractInputParaOrType, 0, "uint32", args[0])
}

info, err := p.assetsKeeper.GetClientChainInfoByIndex(ctx, uint64(clientChainID))
if err != nil {
return nil, err
}
clientChainAddrLength := info.AddressLength
staker, ok := args[1].([]byte)
if !ok || staker == nil {
return nil, fmt.Errorf(exocmn.ErrContractInputParaOrType, 1, "[]byte", args[1])
}
// TODO: In the future, the check should be the same as it is in delegation if using LayerZero to route the
// message for non-EVM client chains, such as Solana.
if len(staker) != common.AddressLength {
return nil, fmt.Errorf(exocmn.ErrInvalidEVMAddr, staker)
if uint32(len(staker)) < clientChainAddrLength {
return nil, fmt.Errorf(exocmn.ErrInvalidAddrLength, len(staker), clientChainAddrLength)
}
staker = staker[:clientChainAddrLength]

operator, ok := args[2].([]byte)
if !ok || operator == nil {
Expand All @@ -133,7 +138,7 @@ func (p Precompile) AssociateOperatorWithStaker(
if err != nil {
return nil, fmt.Errorf("failed to parse the operator address from Bech32, operator:%s, error:%s ", operator, err.Error())
}
err = p.delegationKeeper.AssociateOperatorWithStaker(ctx, uint64(clientChainID), operatorAccAddr, common.Address(staker))
err = p.delegationKeeper.AssociateOperatorWithStaker(ctx, uint64(clientChainID), operatorAccAddr, staker)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -161,17 +166,22 @@ func (p Precompile) DissociateOperatorFromStaker(
if !ok {
return nil, fmt.Errorf(exocmn.ErrContractInputParaOrType, 0, "uint32", args[0])
}
info, err := p.assetsKeeper.GetClientChainInfoByIndex(ctx, uint64(clientChainID))
if err != nil {
return nil, err
}
clientChainAddrLength := info.AddressLength

staker, ok := args[1].([]byte)
if !ok || staker == nil {
return nil, fmt.Errorf(exocmn.ErrContractInputParaOrType, 1, "[]byte", args[1])
}
// TODO: In the future, the check should be the same as it is in delegation if using LayerZero to route the
// message for non-EVM client chains, such as Solana.
if len(staker) != common.AddressLength {
return nil, fmt.Errorf(exocmn.ErrInvalidEVMAddr, staker)
if uint32(len(staker)) < clientChainAddrLength {
return nil, fmt.Errorf(exocmn.ErrInvalidAddrLength, len(staker), clientChainAddrLength)
}
staker = staker[:clientChainAddrLength]

err = p.delegationKeeper.DissociateOperatorFromStaker(ctx, uint64(clientChainID), common.Address(staker))
err = p.delegationKeeper.DissociateOperatorFromStaker(ctx, uint64(clientChainID), staker)
if err != nil {
return nil, err
}
Expand Down
10 changes: 4 additions & 6 deletions x/delegation/keeper/delegation.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package keeper
import (
"fmt"

"github.com/ethereum/go-ethereum/common"

errorsmod "cosmossdk.io/errors"
assetstype "github.com/ExocoreNetwork/exocore/x/assets/types"
delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types"
Expand Down Expand Up @@ -167,7 +165,7 @@ func (k *Keeper) AssociateOperatorWithStaker(
ctx sdk.Context,
clientChainID uint64,
operatorAddress sdk.AccAddress,
stakerAddress common.Address,
stakerAddress []byte,
) error {
if !k.assetsKeeper.ClientChainExists(ctx, clientChainID) {
return delegationtype.ErrClientChainNotExist
Expand All @@ -176,7 +174,7 @@ func (k *Keeper) AssociateOperatorWithStaker(
return delegationtype.ErrOperatorNotExist
}

stakerID, _ := assetstype.GetStakeIDAndAssetID(clientChainID, stakerAddress[:], nil)
stakerID, _ := assetstype.GetStakeIDAndAssetID(clientChainID, stakerAddress, nil)
associatedOperator, err := k.GetAssociatedOperator(ctx, stakerID)
if err != nil {
return err
Expand Down Expand Up @@ -217,9 +215,9 @@ func (k *Keeper) AssociateOperatorWithStaker(
func (k *Keeper) DissociateOperatorFromStaker(
ctx sdk.Context,
clientChainID uint64,
stakerAddress common.Address,
stakerAddress []byte,
) error {
stakerID, _ := assetstype.GetStakeIDAndAssetID(clientChainID, stakerAddress[:], nil)
stakerID, _ := assetstype.GetStakeIDAndAssetID(clientChainID, stakerAddress, nil)
associatedOperator, err := k.GetAssociatedOperator(ctx, stakerID)
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion x/delegation/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (k Keeper) InitGenesis(
// #nosec G703 // already validated
stakerAddress, clientChainID, _ := assetstype.ParseID(stakerID)
// we have checked IsHexAddress already
stakerAddressBytes := common.HexToAddress(stakerAddress)
stakerAddressBytes := common.FromHex(stakerAddress)
// #nosec G703 // already validated
accAddress, _ := sdk.AccAddressFromBech32(operatorAddress)
// this can only fail if the operator is not registered
Expand Down
4 changes: 2 additions & 2 deletions x/dogfood/keeper/impl_epochs_hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (suite *KeeperTestSuite) TestSameEpochOperations() {
suite.NoError(err)
// self delegate
err = suite.App.DelegationKeeper.AssociateOperatorWithStaker(
suite.Ctx, lzID, operatorAddress, staker,
suite.Ctx, lzID, operatorAddress, staker.Bytes(),
)
suite.NoError(err)
}
Expand Down Expand Up @@ -244,7 +244,7 @@ func (suite *KeeperTestSuite) TestDifferentEpochOperations() {
suite.NoError(err)
// self delegate
err = suite.App.DelegationKeeper.AssociateOperatorWithStaker(
suite.Ctx, lzID, operatorAddress, staker,
suite.Ctx, lzID, operatorAddress, staker.Bytes(),
)
suite.NoError(err)
}
Expand Down
2 changes: 1 addition & 1 deletion x/dogfood/keeper/opt_out_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (suite *KeeperTestSuite) TestBasicOperations() {
suite.CheckLengthOfValidatorUpdates(0, nil, "delegate but not self delegate")
// mark it as self delegation
err = suite.App.DelegationKeeper.AssociateOperatorWithStaker(
suite.Ctx, lzID, operatorAddress, staker,
suite.Ctx, lzID, operatorAddress, staker.Bytes(),
)
suite.NoError(err)
suite.CheckLengthOfValidatorUpdates(0, nil, "self delegate but below min")
Expand Down
4 changes: 2 additions & 2 deletions x/dogfood/keeper/unbonding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func (suite *KeeperTestSuite) TestUndelegations() {
suite.NoError(err)
// self delegate
err = suite.App.DelegationKeeper.AssociateOperatorWithStaker(
suite.Ctx, lzID, operatorAddress, staker,
suite.Ctx, lzID, operatorAddress, staker.Bytes(),
)
suite.NoError(err)
// opt in
Expand Down Expand Up @@ -202,7 +202,7 @@ func (suite *KeeperTestSuite) TestUndelegationEdgeCases() {
suite.NoError(err)
// mark as self delegation
err = suite.App.DelegationKeeper.AssociateOperatorWithStaker(
suite.Ctx, lzID, operatorAddress, staker,
suite.Ctx, lzID, operatorAddress, staker.Bytes(),
)
suite.NoError(err)
suite.CheckLengthOfValidatorUpdates(0, []int64{}, "delegate without opt in")
Expand Down
8 changes: 4 additions & 4 deletions x/operator/keeper/usd_value.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
assetstype "github.com/ExocoreNetwork/exocore/x/assets/types"
delegationkeeper "github.com/ExocoreNetwork/exocore/x/delegation/keeper"
delegationtype "github.com/ExocoreNetwork/exocore/x/delegation/types"
oracletypes "github.com/ExocoreNetwork/exocore/x/oracle/types"
oracletype "github.com/ExocoreNetwork/exocore/x/oracle/types"

errorsmod "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
Expand Down Expand Up @@ -283,7 +283,7 @@ func (k *Keeper) CalculateUSDValueForOperator(
operator string,
assetsFilter map[string]interface{},
decimals map[string]uint32,
prices map[string]oracletypes.Price,
prices map[string]oracletype.Price,
) (operatortypes.OperatorStakingInfo, error) {
var err error
ret := operatortypes.OperatorStakingInfo{
Expand All @@ -294,15 +294,15 @@ func (k *Keeper) CalculateUSDValueForOperator(
// iterate all assets owned by the operator to calculate its voting power
opFuncToIterateAssets := func(assetID string, state *assetstype.OperatorAssetInfo) error {
// var price operatortypes.Price
var price oracletypes.Price
var price oracletype.Price
var decimal uint32
if isForSlash {
// when calculated the USD value for slashing, the input prices map is null
// so the price needs to be retrieved here
price, err = k.oracleKeeper.GetSpecifiedAssetsPrice(ctx, assetID)
if err != nil {
// TODO: when assetID is not registered in oracle module, this error will finally lead to panic
if !errors.Is(err, oracletypes.ErrGetPriceRoundNotFound) {
if !errors.Is(err, oracletype.ErrGetPriceRoundNotFound) {
return err
}
// TODO: for now, we ignore the error when the price round is not found and set the price to 1 to avoid panic
Expand Down

0 comments on commit 5a59729

Please sign in to comment.