Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: API for EthGetMessageCidByTransactionHash #10055

Merged
merged 2 commits into from
Jan 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/api_full.go
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,7 @@ type FullNode interface {
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
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
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
Expand Down
15 changes: 15 additions & 0 deletions api/mocks/mock_full.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions api/proxy_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified build/openrpc/full.json.gz
Binary file not shown.
Binary file modified build/openrpc/gateway.json.gz
Binary file not shown.
Binary file modified build/openrpc/miner.json.gz
Binary file not shown.
Binary file modified build/openrpc/worker.json.gz
Binary file not shown.
20 changes: 20 additions & 0 deletions documentation/en/api-v1-unstable-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
* [EthGetFilterChanges](#EthGetFilterChanges)
* [EthGetFilterLogs](#EthGetFilterLogs)
* [EthGetLogs](#EthGetLogs)
* [EthGetMessageCidByTransactionHash](#EthGetMessageCidByTransactionHash)
* [EthGetStorageAt](#EthGetStorageAt)
* [EthGetTransactionByBlockHashAndIndex](#EthGetTransactionByBlockHashAndIndex)
* [EthGetTransactionByBlockNumberAndIndex](#EthGetTransactionByBlockNumberAndIndex)
Expand Down Expand Up @@ -2641,6 +2642,25 @@ Response:
]
```

### EthGetMessageCidByTransactionHash


Perms: read

Inputs:
```json
[
"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
]
```

Response:
```json
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
```

### EthGetStorageAt


Expand Down
258 changes: 258 additions & 0 deletions itests/eth_hash_lookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,261 @@ func TestTransactionHashLookupSecpFilecoinMessage(t *testing.T) {
require.NotNil(t, chainTx.TransactionIndex)
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: &ethAddr,
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)
}
1 change: 1 addition & 0 deletions node/config/def.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ func DefaultFullNode() *FullNode {
},
Fevm: FevmConfig{
EnableEthHashToFilecoinCidMapping: false,
EthTxHashMappingLifetimeDays: 0,
},
}
}
Expand Down
Loading