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"`
|
Uncles []EthHash `json:"uncles"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const EthBloomSize = 2048
|
||||||
|
|
||||||
var (
|
var (
|
||||||
EmptyEthBloom = [256]byte{}
|
EmptyEthBloom = [EthBloomSize / 8]byte{}
|
||||||
|
FullEthBloom = [EthBloomSize / 8]byte{}
|
||||||
EmptyEthHash = EthHash{}
|
EmptyEthHash = EthHash{}
|
||||||
EmptyUncleHash = must.One(ParseEthHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")) // Keccak-256 of an RLP of an empty array
|
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
|
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}
|
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 {
|
func NewEthBlock(hasTransactions bool) EthBlock {
|
||||||
b := EthBlock{
|
b := EthBlock{
|
||||||
Sha3Uncles: EmptyUncleHash, // Sha3Uncles set to a hardcoded value which is used by some clients to determine if has no uncles.
|
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.
|
TransactionsRoot: EmptyRootHash, // TransactionsRoot set to a hardcoded value which is used by some clients to determine if has no transactions.
|
||||||
ReceiptsRoot: EmptyEthHash,
|
ReceiptsRoot: EmptyEthHash,
|
||||||
Difficulty: EmptyEthInt,
|
Difficulty: EmptyEthInt,
|
||||||
LogsBloom: EmptyEthBloom[:],
|
LogsBloom: FullEthBloom[:],
|
||||||
Extradata: []byte{},
|
Extradata: []byte{},
|
||||||
MixHash: EmptyEthHash,
|
MixHash: EmptyEthHash,
|
||||||
Nonce: EmptyEthNonce,
|
Nonce: EmptyEthNonce,
|
||||||
@ -440,6 +449,17 @@ func EthHashFromTxBytes(b []byte) EthHash {
|
|||||||
return 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 {
|
type EthFeeHistory struct {
|
||||||
OldestBlock EthUint64 `json:"oldestBlock"`
|
OldestBlock EthUint64 `json:"oldestBlock"`
|
||||||
BaseFeePerGas []EthBigInt `json:"baseFeePerGas"`
|
BaseFeePerGas []EthBigInt `json:"baseFeePerGas"`
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/bits"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -423,6 +424,51 @@ func TestEthSubscribeLogsNoTopicSpec(t *testing.T) {
|
|||||||
AssertEthLogs(t, elogs, expected, messages)
|
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) {
|
func TestEthGetLogs(t *testing.T) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
kit.QuietAllLogsExcept("events", "messagepool")
|
kit.QuietAllLogsExcept("events", "messagepool")
|
||||||
|
@ -1890,11 +1890,6 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(events) > 0 {
|
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))
|
receipt.Logs = make([]ethtypes.EthLog, 0, len(events))
|
||||||
for i, evt := range events {
|
for i, evt := range events {
|
||||||
l := ethtypes.EthLog{
|
l := ethtypes.EthLog{
|
||||||
@ -1912,6 +1907,7 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if entry.Key == ethtypes.EthTopic1 || entry.Key == ethtypes.EthTopic2 || entry.Key == ethtypes.EthTopic3 || entry.Key == ethtypes.EthTopic4 {
|
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)
|
l.Topics = append(l.Topics, entry.Value)
|
||||||
} else {
|
} else {
|
||||||
l.Data = entry.Value
|
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)
|
return api.EthTxReceipt{}, xerrors.Errorf("failed to resolve Ethereum address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ethtypes.EthBloomSet(receipt.LogsBloom, l.Address[:])
|
||||||
receipt.Logs = append(receipt.Logs, l)
|
receipt.Logs = append(receipt.Logs, l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user