simplify by moving receipt constructor logic to API.
This commit is contained in:
parent
32385a97cd
commit
1ab39a40da
@ -17,13 +17,10 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
||||||
"github.com/filecoin-project/go-state-types/builtin/v10/eam"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -210,80 +207,6 @@ type EthTxReceipt struct {
|
|||||||
Logs []EthLog `json:"logs"`
|
Logs []EthLog `json:"logs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEthTxReceipt(tx EthTx, lookup *MsgLookup, replay *InvocResult, events []types.Event, addressResolver func(id abi.ActorID) (address.Address, bool, error)) (EthTxReceipt, error) {
|
|
||||||
receipt := EthTxReceipt{
|
|
||||||
TransactionHash: tx.Hash,
|
|
||||||
TransactionIndex: tx.TransactionIndex,
|
|
||||||
BlockHash: tx.BlockHash,
|
|
||||||
BlockNumber: tx.BlockNumber,
|
|
||||||
From: tx.From,
|
|
||||||
To: tx.To,
|
|
||||||
StateRoot: EmptyEthHash,
|
|
||||||
LogsBloom: []byte{0},
|
|
||||||
}
|
|
||||||
|
|
||||||
if receipt.To == nil && lookup.Receipt.ExitCode.IsSuccess() {
|
|
||||||
// Create and Create2 return the same things.
|
|
||||||
var ret eam.CreateReturn
|
|
||||||
if err := ret.UnmarshalCBOR(bytes.NewReader(lookup.Receipt.Return)); err != nil {
|
|
||||||
return EthTxReceipt{}, xerrors.Errorf("failed to parse contract creation result: %w", err)
|
|
||||||
}
|
|
||||||
addr := EthAddress(ret.EthAddress)
|
|
||||||
receipt.ContractAddress = &addr
|
|
||||||
}
|
|
||||||
|
|
||||||
if lookup.Receipt.ExitCode.IsSuccess() {
|
|
||||||
receipt.Status = 1
|
|
||||||
}
|
|
||||||
if lookup.Receipt.ExitCode.IsError() {
|
|
||||||
receipt.Status = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(events) > 0 {
|
|
||||||
receipt.Logs = make([]EthLog, 0, len(events))
|
|
||||||
for i, evt := range events {
|
|
||||||
l := EthLog{
|
|
||||||
Removed: false,
|
|
||||||
LogIndex: EthUint64(i),
|
|
||||||
TransactionIndex: tx.TransactionIndex,
|
|
||||||
TransactionHash: tx.Hash,
|
|
||||||
BlockHash: tx.BlockHash,
|
|
||||||
BlockNumber: tx.BlockNumber,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, entry := range evt.Entries {
|
|
||||||
hash := EthHashData(entry.Value)
|
|
||||||
if entry.Key == EthTopic1 || entry.Key == EthTopic2 || entry.Key == EthTopic3 || entry.Key == EthTopic4 {
|
|
||||||
l.Topics = append(l.Topics, hash)
|
|
||||||
} else {
|
|
||||||
l.Data = append(l.Data, hash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
f4addr, ok, err := addressResolver(evt.Emitter)
|
|
||||||
if err != nil || !ok {
|
|
||||||
return EthTxReceipt{}, xerrors.Errorf("failed to resolve predictable address: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
l.Address, err = EthAddressFromFilecoinAddress(f4addr)
|
|
||||||
if err != nil {
|
|
||||||
return EthTxReceipt{}, xerrors.Errorf("failed to translate to Ethereum address: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
receipt.Logs = append(receipt.Logs, l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
receipt.GasUsed = EthUint64(lookup.Receipt.GasUsed)
|
|
||||||
|
|
||||||
// TODO: handle CumulativeGasUsed
|
|
||||||
receipt.CumulativeGasUsed = EmptyEthInt
|
|
||||||
|
|
||||||
effectiveGasPrice := big.Div(replay.GasCost.TotalCost, big.NewInt(lookup.Receipt.GasUsed))
|
|
||||||
receipt.EffectiveGasPrice = EthBigInt(effectiveGasPrice)
|
|
||||||
return receipt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
EthAddressLength = 20
|
EthAddressLength = 20
|
||||||
EthHashLength = 32
|
EthHashLength = 32
|
||||||
|
@ -244,24 +244,11 @@ func (a *EthModule) EthGetTransactionReceipt(ctx context.Context, txHash api.Eth
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
receipt, err := api.NewEthTxReceipt(tx, msgLookup, replay, events, func(id abi.ActorID) (address.Address, bool, error) {
|
receipt, err := a.newEthTxReceipt(ctx, tx, msgLookup, replay, events)
|
||||||
addr, err := address.NewIDAddress(uint64(id))
|
|
||||||
if err != nil {
|
|
||||||
return address.Undef, false, xerrors.Errorf("failed to create ID address: %w", err)
|
|
||||||
}
|
|
||||||
actor, err := a.StateGetActor(ctx, addr, types.EmptyTSK)
|
|
||||||
if err != nil {
|
|
||||||
return address.Undef, false, xerrors.Errorf("failed to load actor: %w", err)
|
|
||||||
}
|
|
||||||
if actor.Address == nil {
|
|
||||||
return address.Undef, false, nil
|
|
||||||
}
|
|
||||||
return *actor.Address, true, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return &receipt, nil
|
return &receipt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -892,6 +879,81 @@ func (a *EthModule) newEthTxFromFilecoinMessageLookup(ctx context.Context, msgLo
|
|||||||
return tx, nil
|
return tx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *EthModule) newEthTxReceipt(ctx context.Context, tx api.EthTx, lookup *api.MsgLookup, replay *api.InvocResult, events []types.Event) (api.EthTxReceipt, error) {
|
||||||
|
receipt := api.EthTxReceipt{
|
||||||
|
TransactionHash: tx.Hash,
|
||||||
|
TransactionIndex: tx.TransactionIndex,
|
||||||
|
BlockHash: tx.BlockHash,
|
||||||
|
BlockNumber: tx.BlockNumber,
|
||||||
|
From: tx.From,
|
||||||
|
To: tx.To,
|
||||||
|
StateRoot: api.EmptyEthHash,
|
||||||
|
LogsBloom: []byte{0},
|
||||||
|
}
|
||||||
|
|
||||||
|
if receipt.To == nil && lookup.Receipt.ExitCode.IsSuccess() {
|
||||||
|
// Create and Create2 return the same things.
|
||||||
|
var ret eam.CreateReturn
|
||||||
|
if err := ret.UnmarshalCBOR(bytes.NewReader(lookup.Receipt.Return)); err != nil {
|
||||||
|
return api.EthTxReceipt{}, xerrors.Errorf("failed to parse contract creation result: %w", err)
|
||||||
|
}
|
||||||
|
addr := api.EthAddress(ret.EthAddress)
|
||||||
|
receipt.ContractAddress = &addr
|
||||||
|
}
|
||||||
|
|
||||||
|
if lookup.Receipt.ExitCode.IsSuccess() {
|
||||||
|
receipt.Status = 1
|
||||||
|
}
|
||||||
|
if lookup.Receipt.ExitCode.IsError() {
|
||||||
|
receipt.Status = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(events) > 0 {
|
||||||
|
receipt.Logs = make([]api.EthLog, 0, len(events))
|
||||||
|
for i, evt := range events {
|
||||||
|
l := api.EthLog{
|
||||||
|
Removed: false,
|
||||||
|
LogIndex: api.EthUint64(i),
|
||||||
|
TransactionIndex: tx.TransactionIndex,
|
||||||
|
TransactionHash: tx.Hash,
|
||||||
|
BlockHash: tx.BlockHash,
|
||||||
|
BlockNumber: tx.BlockNumber,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range evt.Entries {
|
||||||
|
hash := api.EthHashData(entry.Value)
|
||||||
|
if entry.Key == api.EthTopic1 || entry.Key == api.EthTopic2 || entry.Key == api.EthTopic3 || entry.Key == api.EthTopic4 {
|
||||||
|
l.Topics = append(l.Topics, hash)
|
||||||
|
} else {
|
||||||
|
l.Data = append(l.Data, hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addr, err := address.NewIDAddress(uint64(evt.Emitter))
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTxReceipt{}, xerrors.Errorf("failed to create ID address: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Address, err = a.lookupEthAddress(ctx, addr)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTxReceipt{}, xerrors.Errorf("failed to resolve Ethereum address: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
receipt.Logs = append(receipt.Logs, l)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
receipt.GasUsed = api.EthUint64(lookup.Receipt.GasUsed)
|
||||||
|
|
||||||
|
// TODO: handle CumulativeGasUsed
|
||||||
|
receipt.CumulativeGasUsed = api.EmptyEthInt
|
||||||
|
|
||||||
|
effectiveGasPrice := big.Div(replay.GasCost.TotalCost, big.NewInt(lookup.Receipt.GasUsed))
|
||||||
|
receipt.EffectiveGasPrice = api.EthBigInt(effectiveGasPrice)
|
||||||
|
|
||||||
|
return receipt, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (e *EthEvent) EthGetLogs(ctx context.Context, filterSpec *api.EthFilterSpec) (*api.EthFilterResult, error) {
|
func (e *EthEvent) EthGetLogs(ctx context.Context, filterSpec *api.EthFilterSpec) (*api.EthFilterResult, error) {
|
||||||
if e.EventFilterManager == nil {
|
if e.EventFilterManager == nil {
|
||||||
return nil, api.ErrNotSupported
|
return nil, api.ErrNotSupported
|
||||||
|
Loading…
Reference in New Issue
Block a user