Skip to content

Commit

Permalink
Merge pull request #9897 from filecoin-project/sbansal/eth-state-cli
Browse files Browse the repository at this point in the history
feat: cli: Add cli to inspect Eth addresses and simulate calls
  • Loading branch information
shrenujbansal authored Dec 19, 2022
2 parents a452ab7 + d916253 commit 3d3bce6
Show file tree
Hide file tree
Showing 5 changed files with 224 additions and 1 deletion.
2 changes: 2 additions & 0 deletions chain/types/ethtypes/eth_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ func (ea EthAddress) ToFilecoinAddress() (address.Address, error) {
return addr, nil
}

// This API assumes that if an ID address is passed in, it doesn't have an equivalent
// delegated address
func TryEthAddressFromFilecoinAddress(addr address.Address, allowId bool) (EthAddress, bool, error) {
switch addr.Protocol() {
case address.ID:
Expand Down
1 change: 1 addition & 0 deletions cli/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ var Commands = []*cli.Command{
WithCategory("developer", LogCmd),
WithCategory("developer", WaitApiCmd),
WithCategory("developer", FetchParamCmd),
WithCategory("developer", EthCmd),
WithCategory("network", NetCmd),
WithCategory("network", SyncCmd),
WithCategory("status", StatusCmd),
Expand Down
174 changes: 174 additions & 0 deletions cli/eth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
package cli

import (
"context"
"encoding/hex"
"fmt"

"github.com/urfave/cli/v2"
"golang.org/x/xerrors"

"github.com/filecoin-project/go-address"

"github.com/filecoin-project/lotus/api/v0api"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
)

var EthCmd = &cli.Command{
Name: "eth",
Usage: "Query eth contract state",
Subcommands: []*cli.Command{
EthGetInfoCmd,
EthCallSimulateCmd,
},
}

var EthGetInfoCmd = &cli.Command{
Name: "stat",
Usage: "Print eth/filecoin addrs and code cid",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "filAddr",
Usage: "Filecoin address",
},
&cli.StringFlag{
Name: "ethAddr",
Usage: "Ethereum address",
},
},
Action: func(cctx *cli.Context) error {

filAddr := cctx.String("filAddr")
ethAddr := cctx.String("ethAddr")

var faddr address.Address
var eaddr ethtypes.EthAddress

api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)

if filAddr != "" {
addr, err := address.NewFromString(filAddr)
if err != nil {
return err
}
eaddr, faddr, err = ethAddrFromFilecoinAddress(ctx, addr, api)
if err != nil {
return err
}
} else if ethAddr != "" {
eaddr, err = ethtypes.EthAddressFromHex(ethAddr)
if err != nil {
return err
}
faddr, err = eaddr.ToFilecoinAddress()
if err != nil {
return err
}
} else {
return xerrors.Errorf("Neither filAddr nor ethAddr specified")
}

actor, err := api.StateGetActor(ctx, faddr, types.EmptyTSK)
if err != nil {
return err
}

fmt.Println("Filecoin address: ", faddr)
fmt.Println("Eth address: ", eaddr)
fmt.Println("Code cid: ", actor.Code.String())

return nil

},
}

var EthCallSimulateCmd = &cli.Command{
Name: "call",
Usage: "Simulate an eth contract call",
ArgsUsage: "[from] [to] [params]",
Action: func(cctx *cli.Context) error {

if cctx.NArg() != 3 {
return IncorrectNumArgs(cctx)
}

fromEthAddr, err := ethtypes.EthAddressFromHex(cctx.Args().Get(0))
if err != nil {
return err
}

toEthAddr, err := ethtypes.EthAddressFromHex(cctx.Args().Get(1))
if err != nil {
return err
}

params, err := hex.DecodeString(cctx.Args().Get(2))
if err != nil {
return err
}

api, closer, err := GetFullNodeAPIV1(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)

res, err := api.EthCall(ctx, ethtypes.EthCall{
From: &fromEthAddr,
To: &toEthAddr,
Data: params,
}, "")
if err != nil {
fmt.Println("Eth call fails, return val: ", res)
return err
}

fmt.Println("Result: ", res)

return nil

},
}

func ethAddrFromFilecoinAddress(ctx context.Context, addr address.Address, fnapi v0api.FullNode) (ethtypes.EthAddress, address.Address, error) {
var faddr address.Address
var err error

switch addr.Protocol() {
case address.BLS, address.SECP256K1:
faddr, err = fnapi.StateLookupID(ctx, addr, types.EmptyTSK)
if err != nil {
return ethtypes.EthAddress{}, addr, err
}
case address.Actor, address.ID:
faddr, err = fnapi.StateLookupID(ctx, addr, types.EmptyTSK)
if err != nil {
return ethtypes.EthAddress{}, addr, err
}
fAct, err := fnapi.StateGetActor(ctx, faddr, types.EmptyTSK)
if err != nil {
return ethtypes.EthAddress{}, addr, err
}
if fAct.Address != nil && (*fAct.Address).Protocol() == address.Delegated {
faddr = *fAct.Address
}
case address.Delegated:
faddr = addr
default:
return ethtypes.EthAddress{}, addr, xerrors.Errorf("Filecoin address doesn't match known protocols")
}

ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(faddr)
if err != nil {
return ethtypes.EthAddress{}, addr, err
}

return ethAddr, faddr, nil
}
46 changes: 46 additions & 0 deletions documentation/en/cli-lotus.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ COMMANDS:
log Manage logging
wait-api Wait for lotus api to come online
fetch-params Fetch proving parameters
eth Query eth contract state
NETWORK:
net Manage P2P Network
sync Inspect or interact with the chain syncer
Expand Down Expand Up @@ -2569,6 +2570,51 @@ OPTIONS:
```

## lotus eth
```
NAME:
lotus eth - Query eth contract state
USAGE:
lotus eth command [command options] [arguments...]
COMMANDS:
stat Print eth/filecoin addrs and code cid
call Simulate an eth contract call
help, h Shows a list of commands or help for one command
OPTIONS:
--help, -h show help (default: false)
```

### lotus eth stat
```
NAME:
lotus eth stat - Print eth/filecoin addrs and code cid
USAGE:
lotus eth stat [command options] [arguments...]
OPTIONS:
--ethAddr value Ethereum address
--filAddr value Filecoin address
```

### lotus eth call
```
NAME:
lotus eth call - Simulate an eth contract call
USAGE:
lotus eth call [command options] [from] [to] [params]
OPTIONS:
--help, -h show help (default: false)
```

## lotus net
```
NAME:
Expand Down
2 changes: 1 addition & 1 deletion node/impl/full/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ func (a *EthModule) applyMessage(ctx context.Context, msg *types.Message, tsk ty
return nil, xerrors.Errorf("CallWithGas failed: %w", err)
}
if res.MsgRct.ExitCode.IsError() {
return nil, xerrors.Errorf("message execution failed: exit %s, reason: %s", res.MsgRct.ExitCode, res.Error)
return nil, xerrors.Errorf("message execution failed: exit %s, msg receipt: %s, reason: %s", res.MsgRct.ExitCode, res.MsgRct.Return, res.Error)
}
return res, nil
}
Expand Down

0 comments on commit 3d3bce6

Please sign in to comment.