From 1f579f28757a0a913da4a5f722c1e319a44465a1 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 21 Feb 2024 12:20:00 -0800 Subject: [PATCH] feat: api: improve the correctness of Eth's trace_block (#11609) * Improve the correctness of Eth's trace_block - Improve encoding/decoding of parameters and return values: - Encode "native" parameters and return values with Solidity ABI. - Correctly decode parameters to "create" calls. - Use the correct (ish) output for "create" calls. - Handle all forms of "create". - Make robust with respect to reverts: - Use the actor ID/address from the trace instead of looking it up in the state-tree (may not exist in the state-tree due to a revert). - Gracefully handle failed actor/contract creation. - Improve performance: - We avoid looking anything up in the state-tree when translating the trace, which should significantly improve performance. - Improve code readability: - Remove all "backtracking" logic. - Use an "environment" struct to store temporary state instead of attaching it to the trace. - Fix random bugs: - Fix an allocation bug in the "address" logic (need to set the capacity before modifying the slice). - Improved error checking/handling. - Use correct types for `trace_block` action/results (create, call, etc.). - And use the correct types for Result/Action structs instead of reusing the same "Call" action every time. - Improve error messages. --- CHANGELOG.md | 17 + api/api_full.go | 19 +- build/openrpc/full.json.gz | Bin 35035 -> 35372 bytes build/openrpc/gateway.json.gz | Bin 11922 -> 11854 bytes chain/actors/builtin/evm/actor.go.template | 14 + chain/actors/builtin/evm/evm.go | 13 + chain/types/ethtypes/eth_types.go | 58 +- documentation/en/api-v1-unstable-methods.md | 52 +- node/impl/full/eth.go | 61 +- node/impl/full/eth_test.go | 40 ++ node/impl/full/eth_trace.go | 701 +++++++++++++++----- node/impl/full/eth_utils.go | 31 +- 12 files changed, 729 insertions(+), 277 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 88ccfa97101..abcdf3e5448 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,23 @@ Replace the `CodeCid` field in the message trace (added in 1.23.4) with an `Invo This means the trace now contains an accurate "snapshot" of the actor at the time of the call, information that may not be present in the final state-tree (e.g., due to reverts). This will hopefully improve the performance and accuracy of indexing services. +### Ethereum Tracing API (`trace_block` and `trace_replayBlockTransactions`) + +For those with the Ethereum JSON-RPC API enabled, the experimental Ethereum Tracing API has been improved significantly and should be considered "functional". However, it's still new and should be tested extensively before relying on it. This API translates FVM traces to Ethereum-style traces, implementing the OpenEthereum `trace_block` and `trace_replayBlockTransactions` APIs. + +This release fixes numerous bugs with this API and now ABI-encodes non-EVM inputs/outputs as if they were explicit EVM calls to [`handle_filecoin_method`][handlefilecoinmethod] for better block explorer compatibility. + +However, there are some _significant_ limitations: + +1. The Geth APIs are not implemented, only the OpenEthereum (Erigon, etc.) APIs. +2. Block rewards are not (yet) included in the trace. +3. Selfdestruct operations are not included in the trace. +4. EVM smart contract "create" events always specify `0xfe` as the "code" for newly created EVM smart contracts. + +Additionally, Filecoin is not Ethereum no matter how much we try to provide API/tooling compatibility. This API attempts to translate Filecoin semantics into Ethereum semantics as accurately as possible, but it's hardly the best source of data unless you _need_ Filecoin to look like an Ethereum compatible chain. If you're trying to build a new integration with Filecoin, please use the native `StateCompute` method instead. + +[handlefilecoinmethod]: https://fips.filecoin.io/FIPS/fip-0054.html#handlefilecoinmethod-general-handler-for-method-numbers--1024 + # v1.25.2 / 2024-01-11 This is an optional but **highly recommended feature release** of Lotus, as it includes fixes for synchronizations issues that users have experienced. The feature release also introduces `Lotus-Provider` in its alpha testing phase, as well as the ability to call external PC2-binaries during the sealing process. diff --git a/api/api_full.go b/api/api_full.go index dc219718d0b..96f02b5fda2 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -871,9 +871,26 @@ type FullNode interface { Web3ClientVersion(ctx context.Context) (string, error) //perm:read // TraceAPI related methods + + // Returns an OpenEthereum-compatible trace of the given block (implementing `trace_block`), + // translating Filecoin semantics into Ethereum semantics and tracing both EVM and FVM calls. + // + // Features: + // + // - FVM actor create events, calls, etc. show up as if they were EVM smart contract events. + // - Native FVM call inputs are ABI-encoded (Solidity ABI) as if they were calls to a + // `handle_filecoin_method(uint64 method, uint64 codec, bytes params)` function + // (where `codec` is the IPLD codec of `params`). + // - Native FVM call outputs (return values) are ABI-encoded as `(uint32 exit_code, uint64 + // codec, bytes output)` where `codec` is the IPLD codec of `output`. // - // Returns traces created at given block + // Limitations (for now): + // + // 1. Block rewards are not included in the trace. + // 2. SELFDESTRUCT operations are not included in the trace. + // 3. EVM smart contract "create" events always specify `0xfe` as the "code" for newly created EVM smart contracts. EthTraceBlock(ctx context.Context, blkNum string) ([]*ethtypes.EthTraceBlock, error) //perm:read + // Replays all transactions in a block returning the requested traces for each transaction EthTraceReplayBlockTransactions(ctx context.Context, blkNum string, traceTypes []string) ([]*ethtypes.EthTraceReplayBlockTransaction, error) //perm:read diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index 3829a7f34b1b207b6cf943dc9b09c4c39a0a9283..ee4eef2573f26573e7343586ea4c67260f8786c9 100644 GIT binary patch literal 35372 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%0A9j8)mkx4fndRycgh*ymcSqADyz2%E@-9qAK;> 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 diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index 6571430bcc4533d2bb8a5cb8cbf0525c1047254f..778a6c010b8e9e41c8e9e66f403390b113dfdad3 100644 GIT binary patch delta 11725 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 a=3(z0?jrtS`cK>b_+aqKv{8(Og7`0Z7Sr+o delta 11736 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 0 { + switch r := env.traces[0].Result.(type) { + case *ethtypes.EthCallTraceResult: + output = r.Output + case *ethtypes.EthCreateTraceResult: + output = r.Code } - } else { - output = encodeFilecoinReturnAsABI(ir.ExecutionTrace.MsgRct.ExitCode, ir.ExecutionTrace.MsgRct.ReturnCodec, ir.ExecutionTrace.MsgRct.Return) } - t := ethtypes.EthTraceReplayBlockTransaction{ + allTraces = append(allTraces, ðtypes.EthTraceReplayBlockTransaction{ Output: output, TransactionHash: *txHash, + Trace: env.traces, StateDiff: nil, VmTrace: nil, - } - - err = buildTraces(&t.Trace, nil, []int{}, ir.ExecutionTrace, int64(ts.Height()), st) - if err != nil { - return nil, xerrors.Errorf("failed building traces: %w", err) - } - - allTraces = append(allTraces, &t) + }) } return allTraces, nil diff --git a/node/impl/full/eth_test.go b/node/impl/full/eth_test.go index c364a4873c4..05c3f257504 100644 --- a/node/impl/full/eth_test.go +++ b/node/impl/full/eth_test.go @@ -1,11 +1,14 @@ package full import ( + "bytes" "encoding/hex" "testing" "github.com/ipfs/go-cid" + "github.com/multiformats/go-multicodec" "github.com/stretchr/testify/require" + cbg "github.com/whyrusleeping/cbor-gen" "github.com/filecoin-project/go-state-types/big" @@ -177,3 +180,40 @@ func TestABIEncoding(t *testing.T) { require.Equal(t, expectedBytes, encodeAsABIHelper(22, 81, dataBytes)) } + +func TestDecodePayload(t *testing.T) { + // "empty" + b, err := decodePayload(nil, 0) + require.NoError(t, err) + require.Empty(t, b) + + // raw empty + _, err = decodePayload(nil, uint64(multicodec.Raw)) + require.NoError(t, err) + require.Empty(t, b) + + // raw non-empty + b, err = decodePayload([]byte{1}, uint64(multicodec.Raw)) + require.NoError(t, err) + require.EqualValues(t, b, []byte{1}) + + // Invalid cbor bytes + _, err = decodePayload(nil, uint64(multicodec.DagCbor)) + require.Error(t, err) + + // valid cbor bytes + var w bytes.Buffer + require.NoError(t, cbg.WriteByteArray(&w, []byte{1})) + b, err = decodePayload(w.Bytes(), uint64(multicodec.DagCbor)) + require.NoError(t, err) + require.EqualValues(t, b, []byte{1}) + + // regular cbor also works. + b, err = decodePayload(w.Bytes(), uint64(multicodec.Cbor)) + require.NoError(t, err) + require.EqualValues(t, b, []byte{1}) + + // random codec should fail + _, err = decodePayload(w.Bytes(), 42) + require.Error(t, err) +} diff --git a/node/impl/full/eth_trace.go b/node/impl/full/eth_trace.go index 123d96fe103..e4e5d794d0e 100644 --- a/node/impl/full/eth_trace.go +++ b/node/impl/full/eth_trace.go @@ -2,15 +2,22 @@ package full import ( "bytes" + "fmt" "github.com/multiformats/go-multicodec" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/builtin" - "github.com/filecoin-project/go-state-types/builtin/v10/evm" + eam12 "github.com/filecoin-project/go-state-types/builtin/v12/eam" + evm12 "github.com/filecoin-project/go-state-types/builtin/v12/evm" + init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" + "github.com/filecoin-project/go-state-types/exitcode" builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/actors/builtin/evm" "github.com/filecoin-project/lotus/chain/state" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/ethtypes" @@ -18,10 +25,6 @@ import ( // decodePayload is a utility function which decodes the payload using the given codec func decodePayload(payload []byte, codec uint64) (ethtypes.EthBytes, error) { - if len(payload) == 0 { - return nil, nil - } - switch multicodec.Code(codec) { case multicodec.Identity: return nil, nil @@ -38,217 +41,565 @@ func decodePayload(payload []byte, codec uint64) (ethtypes.EthBytes, error) { return nil, xerrors.Errorf("decodePayload: unsupported codec: %d", codec) } -// buildTraces recursively builds the traces for a given ExecutionTrace by walking the subcalls -func buildTraces(traces *[]*ethtypes.EthTrace, parent *ethtypes.EthTrace, addr []int, et types.ExecutionTrace, height int64, st *state.StateTree) error { - // lookup the eth address from the from/to addresses. Note that this may fail but to support - // this we need to include the ActorID in the trace. For now, just log a warning and skip - // this trace. - // - // TODO: Add ActorID in trace, see https://github.com/filecoin-project/lotus/pull/11100#discussion_r1302442288 - from, err := lookupEthAddress(et.Msg.From, st) +func decodeParams[P any, T interface { + *P + cbg.CBORUnmarshaler +}](msg *types.MessageTrace) (T, error) { + var params T = new(P) + switch msg.ParamsCodec { + case uint64(multicodec.DagCbor), uint64(multicodec.Cbor): + default: + return nil, xerrors.Errorf("Method called with unexpected codec %d", msg.ParamsCodec) + } + + if err := params.UnmarshalCBOR(bytes.NewReader(msg.Params)); err != nil { + return nil, xerrors.Errorf("failed to decode params: %w", err) + } + + return params, nil +} + +func decodeReturn[R any, T interface { + *R + cbg.CBORUnmarshaler +}](ret *types.ReturnTrace) (T, error) { + var retval T = new(R) + switch ret.ReturnCodec { + case uint64(multicodec.DagCbor), uint64(multicodec.Cbor): + default: + return nil, xerrors.Errorf("Method returned an unexpected codec %d", ret.ReturnCodec) + } + + if err := retval.UnmarshalCBOR(bytes.NewReader(ret.Return)); err != nil { + return nil, xerrors.Errorf("failed to decode return value: %w", err) + } + + return retval, nil +} + +func find[T any](values []T, cb func(t *T) *T) *T { + for i := range values { + if o := cb(&values[i]); o != nil { + return o + } + } + return nil +} + +type environment struct { + caller ethtypes.EthAddress + isEVM bool + subtraceCount int + traces []*ethtypes.EthTrace + lastByteCode *ethtypes.EthAddress +} + +func baseEnvironment(st *state.StateTree, from address.Address) (*environment, error) { + sender, err := lookupEthAddress(from, st) if err != nil { - log.Warnf("buildTraces: failed to lookup from address %s: %v", et.Msg.From, err) - return nil + return nil, xerrors.Errorf("top-level message sender %s s could not be found: %w", from, err) + } + return &environment{caller: sender}, nil +} + +func traceToAddress(act *types.ActorTrace) ethtypes.EthAddress { + if act.State.Address != nil { + if addr, err := ethtypes.EthAddressFromFilecoinAddress(*act.State.Address); err == nil { + return addr + } + } + return ethtypes.EthAddressFromActorID(act.Id) +} + +// traceIsEVMOrEAM returns true if the trace is a call to an EVM or EAM actor. +func traceIsEVMOrEAM(et *types.ExecutionTrace) bool { + if et.InvokedActor == nil { + return false + } + return builtinactors.IsEvmActor(et.InvokedActor.State.Code) || + et.InvokedActor.Id != abi.ActorID(builtin.EthereumAddressManagerActorID) +} + +func traceErrMsg(et *types.ExecutionTrace) string { + code := et.MsgRct.ExitCode + + if code.IsSuccess() { + return "" + } + + // EVM tools often expect this literal string. + if code == exitcode.SysErrOutOfGas { + return "out of gas" + } + + // indicate when we have a "system" error. + if code < exitcode.FirstActorErrorCode { + return fmt.Sprintf("vm error: %s", code) } - to, err := lookupEthAddress(et.Msg.To, st) + + // handle special exit codes from the EVM/EAM. + if traceIsEVMOrEAM(et) { + switch code { + case evm.ErrReverted: + return "Reverted" // capitalized for compatibility + case evm.ErrInvalidInstruction: + return "invalid instruction" + case evm.ErrUndefinedInstruction: + return "undefined instruction" + case evm.ErrStackUnderflow: + return "stack underflow" + case evm.ErrStackOverflow: + return "stack overflow" + case evm.ErrIllegalMemoryAccess: + return "illegal memory access" + case evm.ErrBadJumpdest: + return "invalid jump destination" + case evm.ErrSelfdestructFailed: + return "self destruct failed" + } + } + // everything else... + return fmt.Sprintf("actor error: %s", code.Error()) +} + +// buildTraces recursively builds the traces for a given ExecutionTrace by walking the subcalls +func buildTraces(env *environment, addr []int, et *types.ExecutionTrace) error { + trace, recurseInto, err := buildTrace(env, addr, et) if err != nil { - log.Warnf("buildTraces: failed to lookup to address %s: %w", et.Msg.To, err) + return xerrors.Errorf("at trace %v: %w", addr, err) + } + + if trace != nil { + env.traces = append(env.traces, trace) + env.subtraceCount++ + } + + // Skip if there's nothing more to do and/or `buildTrace` told us to skip this one. + if recurseInto == nil || recurseInto.InvokedActor == nil || len(recurseInto.Subcalls) == 0 { return nil } - // Skip the trace if we never reached the point where we invoked this actor. + subEnv := &environment{ + caller: traceToAddress(recurseInto.InvokedActor), + isEVM: builtinactors.IsEvmActor(recurseInto.InvokedActor.State.Code), + traces: env.traces, + } + // Set capacity to the length so each `append` below creates a new slice. Otherwise, we'll + // end up repeatedly mutating previous paths. + addr = addr[:len(addr):len(addr)] + for i := range recurseInto.Subcalls { + err := buildTraces(subEnv, append(addr, subEnv.subtraceCount), &recurseInto.Subcalls[i]) + if err != nil { + return err + } + } + trace.Subtraces = subEnv.subtraceCount + env.traces = subEnv.traces + + return nil +} + +// buildTrace processes the passed execution trace and updates the environment, if necessary. +// +// On success, it returns a trace to add (or nil to skip) and the trace recurse into (or nil to skip). +func buildTrace(env *environment, addr []int, et *types.ExecutionTrace) (*ethtypes.EthTrace, *types.ExecutionTrace, error) { + // This function first assumes that the call is a "native" call, then handles all the "not + // native" cases. If we get any unexpected results in any of these special cases, we just + // keep the "native" interpretation and move on. + // + // 1. If we're invoking a contract (even if the caller is a native account/actor), we + // attempt to decode the params/return value as a contract invocation. + // 2. If we're calling the EAM and/or init actor, we try to treat the call as a CREATE. + // 3. Finally, if the caller is an EVM smart contract and it's calling a "private" (1-1023) + // method, we know something special is going on. We look for calls related to + // DELEGATECALL and drop everything else (everything else includes calls triggered by, + // e.g., EXTCODEHASH). + + // If we don't have sufficient funds, or we have a fatal error, or we have some + // other syscall error: skip the entire trace to mimic Ethereum (Ethereum records + // traces _after_ checking things like this). + // + // NOTE: The FFI currently folds all unknown syscall errors into "sys assertion + // failed" which is turned into SysErrFatal. + if len(addr) > 0 { + switch et.MsgRct.ExitCode { + case exitcode.SysErrInsufficientFunds, exitcode.SysErrFatal: + return nil, nil, nil + } + } + + // We may fail before we can even invoke the actor. In that case, we have no 100% reliable + // way of getting its address (e.g., due to reverts) so we're just going to drop the entire + // trace. This is OK (ish) because the call never really "happened". if et.InvokedActor == nil { - return nil + return nil, nil, nil } - trace := ðtypes.EthTrace{ - Action: ethtypes.EthTraceAction{ - From: from, - To: to, - Gas: ethtypes.EthUint64(et.Msg.GasLimit), - Input: nil, - Value: ethtypes.EthBigInt(et.Msg.Value), + // Step 2: Decode as a contract invocation + // + // Normal EVM calls. We don't care if the caller/receiver are actually EVM actors, we only + // care if the call _looks_ like an EVM call. If we fail to decode it as an EVM call, we + // fallback on interpreting it as a native call. + if et.Msg.Method == builtin.MethodsEVM.InvokeContract { + return traceEVMCall(env, addr, et) + } + + // Step 3: Decode as a contract deployment + switch et.Msg.To { + // NOTE: this will only catch _direct_ calls to the init actor. Calls through the EAM will + // be caught and _skipped_ below in the next case. + case builtin.InitActorAddr: + switch et.Msg.Method { + case builtin.MethodsInit.Exec, builtin.MethodsInit.Exec4: + return traceNativeCreate(env, addr, et) + } + case builtin.EthereumAddressManagerActorAddr: + switch et.Msg.Method { + case builtin.MethodsEAM.Create, builtin.MethodsEAM.Create2, builtin.MethodsEAM.CreateExternal: + return traceEthCreate(env, addr, et) + } + } + + // Step 4: Handle DELEGATECALL + // + // EVM contracts cannot call methods in the range 1-1023, only the EVM itself can. So, if we + // see a call in this range, we know it's an implementation detail of the EVM and not an + // explicit call by the user. + // + // While the EVM calls several methods in this range (some we've already handled above with + // respect to the EAM), we only care about the ones relevant DELEGATECALL and can _ignore_ + // all the others. + if env.isEVM && et.Msg.Method > 0 && et.Msg.Method < 1024 { + return traceEVMPrivate(env, addr, et) + } - FilecoinFrom: et.Msg.From, - FilecoinTo: et.Msg.To, - FilecoinMethod: et.Msg.Method, - FilecoinCodeCid: et.InvokedActor.State.Code, + return traceNativeCall(env, addr, et), et, nil +} + +// Build an EthTrace for a "call" with the given input & output. +func traceCall(env *environment, addr []int, et *types.ExecutionTrace, input, output ethtypes.EthBytes) *ethtypes.EthTrace { + to := traceToAddress(et.InvokedActor) + callType := "call" + if et.Msg.ReadOnly { + callType = "staticcall" + } + return ðtypes.EthTrace{ + Type: "call", + Action: ðtypes.EthCallTraceAction{ + CallType: callType, + From: env.caller, + To: to, + Gas: ethtypes.EthUint64(et.Msg.GasLimit), + Value: ethtypes.EthBigInt(et.Msg.Value), + Input: input, }, - Result: ethtypes.EthTraceResult{ + Result: ðtypes.EthCallTraceResult{ GasUsed: ethtypes.EthUint64(et.SumGas().TotalGas), - Output: nil, + Output: output, }, - Subtraces: 0, // will be updated by the children once they are added to the trace TraceAddress: addr, + Error: traceErrMsg(et), + } +} - Parent: parent, - LastByteCode: nil, +// Build an EthTrace for a "call", parsing the inputs & outputs as a "native" FVM call. +func traceNativeCall(env *environment, addr []int, et *types.ExecutionTrace) *ethtypes.EthTrace { + return traceCall(env, addr, et, + encodeFilecoinParamsAsABI(et.Msg.Method, et.Msg.ParamsCodec, et.Msg.Params), + encodeFilecoinReturnAsABI(et.MsgRct.ExitCode, et.MsgRct.ReturnCodec, et.MsgRct.Return), + ) +} + +// Build an EthTrace for a "call", parsing the inputs & outputs as an EVM call (falling back on +// treating it as a native call). +func traceEVMCall(env *environment, addr []int, et *types.ExecutionTrace) (*ethtypes.EthTrace, *types.ExecutionTrace, error) { + input, err := decodePayload(et.Msg.Params, et.Msg.ParamsCodec) + if err != nil { + log.Debugf("failed to decode contract invocation payload: %w", err) + return traceNativeCall(env, addr, et), et, nil } + output, err := decodePayload(et.MsgRct.Return, et.MsgRct.ReturnCodec) + if err != nil { + log.Debugf("failed to decode contract invocation return: %w", err) + return traceNativeCall(env, addr, et), et, nil + } + return traceCall(env, addr, et, input, output), et, nil +} - trace.SetCallType("call") +// Build an EthTrace for a native "create" operation. This should only be called with an +// ExecutionTrace is an Exec or Exec4 method invocation on the Init actor. +func traceNativeCreate(env *environment, addr []int, et *types.ExecutionTrace) (*ethtypes.EthTrace, *types.ExecutionTrace, error) { + if et.Msg.ReadOnly { + // "create" isn't valid in a staticcall, so we just skip this trace + // (couldn't have created an actor anyways). + // This mimic's the EVM: it doesn't trace CREATE calls when in + // read-only mode. + return nil, nil, nil + } - if et.Msg.Method == builtin.MethodsEVM.InvokeContract { - log.Debugf("COND1 found InvokeContract call at height: %d", height) + subTrace := find(et.Subcalls, func(c *types.ExecutionTrace) *types.ExecutionTrace { + if c.Msg.Method == builtin.MethodConstructor { + return c + } + return nil + }) + if subTrace == nil { + // If we succeed in calling Exec/Exec4 but don't even try to construct + // something, we have a bug in our tracing logic or a mismatch between our + // tracing logic and the actors. + if et.MsgRct.ExitCode.IsSuccess() { + return nil, nil, xerrors.Errorf("successful Exec/Exec4 call failed to call a constructor") + } + // Otherwise, this can happen if creation fails early (bad params, + // out of gas, contract already exists, etc.). The EVM wouldn't + // trace such cases, so we don't either. + // + // NOTE: It's actually impossible to run out of gas before calling + // initcode in the EVM (without running out of gas in the calling + // contract), but this is an equivalent edge-case to InvokedActor + // being nil, so we treat it the same way and skip the entire + // operation. + return nil, nil, nil + } - // TODO: ignore return errors since actors can send gibberish and we don't want - // to fail the whole trace in that case - trace.Action.Input, err = decodePayload(et.Msg.Params, et.Msg.ParamsCodec) + // Native actors that aren't the EAM can attempt to call Exec4, but such + // call should fail immediately without ever attempting to construct an + // actor. I'm catching this here because it likely means that there's a bug + // in our trace-conversion logic. + if et.Msg.Method == builtin.MethodsInit.Exec4 { + return nil, nil, xerrors.Errorf("direct call to Exec4 successfully called a constructor!") + } + + var output ethtypes.EthBytes + var createdAddr *ethtypes.EthAddress + if et.MsgRct.ExitCode.IsSuccess() { + // We're supposed to put the "installed bytecode" here. But this + // isn't an EVM actor, so we just put some invalid bytecode (this is + // the answer you'd get if you called EXTCODECOPY on a native + // non-account actor, anyways). + output = []byte{0xFE} + + // Extract the address of the created actor from the return value. + initReturn, err := decodeReturn[init12.ExecReturn](&et.MsgRct) if err != nil { - return xerrors.Errorf("buildTraces: %w", err) + return nil, nil, xerrors.Errorf("failed to decode init params after a successful Init.Exec call: %w", err) } - trace.Result.Output, err = decodePayload(et.MsgRct.Return, et.MsgRct.ReturnCodec) + actorId, err := address.IDFromAddress(initReturn.IDAddress) if err != nil { - return xerrors.Errorf("buildTraces: %w", err) + return nil, nil, xerrors.Errorf("failed to extract created actor ID from address: %w", err) } - } else if et.Msg.To == builtin.EthereumAddressManagerActorAddr && - et.Msg.Method == builtin.MethodsEAM.CreateExternal { - log.Debugf("COND2 found CreateExternal call at height: %d", height) - trace.Action.Input, err = decodePayload(et.Msg.Params, et.Msg.ParamsCodec) + ethAddr := ethtypes.EthAddressFromActorID(abi.ActorID(actorId)) + createdAddr = ðAddr + } + + return ðtypes.EthTrace{ + Type: "create", + Action: ðtypes.EthCreateTraceAction{ + From: env.caller, + Gas: ethtypes.EthUint64(et.Msg.GasLimit), + Value: ethtypes.EthBigInt(et.Msg.Value), + // If we get here, this isn't a native EVM create. Those always go through + // the EAM. So we have no "real" initcode and must use the sentinel value + // for "invalid" initcode. + Init: []byte{0xFE}, + }, + Result: ðtypes.EthCreateTraceResult{ + GasUsed: ethtypes.EthUint64(et.SumGas().TotalGas), + Address: createdAddr, + Code: output, + }, + TraceAddress: addr, + Error: traceErrMsg(et), + }, subTrace, nil +} + +// Assert that these are all identical so we can simplify the below code and decode once. +var _ *eam12.Return = (*eam12.Return)((*eam12.CreateReturn)(nil)) +var _ *eam12.Return = (*eam12.Return)((*eam12.Create2Return)(nil)) +var _ *eam12.Return = (*eam12.Return)((*eam12.CreateExternalReturn)(nil)) + +// Decode the parameters and return value of an EVM smart contract creation through the EAM. This +// should only be called with an ExecutionTrace for a Create, Create2, or CreateExternal method +// invocation on the EAM. +func decodeCreateViaEAM(et *types.ExecutionTrace) (initcode []byte, addr *ethtypes.EthAddress, err error) { + switch et.Msg.Method { + case builtin.MethodsEAM.Create: + params, err := decodeParams[eam12.CreateParams](&et.Msg) if err != nil { - return xerrors.Errorf("buildTraces: %w", err) + return nil, nil, err } - - if et.MsgRct.ExitCode.IsSuccess() { - // ignore return value - trace.Result.Output = nil - } else { - // return value is the error message - trace.Result.Output, err = decodePayload(et.MsgRct.Return, et.MsgRct.ReturnCodec) - if err != nil { - return xerrors.Errorf("buildTraces: %w", err) - } + initcode = params.Initcode + case builtin.MethodsEAM.Create2: + params, err := decodeParams[eam12.Create2Params](&et.Msg) + if err != nil { + return nil, nil, err } - - // treat this as a contract creation - trace.SetCallType("create") - } else { - // we are going to assume a native method, but we may change it in one of the edge cases below - // TODO: only do this if we know it's a native method (optimization) - trace.Action.Input = encodeFilecoinParamsAsABI(et.Msg.Method, et.Msg.ParamsCodec, et.Msg.Params) - trace.Result.Output = encodeFilecoinReturnAsABI(et.MsgRct.ExitCode, et.MsgRct.ReturnCodec, et.MsgRct.Return) + initcode = params.Initcode + case builtin.MethodsEAM.CreateExternal: + input, err := decodePayload(et.Msg.Params, et.Msg.ParamsCodec) + if err != nil { + return nil, nil, err + } + initcode = input + default: + return nil, nil, xerrors.Errorf("unexpected CREATE method %d", et.Msg.Method) + } + ret, err := decodeReturn[eam12.CreateReturn](&et.MsgRct) + if err != nil { + return nil, (*ethtypes.EthAddress)(&ret.EthAddress), err } + return initcode, (*ethtypes.EthAddress)(&ret.EthAddress), nil +} - // TODO: is it OK to check this here or is this only specific to certain edge case (evm to evm)? +// Build an EthTrace for an EVM "create" operation. This should only be called with an +// ExecutionTrace for a Create, Create2, or CreateExternal method invocation on the EAM. +func traceEthCreate(env *environment, addr []int, et *types.ExecutionTrace) (*ethtypes.EthTrace, *types.ExecutionTrace, error) { + // Same as the Init actor case above, see the comment there. if et.Msg.ReadOnly { - trace.SetCallType("staticcall") + return nil, nil, nil } - // there are several edge cases that require special handling when displaying the traces. Note that while iterating over - // the traces we update the trace backwards (through the parent pointer) - if parent != nil { - // Handle Native actor creation - // - // Actor A calls to the init actor on method 2 and The init actor creates the target actor B then calls it on method 1 - if parent.Action.FilecoinTo == builtin.InitActorAddr && - parent.Action.FilecoinMethod == builtin.MethodsInit.Exec && - et.Msg.Method == builtin.MethodConstructor { - log.Debugf("COND3 Native actor creation! method:%d, code:%s, height:%d", et.Msg.Method, et.InvokedActor.State.Code.String(), height) - parent.SetCallType("create") - parent.Action.To = to - parent.Action.Input = []byte{0xFE} - parent.Result.Output = nil - - // there should never be any subcalls when creating a native actor - // - // TODO: add support for native actors calling another when created - return nil - } - - // Handle EVM contract creation - // - // To detect EVM contract creation we need to check for the following sequence of events: - // - // 1) EVM contract A calls the EAM (Ethereum Address Manager) on method 2 (create) or 3 (create2). - // 2) The EAM calls the init actor on method 3 (Exec4). - // 3) The init actor creates the target actor B then calls it on method 1. - if parent.Parent != nil { - calledCreateOnEAM := parent.Parent.Action.FilecoinTo == builtin.EthereumAddressManagerActorAddr && - (parent.Parent.Action.FilecoinMethod == builtin.MethodsEAM.Create || parent.Parent.Action.FilecoinMethod == builtin.MethodsEAM.Create2) - eamCalledInitOnExec4 := parent.Action.FilecoinTo == builtin.InitActorAddr && - parent.Action.FilecoinMethod == builtin.MethodsInit.Exec4 - initCreatedActor := trace.Action.FilecoinMethod == builtin.MethodConstructor - - // TODO: We need to handle failures in contract creations and support resurrections on an existing but dead EVM actor) - if calledCreateOnEAM && eamCalledInitOnExec4 && initCreatedActor { - log.Debugf("COND4 EVM contract creation method:%d, code:%s, height:%d", et.Msg.Method, et.InvokedActor.State.Code.String(), height) - - if parent.Parent.Action.FilecoinMethod == builtin.MethodsEAM.Create { - parent.Parent.SetCallType("create") - } else { - parent.Parent.SetCallType("create2") + // Look for a call to either a constructor or the EVM's resurrect method. + subTrace := find(et.Subcalls, func(et *types.ExecutionTrace) *types.ExecutionTrace { + if et.Msg.To == builtinactors.InitActorAddr { + return find(et.Subcalls, func(et *types.ExecutionTrace) *types.ExecutionTrace { + if et.Msg.Method == builtinactors.MethodConstructor { + return et } - - // update the parent.parent to make this - parent.Parent.Action.To = trace.Action.To - parent.Parent.Subtraces = 0 - - // delete the parent (the EAM) and skip the current trace (init) - *traces = (*traces)[:len(*traces)-1] - return nil - } - } - - if builtinactors.IsEvmActor(parent.Action.FilecoinCodeCid) { - // Handle delegate calls - // - // 1) Look for trace from an EVM actor to itself on InvokeContractDelegate, method 6. - // 2) Check that the previous trace calls another actor on method 3 (GetByteCode) and they are at the same level (same parent) - // 3) Treat this as a delegate call to actor A. - if parent.LastByteCode != nil && trace.Action.From == trace.Action.To && - trace.Action.FilecoinMethod == builtin.MethodsEVM.InvokeContractDelegate { - log.Debugf("COND7 found delegate call, height: %d", height) - prev := parent.LastByteCode - if prev.Action.From == trace.Action.From && prev.Action.FilecoinMethod == builtin.MethodsEVM.GetBytecode && prev.Parent == trace.Parent { - trace.SetCallType("delegatecall") - trace.Action.To = prev.Action.To - - var dp evm.DelegateCallParams - err := dp.UnmarshalCBOR(bytes.NewReader(et.Msg.Params)) - if err != nil { - return xerrors.Errorf("failed UnmarshalCBOR: %w", err) - } - trace.Action.Input = dp.Input - - trace.Result.Output, err = decodePayload(et.MsgRct.Return, et.MsgRct.ReturnCodec) - if err != nil { - return xerrors.Errorf("failed decodePayload: %w", err) - } - } - } else { - // Handle EVM call special casing - // - // Any outbound call from an EVM actor on methods 1-1023 are side-effects from EVM instructions - // and should be dropped from the trace. - if et.Msg.Method > 0 && - et.Msg.Method <= 1023 { - log.Debugf("Infof found outbound call from an EVM actor on method 1-1023 method:%d, code:%s, height:%d", et.Msg.Method, parent.Action.FilecoinCodeCid.String(), height) - - if et.Msg.Method == builtin.MethodsEVM.GetBytecode { - // save the last bytecode trace to handle delegate calls - parent.LastByteCode = trace - } - - return nil - } - } + }) + } + if et.Msg.Method == builtin.MethodsEVM.Resurrect { + return et } + return nil + }) + // Same as the Init actor case above, see the comment there. + if subTrace == nil { + if et.MsgRct.ExitCode.IsSuccess() { + return nil, nil, xerrors.Errorf("successful Create/Create2 call failed to call a constructor") + } + return nil, nil, nil } - // we are adding trace to the traces so update the parent subtraces count as it was originally set to zero - if parent != nil { - parent.Subtraces++ + // Decode inputs & determine create type. + initcode, createdAddr, err := decodeCreateViaEAM(et) + if err != nil { + return nil, nil, xerrors.Errorf("EAM called with invalid params or returned an invalid result, but it still tried to construct the contract: %w", err) + } + + var output ethtypes.EthBytes + // Handle the output. + switch et.MsgRct.ExitCode { + case 0: // success + // We're _supposed_ to include the contracts bytecode here, but we + // can't do that reliably (e.g., if some part of the trace reverts). + // So we don't try and include a sentinel "impossible bytecode" + // value (the value specified by EIP-3541). + output = []byte{0xFE} + case 33: // Reverted, parse the revert message. + // If we managed to call the constructor, parse/return its revert message. If we + // fail, we just return no output. + output, _ = decodePayload(subTrace.MsgRct.Return, subTrace.MsgRct.ReturnCodec) } - *traces = append(*traces, trace) + return ðtypes.EthTrace{ + Type: "create", + Action: ðtypes.EthCreateTraceAction{ + From: env.caller, + Gas: ethtypes.EthUint64(et.Msg.GasLimit), + Value: ethtypes.EthBigInt(et.Msg.Value), + Init: initcode, + }, + Result: ðtypes.EthCreateTraceResult{ + GasUsed: ethtypes.EthUint64(et.SumGas().TotalGas), + Address: createdAddr, + Code: output, + }, + TraceAddress: addr, + Error: traceErrMsg(et), + }, subTrace, nil +} - for i, call := range et.Subcalls { - err := buildTraces(traces, trace, append(addr, i), call, height, st) +// Build an EthTrace for a "private" method invocation from the EVM. This should only be called with +// an ExecutionTrace from an EVM instance and on a method between 1 and 1023 inclusive. +func traceEVMPrivate(env *environment, addr []int, et *types.ExecutionTrace) (*ethtypes.EthTrace, *types.ExecutionTrace, error) { + // The EVM actor implements DELEGATECALL by: + // + // 1. Asking the callee for its bytecode by calling it on the GetBytecode method. + // 2. Recursively invoking the currently executing contract on the + // InvokeContractDelegate method. + // + // The code below "reconstructs" that delegate call by: + // + // 1. Remembering the last contract on which we called GetBytecode. + // 2. Treating the contract invoked in step 1 as the DELEGATECALL receiver. + // + // Note, however: GetBytecode will be called, e.g., if the user invokes the + // EXTCODECOPY instruction. It's not an error to see multiple GetBytecode calls + // before we see an InvokeContractDelegate. + switch et.Msg.Method { + case builtin.MethodsEVM.GetBytecode: + // NOTE: I'm not checking anything about the receiver here. The EVM won't + // DELEGATECALL any non-EVM actor, but there's no need to encode that fact + // here in case we decide to loosen this up in the future. + if et.MsgRct.ExitCode.IsSuccess() { + to := traceToAddress(et.InvokedActor) + env.lastByteCode = &to + } else { + env.lastByteCode = nil + } + return nil, nil, nil + case builtin.MethodsEVM.InvokeContractDelegate: + // NOTE: We return errors in all the failure cases below instead of trying + // to continue because the caller is an EVM actor. If something goes wrong + // here, there's a bug in our EVM implementation. + + // Handle delegate calls + // + // 1) Look for trace from an EVM actor to itself on InvokeContractDelegate, + // method 6. + // 2) Check that the previous trace calls another actor on method 3 + // (GetByteCode) and they are at the same level (same parent) + // 3) Treat this as a delegate call to actor A. + if env.lastByteCode == nil { + return nil, nil, xerrors.Errorf("unknown bytecode for delegate call") + } + + if to := traceToAddress(et.InvokedActor); env.caller != to { + return nil, nil, xerrors.Errorf("delegate-call not from & to self: %s != %s", env.caller, to) + } + + dp, err := decodeParams[evm12.DelegateCallParams](&et.Msg) if err != nil { - return err + return nil, nil, xerrors.Errorf("failed to decode delegate-call params: %w", err) } - } - return nil + output, err := decodePayload(et.MsgRct.Return, et.MsgRct.ReturnCodec) + if err != nil { + return nil, nil, xerrors.Errorf("failed to decode delegate-call return: %w", err) + } + + return ðtypes.EthTrace{ + Type: "call", + Action: ðtypes.EthCallTraceAction{ + CallType: "delegatecall", + From: env.caller, + To: *env.lastByteCode, + Gas: ethtypes.EthUint64(et.Msg.GasLimit), + Value: ethtypes.EthBigInt(et.Msg.Value), + Input: dp.Input, + }, + Result: ðtypes.EthCallTraceResult{ + GasUsed: ethtypes.EthUint64(et.SumGas().TotalGas), + Output: output, + }, + TraceAddress: addr, + Error: traceErrMsg(et), + }, et, nil + } + // We drop all other "private" calls from FEVM. We _forbid_ explicit calls between 0 and + // 1024 (exclusive), so any calls in this range must be implementation details. + return nil, nil, nil } diff --git a/node/impl/full/eth_utils.go b/node/impl/full/eth_utils.go index 1e407a321de..04e8e497086 100644 --- a/node/impl/full/eth_utils.go +++ b/node/impl/full/eth_utils.go @@ -381,34 +381,35 @@ func parseEthRevert(ret []byte) string { // 3. Otherwise, we fall back to returning a masked ID Ethereum address. If the supplied address is an f0 address, we // use that ID to form the masked ID address. // 4. Otherwise, we fetch the actor's ID from the state tree and form the masked ID with it. +// +// If the actor doesn't exist in the state-tree but we have its ID, we use a masked ID address. It could have been deleted. func lookupEthAddress(addr address.Address, st *state.StateTree) (ethtypes.EthAddress, error) { - // BLOCK A: We are trying to get an actual Ethereum address from an f410 address. // Attempt to convert directly, if it's an f4 address. ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(addr) if err == nil && !ethAddr.IsMaskedID() { return ethAddr, nil } - // Lookup on the target actor and try to get an f410 address. - if actor, err := st.GetActor(addr); err != nil { + // Otherwise, resolve the ID addr. + idAddr, err := st.LookupID(addr) + if err != nil { return ethtypes.EthAddress{}, err - } else if actor.Address != nil { - if ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(*actor.Address); err == nil && !ethAddr.IsMaskedID() { - return ethAddr, nil - } } - // BLOCK B: We gave up on getting an actual Ethereum address and are falling back to a Masked ID address. - // Check if we already have an ID addr, and use it if possible. - if err == nil && ethAddr.IsMaskedID() { + // Lookup on the target actor and try to get an f410 address. + if actor, err := st.GetActor(idAddr); errors.Is(err, types.ErrActorNotFound) { + // Not found -> use a masked ID address + } else if err != nil { + // Any other error -> fail. + return ethtypes.EthAddress{}, err + } else if actor.Address == nil { + // No delegated address -> use masked ID address. + } else if ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(*actor.Address); err == nil && !ethAddr.IsMaskedID() { + // Conversable into an eth address, use it. return ethAddr, nil } - // Otherwise, resolve the ID addr. - idAddr, err := st.LookupID(addr) - if err != nil { - return ethtypes.EthAddress{}, err - } + // Otherwise, use the masked address. return ethtypes.EthAddressFromFilecoinAddress(idAddr) }