More assertions in TestEthNewFilterCatchAll

This commit is contained in:
Ian Davis 2022-11-16 10:27:20 +00:00
parent 28035525f4
commit 0376b7b3e6
2 changed files with 188 additions and 3 deletions

2
extern/filecoin-ffi vendored

@ -1 +1 @@
Subproject commit 14151f5e623b37c9d47aee5192af6b3eeeae4a35
Subproject commit 39bed0d7a477eae618d310a476233eafe3e6b571

View File

@ -4,11 +4,15 @@ package itests
import (
"context"
"encoding/hex"
"fmt"
"os"
"strconv"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
@ -211,6 +215,13 @@ func TestEthNewFilterCatchAll(t *testing.T) {
const iterations = 10
type msgInTipset struct {
msg api.Message
ts *types.TipSet
}
msgChan := make(chan msgInTipset, iterations)
waitAllCh := make(chan struct{})
go func() {
headChangeCh, err := client.ChainNotify(ctx)
@ -223,9 +234,21 @@ func TestEthNewFilterCatchAll(t *testing.T) {
case headChanges := <-headChangeCh:
for _, change := range headChanges {
if change.Type == store.HCApply || change.Type == store.HCRevert {
count++
if count == iterations*3 {
msgs, err := client.ChainGetMessagesInTipset(ctx, change.Val.Key())
require.NoError(err)
count += len(msgs)
for _, m := range msgs {
select {
case msgChan <- msgInTipset{msg: m, ts: change.Val}:
default:
}
}
if count == iterations {
close(msgChan)
close(waitAllCh)
return
}
}
}
@ -247,10 +270,172 @@ func TestEthNewFilterCatchAll(t *testing.T) {
t.Errorf("timeout to wait for pack messages")
}
received := make(map[api.EthHash]msgInTipset)
for m := range msgChan {
eh, err := api.NewEthHashFromCid(m.msg.Cid)
require.NoError(err)
received[eh] = m
}
require.Equal(iterations, len(received), "all messages on chain")
ts, err := client.ChainHead(ctx)
require.NoError(err)
raddr, err := client.StateLookupRobustAddress(ctx, idAddr, ts.Key())
require.NoError(err)
ethContractAddr, err := api.EthAddressFromFilecoinAddress(raddr)
require.NoError(err)
// collect filter results
res, err := client.EthGetFilterChanges(ctx, filterID)
require.NoError(err)
// expect to have seen iteration number of events
require.Equal(iterations, len(res.Results))
fmt.Printf("ethAddr=%v\n", ethContractAddr.String())
for _, r := range res.Results {
// since response is a union and Go doesn't support them well, go-jsonrpc won't give us typed results
rc, ok := r.(map[string]interface{})
require.True(ok, "result type")
elog, err := ParseEthLog(rc)
require.NoError(err)
_ = elog
require.Equal(ethContractAddr.String(), rc["address"], "event address")
require.Equal("0x0", rc["transactionIndex"], "transaction index") // only one message per tipset
txHashAny, ok := rc["transactionHash"]
require.True(ok, "transactionHash")
txHashStr, ok := txHashAny.(string)
require.True(ok, "transactionHash string")
txHash, err := api.EthHashFromHex(txHashStr)
require.NoError(err)
msg, exists := received[txHash]
require.True(exists, "message seen on chain")
tsCid, err := msg.ts.Key().Cid()
require.NoError(err)
tsCidHash, err := api.NewEthHashFromCid(tsCid)
require.NoError(err)
require.Equal(tsCidHash.String(), rc["blockHash"], "block hash")
for k, v := range rc {
switch k {
}
fmt.Printf("%s=%v\n", k, v)
}
}
}
func ParseEthLog(in map[string]interface{}) (*api.EthLog, error) {
el := &api.EthLog{}
ethHash := func(k string, v interface{}) (api.EthHash, error) {
s, ok := v.(string)
if !ok {
return api.EthHash{}, xerrors.Errorf(k + " not a string")
}
return api.EthHashFromHex(s)
}
ethUint64 := func(k string, v interface{}) (api.EthUint64, error) {
s, ok := v.(string)
if !ok {
return 0, xerrors.Errorf(k + " not a string")
}
parsedInt, err := strconv.ParseUint(strings.Replace(s, "0x", "", -1), 16, 64)
if err != nil {
return 0, err
}
return api.EthUint64(parsedInt), nil
}
var err error
for k, v := range in {
switch k {
case "removed":
b, ok := v.(bool)
if ok {
el.Removed = b
continue
}
s, ok := v.(string)
if !ok {
return nil, xerrors.Errorf(k + " not a string")
}
el.Removed, err = strconv.ParseBool(s)
if err != nil {
return nil, err
}
case "address":
s, ok := v.(string)
if !ok {
return nil, xerrors.Errorf(k + " not a string")
}
el.Address, err = api.EthAddressFromHex(s)
if err != nil {
return nil, err
}
case "logIndex":
el.LogIndex, err = ethUint64(k, v)
if err != nil {
return nil, err
}
case "transactionIndex":
el.TransactionIndex, err = ethUint64(k, v)
if err != nil {
return nil, err
}
case "blockNumber":
el.BlockNumber, err = ethUint64(k, v)
if err != nil {
return nil, err
}
case "transactionHash":
el.TransactionHash, err = ethHash(k, v)
if err != nil {
return nil, err
}
case "blockHash":
el.BlockHash, err = ethHash(k, v)
if err != nil {
return nil, err
}
case "data":
sl, ok := v.([]interface{})
if !ok {
return nil, xerrors.Errorf(k + " not a slice")
}
for _, s := range sl {
data, err := ethHash(k, s)
if err != nil {
return nil, err
}
el.Data = append(el.Data, data)
}
case "topics":
sl, ok := v.([]interface{})
if !ok {
return nil, xerrors.Errorf(k + " not a slice")
}
for _, s := range sl {
topic, err := ethHash(k, s)
if err != nil {
return nil, err
}
el.Topics = append(el.Topics, topic)
}
}
}
return el, err
}