Merge pull request #10055 from filecoin-project/gstuart/tx-hash-to-msg-cid
feat: API for EthGetMessageCidByTransactionHash
This commit is contained in:
commit
a7374a9019
@ -779,6 +779,7 @@ type FullNode interface {
|
|||||||
EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read
|
EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read
|
||||||
EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) //perm:read
|
EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) //perm:read
|
||||||
EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) //perm:read
|
EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) //perm:read
|
||||||
|
EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error) //perm:read
|
||||||
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) //perm:read
|
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) //perm:read
|
||||||
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error) //perm:read
|
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error) //perm:read
|
||||||
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read
|
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read
|
||||||
|
@ -1177,6 +1177,21 @@ func (mr *MockFullNodeMockRecorder) EthGetLogs(arg0, arg1 interface{}) *gomock.C
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetLogs", reflect.TypeOf((*MockFullNode)(nil).EthGetLogs), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetLogs", reflect.TypeOf((*MockFullNode)(nil).EthGetLogs), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EthGetMessageCidByTransactionHash mocks base method.
|
||||||
|
func (m *MockFullNode) EthGetMessageCidByTransactionHash(arg0 context.Context, arg1 *ethtypes.EthHash) (*cid.Cid, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "EthGetMessageCidByTransactionHash", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(*cid.Cid)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// EthGetMessageCidByTransactionHash indicates an expected call of EthGetMessageCidByTransactionHash.
|
||||||
|
func (mr *MockFullNodeMockRecorder) EthGetMessageCidByTransactionHash(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetMessageCidByTransactionHash", reflect.TypeOf((*MockFullNode)(nil).EthGetMessageCidByTransactionHash), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// EthGetStorageAt mocks base method.
|
// EthGetStorageAt mocks base method.
|
||||||
func (m *MockFullNode) EthGetStorageAt(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 ethtypes.EthBytes, arg3 string) (ethtypes.EthBytes, error) {
|
func (m *MockFullNode) EthGetStorageAt(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 ethtypes.EthBytes, arg3 string) (ethtypes.EthBytes, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
@ -253,6 +253,8 @@ type FullNodeStruct struct {
|
|||||||
|
|
||||||
EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) `perm:"read"`
|
EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) `perm:"read"`
|
||||||
|
|
||||||
|
EthGetMessageCidByTransactionHash func(p0 context.Context, p1 *ethtypes.EthHash) (*cid.Cid, error) `perm:"read"`
|
||||||
|
|
||||||
EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `perm:"read"`
|
EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `perm:"read"`
|
||||||
|
|
||||||
EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `perm:"read"`
|
EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `perm:"read"`
|
||||||
@ -2119,6 +2121,17 @@ func (s *FullNodeStub) EthGetLogs(p0 context.Context, p1 *ethtypes.EthFilterSpec
|
|||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStruct) EthGetMessageCidByTransactionHash(p0 context.Context, p1 *ethtypes.EthHash) (*cid.Cid, error) {
|
||||||
|
if s.Internal.EthGetMessageCidByTransactionHash == nil {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.EthGetMessageCidByTransactionHash(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStub) EthGetMessageCidByTransactionHash(p0 context.Context, p1 *ethtypes.EthHash) (*cid.Cid, error) {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) {
|
func (s *FullNodeStruct) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) {
|
||||||
if s.Internal.EthGetStorageAt == nil {
|
if s.Internal.EthGetStorageAt == nil {
|
||||||
return *new(ethtypes.EthBytes), ErrNotSupported
|
return *new(ethtypes.EthBytes), ErrNotSupported
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -83,6 +83,7 @@
|
|||||||
* [EthGetFilterChanges](#EthGetFilterChanges)
|
* [EthGetFilterChanges](#EthGetFilterChanges)
|
||||||
* [EthGetFilterLogs](#EthGetFilterLogs)
|
* [EthGetFilterLogs](#EthGetFilterLogs)
|
||||||
* [EthGetLogs](#EthGetLogs)
|
* [EthGetLogs](#EthGetLogs)
|
||||||
|
* [EthGetMessageCidByTransactionHash](#EthGetMessageCidByTransactionHash)
|
||||||
* [EthGetStorageAt](#EthGetStorageAt)
|
* [EthGetStorageAt](#EthGetStorageAt)
|
||||||
* [EthGetTransactionByBlockHashAndIndex](#EthGetTransactionByBlockHashAndIndex)
|
* [EthGetTransactionByBlockHashAndIndex](#EthGetTransactionByBlockHashAndIndex)
|
||||||
* [EthGetTransactionByBlockNumberAndIndex](#EthGetTransactionByBlockNumberAndIndex)
|
* [EthGetTransactionByBlockNumberAndIndex](#EthGetTransactionByBlockNumberAndIndex)
|
||||||
@ -2641,6 +2642,25 @@ Response:
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### EthGetMessageCidByTransactionHash
|
||||||
|
|
||||||
|
|
||||||
|
Perms: read
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### EthGetStorageAt
|
### EthGetStorageAt
|
||||||
|
|
||||||
|
|
||||||
|
@ -338,3 +338,261 @@ func TestTransactionHashLookupSecpFilecoinMessage(t *testing.T) {
|
|||||||
require.NotNil(t, chainTx.TransactionIndex)
|
require.NotNil(t, chainTx.TransactionIndex)
|
||||||
require.Equal(t, uint64(*chainTx.TransactionIndex), uint64(0)) // only transaction
|
require.Equal(t, uint64(*chainTx.TransactionIndex), uint64(0)) // only transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestTransactionHashLookupSecpFilecoinMessage tests to see if lotus can find a Secp Filecoin Message using the transaction hash
|
||||||
|
func TestTransactionHashLookupNonexistentMessage(t *testing.T) {
|
||||||
|
kit.QuietMiningLogs()
|
||||||
|
|
||||||
|
blocktime := 1 * time.Second
|
||||||
|
client, _, ens := kit.EnsembleMinimal(
|
||||||
|
t,
|
||||||
|
kit.MockProofs(),
|
||||||
|
kit.ThroughRPC(),
|
||||||
|
kit.EthTxHashLookup(),
|
||||||
|
)
|
||||||
|
ens.InterconnectAll().BeginMining(blocktime)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cid := build.MustParseCid("bafk2bzacecapjnxnyw4talwqv5ajbtbkzmzqiosztj5cb3sortyp73ndjl76e")
|
||||||
|
|
||||||
|
// We shouldn't be able to return a hash for this fake cid
|
||||||
|
chainHash, err := client.EthGetTransactionHashByCid(ctx, cid)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Nil(t, chainHash)
|
||||||
|
|
||||||
|
calculatedHash, err := ethtypes.EthHashFromCid(cid)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// We shouldn't be able to return a cid for this fake hash
|
||||||
|
chainCid, err := client.EthGetMessageCidByTransactionHash(ctx, &calculatedHash)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Nil(t, chainCid)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEthGetMessageCidByTransactionHashEthTx(t *testing.T) {
|
||||||
|
kit.QuietMiningLogs()
|
||||||
|
|
||||||
|
blocktime := 1 * time.Second
|
||||||
|
client, _, ens := kit.EnsembleMinimal(
|
||||||
|
t,
|
||||||
|
kit.MockProofs(),
|
||||||
|
kit.ThroughRPC(),
|
||||||
|
kit.EthTxHashLookup(),
|
||||||
|
)
|
||||||
|
ens.InterconnectAll().BeginMining(blocktime)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// install contract
|
||||||
|
contractHex, err := os.ReadFile("./contracts/SimpleCoin.hex")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
contract, err := hex.DecodeString(string(contractHex))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// create a new Ethereum account
|
||||||
|
key, ethAddr, deployer := client.EVM().NewAccount()
|
||||||
|
|
||||||
|
// send some funds to the f410 address
|
||||||
|
kit.SendFunds(ctx, t, client, deployer, types.FromFil(10))
|
||||||
|
|
||||||
|
gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{
|
||||||
|
From: ðAddr,
|
||||||
|
Data: contract,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// now deploy a contract from the embryo, and validate it went well
|
||||||
|
tx := ethtypes.EthTxArgs{
|
||||||
|
ChainID: build.Eip155ChainId,
|
||||||
|
Value: big.Zero(),
|
||||||
|
Nonce: 0,
|
||||||
|
MaxFeePerGas: types.NanoFil,
|
||||||
|
MaxPriorityFeePerGas: big.Int(maxPriorityFeePerGas),
|
||||||
|
GasLimit: int(gaslimit),
|
||||||
|
Input: contract,
|
||||||
|
V: big.Zero(),
|
||||||
|
R: big.Zero(),
|
||||||
|
S: big.Zero(),
|
||||||
|
}
|
||||||
|
|
||||||
|
client.EVM().SignTransaction(&tx, key.PrivateKey)
|
||||||
|
|
||||||
|
sender, err := tx.Sender()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
unsignedMessage, err := tx.ToUnsignedMessage(sender)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
rawTxHash, err := tx.TxHash()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
hash := client.EVM().SubmitTransaction(ctx, &tx)
|
||||||
|
require.Equal(t, rawTxHash, hash)
|
||||||
|
|
||||||
|
mpoolCid, err := client.EthGetMessageCidByTransactionHash(ctx, &hash)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, mpoolCid)
|
||||||
|
|
||||||
|
mpoolTx, err := client.ChainGetMessage(ctx, *mpoolCid)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, mpoolTx)
|
||||||
|
require.Equal(t, *unsignedMessage, *mpoolTx)
|
||||||
|
|
||||||
|
// Wait for message to land on chain
|
||||||
|
var receipt *api.EthTxReceipt
|
||||||
|
for i := 0; i < 20; i++ {
|
||||||
|
receipt, err = client.EthGetTransactionReceipt(ctx, hash)
|
||||||
|
if err != nil || receipt == nil {
|
||||||
|
time.Sleep(blocktime)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, receipt)
|
||||||
|
|
||||||
|
chainCid, err := client.EthGetMessageCidByTransactionHash(ctx, &hash)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, chainCid)
|
||||||
|
|
||||||
|
chainTx, err := client.ChainGetMessage(ctx, *mpoolCid)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, chainTx)
|
||||||
|
require.Equal(t, *unsignedMessage, *chainTx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEthGetMessageCidByTransactionHashSecp(t *testing.T) {
|
||||||
|
kit.QuietMiningLogs()
|
||||||
|
|
||||||
|
blocktime := 1 * time.Second
|
||||||
|
client, _, ens := kit.EnsembleMinimal(
|
||||||
|
t,
|
||||||
|
kit.MockProofs(),
|
||||||
|
kit.ThroughRPC(),
|
||||||
|
kit.EthTxHashLookup(),
|
||||||
|
)
|
||||||
|
ens.InterconnectAll().BeginMining(blocktime)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// get the existing balance from the default wallet to then split it.
|
||||||
|
bal, err := client.WalletBalance(ctx, client.DefaultKey.Address)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// create a new address where to send funds.
|
||||||
|
addr, err := client.WalletNew(ctx, types.KTSecp256k1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
toSend := big.Div(bal, big.NewInt(2))
|
||||||
|
setupMsg := &types.Message{
|
||||||
|
From: client.DefaultKey.Address,
|
||||||
|
To: addr,
|
||||||
|
Value: toSend,
|
||||||
|
}
|
||||||
|
|
||||||
|
setupSmsg, err := client.MpoolPushMessage(ctx, setupMsg, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
_, err = client.StateWaitMsg(ctx, setupSmsg.Cid(), 3, api.LookbackNoLimit, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Send message for secp account
|
||||||
|
secpMsg := &types.Message{
|
||||||
|
From: addr,
|
||||||
|
To: client.DefaultKey.Address,
|
||||||
|
Value: big.Div(toSend, big.NewInt(2)),
|
||||||
|
}
|
||||||
|
|
||||||
|
secpSmsg, err := client.MpoolPushMessage(ctx, secpMsg, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
hash, err := ethtypes.EthHashFromCid(secpSmsg.Cid())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mpoolCid, err := client.EthGetMessageCidByTransactionHash(ctx, &hash)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, mpoolCid)
|
||||||
|
|
||||||
|
mpoolTx, err := client.ChainGetMessage(ctx, *mpoolCid)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, mpoolTx)
|
||||||
|
require.Equal(t, secpSmsg.Message, *mpoolTx)
|
||||||
|
|
||||||
|
_, err = client.StateWaitMsg(ctx, secpSmsg.Cid(), 3, api.LookbackNoLimit, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
chainCid, err := client.EthGetMessageCidByTransactionHash(ctx, &hash)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, chainCid)
|
||||||
|
|
||||||
|
chainTx, err := client.ChainGetMessage(ctx, *mpoolCid)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, chainTx)
|
||||||
|
require.Equal(t, secpSmsg.Message, *chainTx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEthGetMessageCidByTransactionHashBLS(t *testing.T) {
|
||||||
|
kit.QuietMiningLogs()
|
||||||
|
|
||||||
|
blocktime := 1 * time.Second
|
||||||
|
client, _, ens := kit.EnsembleMinimal(
|
||||||
|
t,
|
||||||
|
kit.MockProofs(),
|
||||||
|
kit.ThroughRPC(),
|
||||||
|
kit.EthTxHashLookup(),
|
||||||
|
)
|
||||||
|
ens.InterconnectAll().BeginMining(blocktime)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// get the existing balance from the default wallet to then split it.
|
||||||
|
bal, err := client.WalletBalance(ctx, client.DefaultKey.Address)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// create a new address where to send funds.
|
||||||
|
addr, err := client.WalletNew(ctx, types.KTBLS)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
toSend := big.Div(bal, big.NewInt(2))
|
||||||
|
msg := &types.Message{
|
||||||
|
From: client.DefaultKey.Address,
|
||||||
|
To: addr,
|
||||||
|
Value: toSend,
|
||||||
|
}
|
||||||
|
|
||||||
|
sm, err := client.MpoolPushMessage(ctx, msg, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
hash, err := ethtypes.EthHashFromCid(sm.Cid())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mpoolCid, err := client.EthGetMessageCidByTransactionHash(ctx, &hash)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, mpoolCid)
|
||||||
|
|
||||||
|
mpoolTx, err := client.ChainGetMessage(ctx, *mpoolCid)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, mpoolTx)
|
||||||
|
require.Equal(t, sm.Message, *mpoolTx)
|
||||||
|
|
||||||
|
_, err = client.StateWaitMsg(ctx, sm.Cid(), 3, api.LookbackNoLimit, true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
chainCid, err := client.EthGetMessageCidByTransactionHash(ctx, &hash)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, chainCid)
|
||||||
|
|
||||||
|
chainTx, err := client.ChainGetMessage(ctx, *mpoolCid)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, chainTx)
|
||||||
|
require.Equal(t, sm.Message, *chainTx)
|
||||||
|
}
|
||||||
|
@ -109,6 +109,7 @@ func DefaultFullNode() *FullNode {
|
|||||||
},
|
},
|
||||||
Fevm: FevmConfig{
|
Fevm: FevmConfig{
|
||||||
EnableEthHashToFilecoinCidMapping: false,
|
EnableEthHashToFilecoinCidMapping: false,
|
||||||
|
EthTxHashMappingLifetimeDays: 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@ type EthModuleAPI interface {
|
|||||||
EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error)
|
EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error)
|
||||||
EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error)
|
EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error)
|
||||||
EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error)
|
EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error)
|
||||||
|
EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error)
|
||||||
EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error)
|
EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error)
|
||||||
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error)
|
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error)
|
||||||
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*api.EthTxReceipt, error)
|
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*api.EthTxReceipt, error)
|
||||||
@ -299,8 +300,53 @@ func (a *EthModule) EthGetTransactionByHash(ctx context.Context, txHash *ethtype
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *EthModule) EthGetMessageCidByTransactionHash(ctx context.Context, txHash *ethtypes.EthHash) (*cid.Cid, error) {
|
||||||
|
// Ethereum's behavior is to return null when the txHash is invalid, so we use nil to check if txHash is valid
|
||||||
|
if txHash == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
c := cid.Undef
|
||||||
|
if a.EthTxHashManager != nil {
|
||||||
|
var err error
|
||||||
|
c, err = a.EthTxHashManager.TransactionHashLookup.GetCidFromHash(*txHash)
|
||||||
|
// We fall out of the first condition and continue
|
||||||
|
if errors.Is(err, ethhashlookup.ErrNotFound) {
|
||||||
|
log.Debug("could not find transaction hash %s in lookup table", txHash.String())
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, xerrors.Errorf("database error: %w", err)
|
||||||
|
} else {
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This isn't an eth transaction we have the mapping for, so let's try looking it up as a filecoin message
|
||||||
|
if c == cid.Undef {
|
||||||
|
c = txHash.ToCid()
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := a.StateAPI.Chain.GetSignedMessage(ctx, c)
|
||||||
|
if err == nil {
|
||||||
|
// This is an Eth Tx, Secp message, Or BLS message in the mpool
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = a.StateAPI.Chain.GetMessage(ctx, c)
|
||||||
|
if err == nil {
|
||||||
|
// This is a BLS message
|
||||||
|
return &c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ethereum clients expect an empty response when the message was not found
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) {
|
func (a *EthModule) EthGetTransactionHashByCid(ctx context.Context, cid cid.Cid) (*ethtypes.EthHash, error) {
|
||||||
hash, err := EthTxHashFromFilecoinMessageCid(ctx, cid, a.StateAPI)
|
hash, err := EthTxHashFromFilecoinMessageCid(ctx, cid, a.StateAPI)
|
||||||
|
if hash == ethtypes.EmptyEthHash {
|
||||||
|
// not found
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
return &hash, err
|
return &hash, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1483,10 +1529,17 @@ func lookupEthAddress(ctx context.Context, addr address.Address, sa StateAPI) (e
|
|||||||
func EthTxHashFromFilecoinMessageCid(ctx context.Context, c cid.Cid, sa StateAPI) (ethtypes.EthHash, error) {
|
func EthTxHashFromFilecoinMessageCid(ctx context.Context, c cid.Cid, sa StateAPI) (ethtypes.EthHash, error) {
|
||||||
smsg, err := sa.Chain.GetSignedMessage(ctx, c)
|
smsg, err := sa.Chain.GetSignedMessage(ctx, c)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
// This is an Eth Tx, Secp message, Or BLS message in the mpool
|
||||||
return EthTxHashFromSignedFilecoinMessage(ctx, smsg, sa)
|
return EthTxHashFromSignedFilecoinMessage(ctx, smsg, sa)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err = sa.Chain.GetMessage(ctx, c)
|
||||||
|
if err == nil {
|
||||||
|
// This is a BLS message
|
||||||
return ethtypes.EthHashFromCid(c)
|
return ethtypes.EthHashFromCid(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ethtypes.EmptyEthHash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func EthTxHashFromSignedFilecoinMessage(ctx context.Context, smsg *types.SignedMessage, sa StateAPI) (ethtypes.EthHash, error) {
|
func EthTxHashFromSignedFilecoinMessage(ctx context.Context, smsg *types.SignedMessage, sa StateAPI) (ethtypes.EthHash, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user