fix: ethrpc: emit correct bloom filters (#10194)
This commit is contained in:
parent
da2bb41aa3
commit
9339267e6e
@ -155,8 +155,11 @@ type EthBlock struct {
|
||||
Uncles []EthHash `json:"uncles"`
|
||||
}
|
||||
|
||||
const EthBloomSize = 2048
|
||||
|
||||
var (
|
||||
EmptyEthBloom = [256]byte{}
|
||||
EmptyEthBloom = [EthBloomSize / 8]byte{}
|
||||
FullEthBloom = [EthBloomSize / 8]byte{}
|
||||
EmptyEthHash = EthHash{}
|
||||
EmptyUncleHash = must.One(ParseEthHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")) // Keccak-256 of an RLP of an empty array
|
||||
EmptyRootHash = must.One(ParseEthHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) // Keccak-256 hash of the RLP of null
|
||||
@ -164,6 +167,12 @@ var (
|
||||
EmptyEthNonce = [8]byte{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
)
|
||||
|
||||
func init() {
|
||||
for i := range FullEthBloom {
|
||||
FullEthBloom[i] = 0xff
|
||||
}
|
||||
}
|
||||
|
||||
func NewEthBlock(hasTransactions bool) EthBlock {
|
||||
b := EthBlock{
|
||||
Sha3Uncles: EmptyUncleHash, // Sha3Uncles set to a hardcoded value which is used by some clients to determine if has no uncles.
|
||||
@ -171,7 +180,7 @@ func NewEthBlock(hasTransactions bool) EthBlock {
|
||||
TransactionsRoot: EmptyRootHash, // TransactionsRoot set to a hardcoded value which is used by some clients to determine if has no transactions.
|
||||
ReceiptsRoot: EmptyEthHash,
|
||||
Difficulty: EmptyEthInt,
|
||||
LogsBloom: EmptyEthBloom[:],
|
||||
LogsBloom: FullEthBloom[:],
|
||||
Extradata: []byte{},
|
||||
MixHash: EmptyEthHash,
|
||||
Nonce: EmptyEthNonce,
|
||||
@ -440,6 +449,17 @@ func EthHashFromTxBytes(b []byte) EthHash {
|
||||
return ethHash
|
||||
}
|
||||
|
||||
func EthBloomSet(f EthBytes, data []byte) {
|
||||
hasher := sha3.NewLegacyKeccak256()
|
||||
hasher.Write(data)
|
||||
hash := hasher.Sum(nil)
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
n := binary.BigEndian.Uint16(hash[i*2:]) % EthBloomSize
|
||||
f[(EthBloomSize/8)-(n/8)-1] |= 1 << (n % 8)
|
||||
}
|
||||
}
|
||||
|
||||
type EthFeeHistory struct {
|
||||
OldestBlock EthUint64 `json:"oldestBlock"`
|
||||
BaseFeePerGas []EthBigInt `json:"baseFeePerGas"`
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/bits"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
@ -423,6 +424,51 @@ func TestEthSubscribeLogsNoTopicSpec(t *testing.T) {
|
||||
AssertEthLogs(t, elogs, expected, messages)
|
||||
}
|
||||
|
||||
func TestTxReceiptBloom(t *testing.T) {
|
||||
blockTime := 50 * time.Millisecond
|
||||
client, _, ens := kit.EnsembleMinimal(
|
||||
t,
|
||||
kit.MockProofs(),
|
||||
kit.ThroughRPC())
|
||||
ens.InterconnectAll().BeginMining(blockTime)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
|
||||
fromAddr, idAddr := client.EVM().DeployContractFromFilename(ctx, "contracts/EventMatrix.hex")
|
||||
|
||||
_, ml, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "logEventZeroData()", nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
th, err := client.EthGetTransactionHashByCid(ctx, ml.Message)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, th)
|
||||
|
||||
receipt, err := client.EthGetTransactionReceipt(ctx, *th)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, receipt)
|
||||
require.Len(t, receipt.Logs, 1)
|
||||
|
||||
// computed by calling EventMatrix/logEventZeroData in remix
|
||||
// note this only contains topic bits
|
||||
matchMask := "0x00000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
|
||||
maskBytes, err := hex.DecodeString(matchMask[2:])
|
||||
require.NoError(t, err)
|
||||
|
||||
bitsSet := 0
|
||||
for i, maskByte := range maskBytes {
|
||||
bitsSet += bits.OnesCount8(receipt.LogsBloom[i])
|
||||
|
||||
if maskByte > 0 {
|
||||
require.True(t, maskByte&receipt.LogsBloom[i] > 0)
|
||||
}
|
||||
}
|
||||
|
||||
// 3 bits from the topic, 3 bits from the address
|
||||
require.Equal(t, 6, bitsSet)
|
||||
}
|
||||
|
||||
func TestEthGetLogs(t *testing.T) {
|
||||
require := require.New(t)
|
||||
kit.QuietAllLogsExcept("events", "messagepool")
|
||||
|
@ -1890,11 +1890,6 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
}
|
||||
|
||||
if len(events) > 0 {
|
||||
// TODO return a dummy non-zero bloom to signal that there are logs
|
||||
// need to figure out how worth it is to populate with a real bloom
|
||||
// should be feasible here since we are iterating over the logs anyway
|
||||
receipt.LogsBloom[255] = 0x01
|
||||
|
||||
receipt.Logs = make([]ethtypes.EthLog, 0, len(events))
|
||||
for i, evt := range events {
|
||||
l := ethtypes.EthLog{
|
||||
@ -1912,6 +1907,7 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
continue
|
||||
}
|
||||
if entry.Key == ethtypes.EthTopic1 || entry.Key == ethtypes.EthTopic2 || entry.Key == ethtypes.EthTopic3 || entry.Key == ethtypes.EthTopic4 {
|
||||
ethtypes.EthBloomSet(receipt.LogsBloom, entry.Value)
|
||||
l.Topics = append(l.Topics, entry.Value)
|
||||
} else {
|
||||
l.Data = entry.Value
|
||||
@ -1928,6 +1924,7 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
||||
return api.EthTxReceipt{}, xerrors.Errorf("failed to resolve Ethereum address: %w", err)
|
||||
}
|
||||
|
||||
ethtypes.EthBloomSet(receipt.LogsBloom, l.Address[:])
|
||||
receipt.Logs = append(receipt.Logs, l)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user