Skip to content

Commit

Permalink
Add JSON encode/decode fuzzer test
Browse files Browse the repository at this point in the history
* remove earlier hardcoded test added in block_test and revert other
  helper changes in block_test
  • Loading branch information
vdamle committed Dec 2, 2024
1 parent 8e3b19b commit 700b1fd
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 72 deletions.
76 changes: 4 additions & 72 deletions core/types/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package types

import (
"bytes"
"encoding/json"
"math/big"
"reflect"
"testing"
Expand Down Expand Up @@ -206,7 +205,7 @@ func TestUncleHash(t *testing.T) {
var benchBuffer = bytes.NewBuffer(make([]byte, 0, 32000))

func BenchmarkEncodeBlock(b *testing.B) {
block := makeBenchBlock(nil)
block := makeBenchBlock()
b.ResetTimer()

for i := 0; i < b.N; i++ {
Expand All @@ -217,15 +216,12 @@ func BenchmarkEncodeBlock(b *testing.B) {
}
}

func makeBenchBlock(config *params.ChainConfig) *Block {
if config == nil {
config = params.TestChainConfig
}
func makeBenchBlock() *Block {
var (
key, _ = crypto.GenerateKey()
txs = make([]*Transaction, 70)
receipts = make([]*Receipt, len(txs))
signer = LatestSigner(config)
signer = LatestSigner(params.TestChainConfig)
uncles = make([]*Header, 3)
)
header := &Header{
Expand Down Expand Up @@ -259,7 +255,7 @@ func makeBenchBlock(config *params.ChainConfig) *Block {
}
}
withdrawals := make([]*Withdrawal, 0)
return NewBlock(header, &Body{Transactions: txs, Uncles: uncles, Withdrawals: withdrawals}, receipts, blocktest.NewHasher(), config)
return NewBlock(header, &Body{Transactions: txs, Uncles: uncles, Withdrawals: withdrawals}, receipts, blocktest.NewHasher(), params.TestChainConfig)
}

func TestRlpDecodeParentHash(t *testing.T) {
Expand Down Expand Up @@ -428,67 +424,3 @@ func TestCheckTransactionConditional(t *testing.T) {
})
}
}

func getTestHeader() *Header {
return &Header{
ParentHash: common.HexToHash("0x112233445566778899001122334455667788990011223344556677889900aabb"),
UncleHash: common.HexToHash("0x2233445566778899001122334455667788990011223344556677889900aabbcc"),
Coinbase: common.HexToAddress("0x8888f1f195afa192cfee860698584c030f4c9db1"),
Root: common.HexToHash("0x33445566778899001122334455667788990011223344556677889900aabbccdd"),
TxHash: common.HexToHash("0x445566778899001122334455667788990011223344556677889900aabbccddee"),
ReceiptHash: common.HexToHash("0x5566778899001122334455667788990011223344556677889900aabbccddeeff"),
WithdrawalsHash: &EmptyWithdrawalsHash,
Bloom: Bloom{},
Difficulty: big.NewInt(131072),
Number: big.NewInt(42),
GasLimit: 3141592,
GasUsed: 21000,
Time: 1426516743,
Extra: []byte("extra data"),
MixDigest: common.HexToHash("0x66778899001122334455667788990011223344556677889900aabbccddeeff00"),
Nonce: EncodeNonce(0xa13a5a8c8f2bb1c4),
BaseFee: big.NewInt(1000000000),
}
}

func checkFields(t *testing.T, header, want *Header) {
check := func(f string, got, want interface{}) {
if !reflect.DeepEqual(got, want) {
t.Errorf("%s mismatch: got %v, want %v", f, got, want)
}
}

check("ParentHash", header.ParentHash, want.ParentHash)
check("UncleHash", header.UncleHash, want.UncleHash)
check("Coinbase", header.Coinbase, want.Coinbase)
check("Root", header.Root, want.Root)
check("TxHash", header.TxHash, want.TxHash)
check("ReceiptHash", header.ReceiptHash, want.ReceiptHash)
check("WithdrawalsHash", header.WithdrawalsHash, want.WithdrawalsHash)
check("Bloom", header.Bloom, want.Bloom)
check("Difficulty", header.Difficulty, want.Difficulty)
check("Number", header.Number, want.Number)
check("GasLimit", header.GasLimit, want.GasLimit)
check("GasUsed", header.GasUsed, want.GasUsed)
check("Time", header.Time, want.Time)
check("Extra", header.Extra, want.Extra)
check("MixDigest", header.MixDigest, want.MixDigest)
check("Nonce", header.Nonce, want.Nonce)
check("BaseFee", header.BaseFee, want.BaseFee)
}

func TestHeaderJSONEncoding(t *testing.T) {
header := getTestHeader()

encoded, err := json.Marshal(header)
if err != nil {
t.Fatalf("failed to encode header to JSON: %v", err)
}

var decoded Header
if err := json.Unmarshal(encoded, &decoded); err != nil {
t.Fatalf("failed to decode header from JSON: %v", err)
}

checkFields(t, &decoded, header)
}
1 change: 1 addition & 0 deletions core/types/gen_transaction_conditional_json.go

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

55 changes: 55 additions & 0 deletions core/types/json_fuzzer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package types

import (
"bytes"
"encoding/json"
"fmt"
"testing"
)

func decodeEncodeJSON(input []byte, val interface{}) error {
if err := json.Unmarshal(input, &val); err != nil {
// not valid JSON, nothing to do
return nil
}
output, err := json.Marshal(val)
if err != nil {
return err
}
if !bytes.Equal(input, output) {
return fmt.Errorf("encode-decode is not equal, \ninput : %x\noutput: %x", input, output)
}
return nil
}

func FuzzJSON(f *testing.F) {
f.Fuzz(fuzzJSON)
}

func fuzzJSON(t *testing.T, input []byte) {
if len(input) == 0 {
return
}
{
var h Header
if err := decodeEncodeJSON(input, &h); err != nil {
t.Fatal(err)
}
var b Block
if err := decodeEncodeJSON(input, &b); err != nil {
t.Fatal(err)
}
var tx Transaction
if err := decodeEncodeJSON(input, &tx); err != nil {
t.Fatal(err)
}
var txs Transactions
if err := decodeEncodeJSON(input, &txs); err != nil {
t.Fatal(err)
}
var rs Receipts
if err := decodeEncodeJSON(input, &rs); err != nil {
t.Fatal(err)
}
}
}

0 comments on commit 700b1fd

Please sign in to comment.