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.
This commit is contained in:
+17
-16
@@ -382,34 +382,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 {
|
||||
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() {
|
||||
return ethAddr, nil
|
||||
}
|
||||
|
||||
// Otherwise, resolve the ID addr.
|
||||
idAddr, err := st.LookupID(addr)
|
||||
if err != nil {
|
||||
return ethtypes.EthAddress{}, err
|
||||
}
|
||||
|
||||
// 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, use the masked address.
|
||||
return ethtypes.EthAddressFromFilecoinAddress(idAddr)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user