mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-26 06:36:43 +00:00
WIP
This commit is contained in:
parent
d86f0547cf
commit
08b6d495a9
6 changed files with 269 additions and 140 deletions
|
|
@ -59,11 +59,12 @@ func (b *Bloom) SetBytes(d []byte) {
|
|||
|
||||
// Add adds d to the filter. Future calls of Test(d) will return true.
|
||||
func (b *Bloom) Add(d []byte) {
|
||||
b.add(d, make([]byte, 6))
|
||||
var buf [6]byte
|
||||
b.AddWithBuffer(d, &buf)
|
||||
}
|
||||
|
||||
// add is internal version of Add, which takes a scratch buffer for reuse (needs to be at least 6 bytes)
|
||||
func (b *Bloom) add(d []byte, buf []byte) {
|
||||
func (b *Bloom) AddWithBuffer(d []byte, buf *[6]byte) {
|
||||
i1, v1, i2, v2, i3, v3 := bloomValues(d, buf)
|
||||
b[i1] |= v1
|
||||
b[i2] |= v2
|
||||
|
|
@ -84,7 +85,8 @@ func (b Bloom) Bytes() []byte {
|
|||
|
||||
// Test checks if the given topic is present in the bloom filter
|
||||
func (b Bloom) Test(topic []byte) bool {
|
||||
i1, v1, i2, v2, i3, v3 := bloomValues(topic, make([]byte, 6))
|
||||
var buf [6]byte
|
||||
i1, v1, i2, v2, i3, v3 := bloomValues(topic, &buf)
|
||||
return v1 == v1&b[i1] &&
|
||||
v2 == v2&b[i2] &&
|
||||
v3 == v3&b[i3]
|
||||
|
|
@ -107,9 +109,9 @@ func CreateBloom(receipt *Receipt) Bloom {
|
|||
buf = make([]byte, 6)
|
||||
)
|
||||
for _, log := range receipt.Logs {
|
||||
bin.add(log.Address.Bytes(), buf)
|
||||
bin.AddWithBuffer(log.Address.Bytes(), buf)
|
||||
for _, b := range log.Topics {
|
||||
bin.add(b[:], buf)
|
||||
bin.AddWithBuffer(b[:], buf)
|
||||
}
|
||||
}
|
||||
return bin
|
||||
|
|
@ -139,21 +141,20 @@ func Bloom9(data []byte) []byte {
|
|||
}
|
||||
|
||||
// bloomValues returns the bytes (index-value pairs) to set for the given data
|
||||
func bloomValues(data []byte, hashbuf []byte) (uint, byte, uint, byte, uint, byte) {
|
||||
func bloomValues(data []byte, hashbuf *[6]byte) (uint, byte, uint, byte, uint, byte) {
|
||||
sha := hasherPool.Get().(crypto.KeccakState)
|
||||
sha.Reset()
|
||||
sha.Write(data)
|
||||
sha.Read(hashbuf)
|
||||
sha.Read(hashbuf[:])
|
||||
hasherPool.Put(sha)
|
||||
// The actual bits to flip
|
||||
v1 := byte(1 << (hashbuf[1] & 0x7))
|
||||
v2 := byte(1 << (hashbuf[3] & 0x7))
|
||||
v3 := byte(1 << (hashbuf[5] & 0x7))
|
||||
// The indices for the bytes to OR in
|
||||
i1 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf)&0x7ff)>>3) - 1
|
||||
i1 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf[0:])&0x7ff)>>3) - 1
|
||||
i2 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf[2:])&0x7ff)>>3) - 1
|
||||
i3 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf[4:])&0x7ff)>>3) - 1
|
||||
|
||||
return i1, v1, i2, v2, i3, v3
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -699,41 +699,3 @@ func testGetPooledTransaction(t *testing.T, blobTx bool) {
|
|||
t.Errorf("pooled transaction mismatch: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTransformReceipts(t *testing.T) {
|
||||
tests := []struct {
|
||||
input []types.ReceiptForStorage
|
||||
txs []*types.Transaction
|
||||
output []receiptForNetwork
|
||||
}{
|
||||
{
|
||||
input: []types.ReceiptForStorage{{CumulativeGasUsed: 123, Status: 1, Logs: nil}},
|
||||
txs: []*types.Transaction{types.NewTx(&types.LegacyTx{})},
|
||||
output: []receiptForNetwork{{GasUsed: 123, Status: 1, Logs: nil}},
|
||||
},
|
||||
{
|
||||
input: []types.ReceiptForStorage{{CumulativeGasUsed: 123, Status: 1, Logs: nil}},
|
||||
txs: []*types.Transaction{types.NewTx(&types.DynamicFeeTx{})},
|
||||
output: []receiptForNetwork{{GasUsed: 123, Status: 1, Logs: nil, Type: 2}},
|
||||
},
|
||||
{
|
||||
input: []types.ReceiptForStorage{{CumulativeGasUsed: 123, Status: 1, Logs: nil}},
|
||||
txs: []*types.Transaction{types.NewTx(&types.AccessListTx{})},
|
||||
output: []receiptForNetwork{{GasUsed: 123, Status: 1, Logs: nil, Type: 1}},
|
||||
},
|
||||
{
|
||||
input: []types.ReceiptForStorage{{CumulativeGasUsed: 123, Status: 1, Logs: []*types.Log{{Address: common.Address{1}, Topics: []common.Hash{{1}}}}}},
|
||||
txs: []*types.Transaction{types.NewTx(&types.AccessListTx{})},
|
||||
output: []receiptForNetwork{{GasUsed: 123, Status: 1, Logs: []*types.Log{{Address: common.Address{1}, Topics: []common.Hash{{1}}}}, Type: 1}},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
in, _ := rlp.EncodeToBytes(test.input)
|
||||
have := transformReceipts(in, test.txs)
|
||||
out, _ := rlp.EncodeToBytes(test.output)
|
||||
if !bytes.Equal(have, out) {
|
||||
t.Fatalf("transforming receipt mismatch, test %v: want %v have %v", i, out, have)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package eth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
|
@ -319,7 +318,7 @@ func serviceGetReceiptsQuery69(chain *core.BlockChain, query GetReceiptsRequest)
|
|||
if header.ReceiptHash != types.EmptyReceiptsHash {
|
||||
body := new(types.Body)
|
||||
if err := rlp.DecodeBytes(chain.GetBodyRLP(hash), &body); err == nil {
|
||||
results = transformReceipts(results, body.Transactions)
|
||||
results = blockReceiptsToNetwork(results, body.Transactions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -329,33 +328,6 @@ func serviceGetReceiptsQuery69(chain *core.BlockChain, query GetReceiptsRequest)
|
|||
return receipts
|
||||
}
|
||||
|
||||
// transformReceipts takes a slice of rlp-encoded receipts, and transactions,
|
||||
// and applies the type-encoding on the receipts (for non-legacy receipts).
|
||||
// e.g. for non-legacy receipts: receipt-data -> {tx-type || receipt-data}
|
||||
func transformReceipts(blockReceipts []byte, txs []*types.Transaction) []byte {
|
||||
var (
|
||||
out bytes.Buffer
|
||||
enc = rlp.NewEncoderBuffer(&out)
|
||||
it, _ = rlp.NewListIterator(blockReceipts)
|
||||
)
|
||||
outer := enc.List()
|
||||
for i := 0; it.Next(); i++ {
|
||||
if txs[i].Type() == types.LegacyTxType {
|
||||
enc.Write(it.Value())
|
||||
continue
|
||||
}
|
||||
content, _, _ := rlp.SplitList(it.Value())
|
||||
receiptList := enc.List()
|
||||
enc.Write([]byte{txs[i].Type()})
|
||||
enc.Write(content)
|
||||
enc.ListEnd(receiptList)
|
||||
}
|
||||
enc.ListEnd(outer)
|
||||
enc.Flush()
|
||||
|
||||
return out.Bytes()
|
||||
}
|
||||
|
||||
func handleNewBlockhashes(backend Backend, msg Decoder, peer *Peer) error {
|
||||
return errors.New("block announcements disallowed") // We dropped support for non-merge networks
|
||||
}
|
||||
|
|
@ -440,32 +412,23 @@ func handleReceipts69(backend Backend, msg Decoder, peer *Peer) error {
|
|||
if err := msg.Decode(res); err != nil {
|
||||
return fmt.Errorf("%w: message %v: %v", errDecode, msg, err)
|
||||
}
|
||||
var response ReceiptsResponse
|
||||
// calculate the bloom filter before dispatching
|
||||
for _, receipts := range res.ReceiptsResponse69 {
|
||||
var rec []*types.Receipt
|
||||
for _, receipt := range receipts {
|
||||
receipt.Bloom = types.CreateBloom((*types.Receipt)(receipt))
|
||||
rec = append(rec, (*types.Receipt)(receipt))
|
||||
}
|
||||
response = append(response, rec)
|
||||
buffers := new(receiptListBuffers)
|
||||
for _, rl := range res.List {
|
||||
rl.buf = buffers
|
||||
// WIP
|
||||
}
|
||||
metadata := func() interface{} {
|
||||
hasher := trie.NewStackTrie(nil)
|
||||
hashes := make([]common.Hash, len(response))
|
||||
for i, receipts := range response {
|
||||
var r []*types.Receipt
|
||||
for _, receipt := range receipts {
|
||||
r = append(r, (*types.Receipt)(receipt))
|
||||
}
|
||||
hashes[i] = types.DeriveSha(types.Receipts(r), hasher)
|
||||
hashes := make([]common.Hash, len(res.List))
|
||||
for i, rl := range res.List {
|
||||
hashes[i] = types.DeriveSha(&rl, hasher)
|
||||
}
|
||||
return hashes
|
||||
}
|
||||
return peer.dispatchResponse(&Response{
|
||||
id: res.RequestId,
|
||||
code: ReceiptsMsg,
|
||||
Res: &response,
|
||||
Res: &res,
|
||||
}, metadata)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -260,14 +260,11 @@ type ReceiptsPacket struct {
|
|||
ReceiptsResponse
|
||||
}
|
||||
|
||||
// ReceiptsResponse is the network packet for block receipts distribution.
|
||||
type ReceiptsResponse69 [][]*receiptForNetwork
|
||||
|
||||
// ReceiptsPacket is the network packet for block receipts distribution with
|
||||
// request ID wrapping.
|
||||
type ReceiptsPacket69 struct {
|
||||
RequestId uint64
|
||||
ReceiptsResponse69
|
||||
List []ReceiptList69
|
||||
}
|
||||
|
||||
// ReceiptsRLPResponse is used for receipts, when we already have it encoded
|
||||
|
|
|
|||
|
|
@ -17,64 +17,206 @@
|
|||
package eth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
type receiptForNetwork types.Receipt
|
||||
|
||||
func (r *receiptForNetwork) DecodeRLP(s *rlp.Stream) error {
|
||||
kind, size, err := s.Kind()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if kind != rlp.List {
|
||||
return errors.New("invalid receipt")
|
||||
}
|
||||
if size == 4 {
|
||||
var rec = new(struct {
|
||||
Type byte
|
||||
Status uint64
|
||||
// Receipt is the eth/69 network encoding of a receipt.
|
||||
type Receipt struct {
|
||||
TxType byte
|
||||
PostStateOrStatus []byte
|
||||
GasUsed uint64
|
||||
Logs []*types.Log
|
||||
})
|
||||
if err := s.Decode(rec); err != nil {
|
||||
Logs rlp.RawValue
|
||||
}
|
||||
|
||||
func (r *Receipt) DecodeRLP(s *rlp.Stream) error {
|
||||
if _, err := s.List(); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Type = rec.Type
|
||||
r.Status = rec.Status
|
||||
r.GasUsed = rec.GasUsed
|
||||
r.Logs = rec.Logs
|
||||
} else {
|
||||
s.Decode(&r)
|
||||
txtype, err := s.Uint8()
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid txType: %w", err)
|
||||
}
|
||||
postStateOrStatus, err := s.Bytes()
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid postStateOrStatus: %w", err)
|
||||
}
|
||||
gasUsed, err := s.Uint64()
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid gasUsed: %w", err)
|
||||
}
|
||||
logs, err := s.Raw()
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid logs: %w", err)
|
||||
}
|
||||
*r = Receipt{
|
||||
TxType: txtype,
|
||||
PostStateOrStatus: postStateOrStatus,
|
||||
GasUsed: gasUsed,
|
||||
Logs: logs,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *receiptForNetwork) EncodeRLP(_w io.Writer) error {
|
||||
data := &types.ReceiptForStorage{Status: r.Status, CumulativeGasUsed: r.GasUsed, Logs: r.Logs}
|
||||
if r.Type == types.LegacyTxType {
|
||||
return rlp.Encode(_w, data)
|
||||
}
|
||||
func (r *Receipt) EncodeRLP(_w io.Writer) error {
|
||||
w := rlp.NewEncoderBuffer(_w)
|
||||
outerList := w.List()
|
||||
w.Write([]byte{r.Type})
|
||||
if r.Status == types.ReceiptStatusSuccessful {
|
||||
w.Write([]byte{0x01})
|
||||
} else {
|
||||
w.Write([]byte{0x00})
|
||||
}
|
||||
list := w.List()
|
||||
w.WriteUint64(uint64(r.TxType))
|
||||
w.WriteBytes(r.PostStateOrStatus)
|
||||
w.WriteUint64(r.GasUsed)
|
||||
logList := w.List()
|
||||
for _, log := range r.Logs {
|
||||
if err := log.EncodeRLP(w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
w.ListEnd(logList)
|
||||
w.ListEnd(outerList)
|
||||
w.Write(r.Logs)
|
||||
w.ListEnd(list)
|
||||
return w.Flush()
|
||||
}
|
||||
|
||||
// bloom computes the bloom filter of the receipt.
|
||||
// Note this doesn't check the validity of encoding, and will produce an invalid filter
|
||||
// for invalid input. This is acceptable for the purpose of this function, which is
|
||||
// recomputing the receipt hash.
|
||||
func (r *Receipt) bloom(buffer *[6]byte) types.Bloom {
|
||||
var b types.Bloom
|
||||
logsIter, err := rlp.NewListIterator(r.Logs)
|
||||
if err != nil {
|
||||
return b
|
||||
}
|
||||
for logsIter.Next() {
|
||||
log := logsIter.Value()
|
||||
address, log, _ := rlp.SplitString(log)
|
||||
b.AddWithBuffer(address, buffer)
|
||||
topicsIter, err := rlp.NewListIterator(log)
|
||||
if err != nil {
|
||||
return b
|
||||
}
|
||||
for topicsIter.Next() {
|
||||
b.AddWithBuffer(topicsIter.Value(), buffer)
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// ReceiptList69 is the block receipt list as downloaded by eth/69.
|
||||
// This implements types.DerivableList for validation purposes.
|
||||
type ReceiptList69 struct {
|
||||
buf *receiptListBuffers
|
||||
items []Receipt
|
||||
}
|
||||
|
||||
type receiptListBuffers struct {
|
||||
enc rlp.EncoderBuffer
|
||||
bloom [6]byte
|
||||
}
|
||||
|
||||
// Len returns the length of the list.
|
||||
func (rl *ReceiptList69) Len() int {
|
||||
return len(rl.items)
|
||||
}
|
||||
|
||||
// EncodeIndex implements types.DerivableList.
|
||||
func (rl *ReceiptList69) EncodeIndex(i int, b *bytes.Buffer) {
|
||||
if rl.buf == nil {
|
||||
rl.buf = new(receiptListBuffers)
|
||||
}
|
||||
|
||||
var (
|
||||
r = &rl.items[i]
|
||||
bloom = r.bloom(&rl.buf.bloom)
|
||||
w = &rl.buf.enc
|
||||
)
|
||||
// encode receipt list: [postStateOrStatus, gasUsed, bloom, logs]
|
||||
w.Reset(b)
|
||||
l := w.List()
|
||||
w.WriteBytes(r.PostStateOrStatus)
|
||||
w.WriteUint64(r.GasUsed)
|
||||
w.WriteBytes(bloom[:])
|
||||
w.Write(r.Logs)
|
||||
w.ListEnd(l)
|
||||
if err := w.Flush(); err != nil {
|
||||
return
|
||||
}
|
||||
// if this is a legacy transaction receipt, we are done.
|
||||
if r.TxType == 0 {
|
||||
return
|
||||
}
|
||||
// Otherwise it's a typed transaction receipt, which has the type prefix and
|
||||
// the inner list as a byte-array: tx-type || rlp(list).
|
||||
// Since b contains the correct inner list, we can reuse its content.
|
||||
w.Reset(b)
|
||||
w.WriteUint64(uint64(r.TxType))
|
||||
w.WriteBytes(b.Bytes())
|
||||
w.Flush()
|
||||
}
|
||||
|
||||
// EncodeForDatabase
|
||||
func (rl *ReceiptList69) EncodeForDatabase() []byte {
|
||||
if rl.buf == nil {
|
||||
rl.buf = new(receiptListBuffers)
|
||||
}
|
||||
|
||||
var (
|
||||
r = &rl.items[i]
|
||||
bloom = r.bloom(&rl.buf.bloom)
|
||||
w = &rl.buf.enc
|
||||
)
|
||||
// encode receipt list: [postStateOrStatus, gasUsed, bloom, logs]
|
||||
w.Reset(b)
|
||||
l := w.List()
|
||||
w.WriteBytes(r.PostStateOrStatus)
|
||||
w.WriteUint64(r.GasUsed)
|
||||
w.WriteBytes(bloom[:])
|
||||
w.Write(r.Logs)
|
||||
w.ListEnd(l)
|
||||
if err := w.Flush(); err != nil {
|
||||
return
|
||||
}
|
||||
// if this is a legacy transaction receipt, we are done.
|
||||
if r.TxType == 0 {
|
||||
return
|
||||
}
|
||||
// Otherwise it's a typed transaction receipt, which has the type prefix and
|
||||
// the inner list as a byte-array: tx-type || rlp(list).
|
||||
// Since b contains the correct inner list, we can reuse its content.
|
||||
w.Reset(b)
|
||||
w.WriteUint64(uint64(r.TxType))
|
||||
w.WriteBytes(b.Bytes())
|
||||
w.Flush()
|
||||
|
||||
}
|
||||
|
||||
func (rl *ReceiptList69) toReceipts() []*types.Receipt {
|
||||
list := make([]*types.Receipt, len(rl.items))
|
||||
for i, r := range rl.items {
|
||||
list[i] = &types.Receipt{
|
||||
Type: r.TxType,
|
||||
PostState: r.PostStateOrStatus,
|
||||
CumulativeGasUsed: r.GasUsed,
|
||||
}
|
||||
rlp.DecodeBytes(r.Logs, &list[i].Logs)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// blockReceiptsToNetwork takes a slice of rlp-encoded receipts, and transactions,
|
||||
// and applies the type-encoding on the receipts (for non-legacy receipts).
|
||||
// e.g. for non-legacy receipts: receipt-data -> {tx-type || receipt-data}
|
||||
func blockReceiptsToNetwork(blockReceipts []byte, txs []*types.Transaction) []byte {
|
||||
var (
|
||||
out bytes.Buffer
|
||||
enc = rlp.NewEncoderBuffer(&out)
|
||||
it, _ = rlp.NewListIterator(blockReceipts)
|
||||
)
|
||||
outer := enc.List()
|
||||
for i := 0; it.Next(); i++ {
|
||||
content, _, _ := rlp.SplitList(it.Value())
|
||||
receiptList := enc.List()
|
||||
enc.Write([]byte{txs[i].Type()})
|
||||
enc.Write(content)
|
||||
enc.ListEnd(receiptList)
|
||||
}
|
||||
enc.ListEnd(outer)
|
||||
enc.Flush()
|
||||
return out.Bytes()
|
||||
}
|
||||
|
|
|
|||
64
eth/protocols/eth/receipt_test.go
Normal file
64
eth/protocols/eth/receipt_test.go
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2024 The go-ethereum Authors
|
||||
// This file is part of the go-ethereum library.
|
||||
//
|
||||
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package eth
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
func TestTransformReceipts(t *testing.T) {
|
||||
tests := []struct {
|
||||
input []types.ReceiptForStorage
|
||||
txs []*types.Transaction
|
||||
output []Receipt
|
||||
}{
|
||||
{
|
||||
input: []types.ReceiptForStorage{{CumulativeGasUsed: 123, Status: 1, Logs: nil}},
|
||||
txs: []*types.Transaction{types.NewTx(&types.LegacyTx{})},
|
||||
output: []Receipt{{GasUsed: 123, PostStateOrStatus: []byte{1}, Logs: nil}},
|
||||
},
|
||||
{
|
||||
input: []types.ReceiptForStorage{{CumulativeGasUsed: 123, Status: 1, Logs: nil}},
|
||||
txs: []*types.Transaction{types.NewTx(&types.DynamicFeeTx{})},
|
||||
output: []Receipt{{GasUsed: 123, PostStateOrStatus: []byte{1}, Logs: nil, TxType: 2}},
|
||||
},
|
||||
{
|
||||
input: []types.ReceiptForStorage{{CumulativeGasUsed: 123, Status: 1, Logs: nil}},
|
||||
txs: []*types.Transaction{types.NewTx(&types.AccessListTx{})},
|
||||
output: []Receipt{{GasUsed: 123, PostStateOrStatus: []byte{1}, Logs: nil, TxType: 1}},
|
||||
},
|
||||
{
|
||||
input: []types.ReceiptForStorage{{CumulativeGasUsed: 123, Status: 1, Logs: []*types.Log{{Address: common.Address{1}, Topics: []common.Hash{{1}}}}}},
|
||||
txs: []*types.Transaction{types.NewTx(&types.AccessListTx{})},
|
||||
output: []Receipt{{GasUsed: 123, PostStateOrStatus: []byte{1}, Logs: []*types.Log{{Address: common.Address{1}, Topics: []common.Hash{{1}}}}, Type: 1}},
|
||||
},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
in, _ := rlp.EncodeToBytes(test.input)
|
||||
have := blockReceiptsToNetwork(in, test.txs)
|
||||
out, _ := rlp.EncodeToBytes(test.output)
|
||||
if !bytes.Equal(have, out) {
|
||||
t.Fatalf("transforming receipt mismatch, test %v: want %v have %v", i, out, have)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue