github.1485827954.workers.dev/ethereum/go-ethereum@v1.14.3/internal/era/era_test.go (about)

     1  // Copyright 2023 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // go-ethereum is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package era
    18  
    19  import (
    20  	"bytes"
    21  	"io"
    22  	"math/big"
    23  	"os"
    24  	"testing"
    25  
    26  	"github.com/ethereum/go-ethereum/common"
    27  )
    28  
    29  type testchain struct {
    30  	headers  [][]byte
    31  	bodies   [][]byte
    32  	receipts [][]byte
    33  	tds      []*big.Int
    34  }
    35  
    36  func TestEra1Builder(t *testing.T) {
    37  	// Get temp directory.
    38  	f, err := os.CreateTemp("", "era1-test")
    39  	if err != nil {
    40  		t.Fatalf("error creating temp file: %v", err)
    41  	}
    42  	defer f.Close()
    43  
    44  	var (
    45  		builder = NewBuilder(f)
    46  		chain   = testchain{}
    47  	)
    48  	for i := 0; i < 128; i++ {
    49  		chain.headers = append(chain.headers, []byte{byte('h'), byte(i)})
    50  		chain.bodies = append(chain.bodies, []byte{byte('b'), byte(i)})
    51  		chain.receipts = append(chain.receipts, []byte{byte('r'), byte(i)})
    52  		chain.tds = append(chain.tds, big.NewInt(int64(i)))
    53  	}
    54  
    55  	// Write blocks to Era1.
    56  	for i := 0; i < len(chain.headers); i++ {
    57  		var (
    58  			header   = chain.headers[i]
    59  			body     = chain.bodies[i]
    60  			receipts = chain.receipts[i]
    61  			hash     = common.Hash{byte(i)}
    62  			td       = chain.tds[i]
    63  		)
    64  		if err = builder.AddRLP(header, body, receipts, uint64(i), hash, td, big.NewInt(1)); err != nil {
    65  			t.Fatalf("error adding entry: %v", err)
    66  		}
    67  	}
    68  
    69  	// Finalize Era1.
    70  	if _, err := builder.Finalize(); err != nil {
    71  		t.Fatalf("error finalizing era1: %v", err)
    72  	}
    73  
    74  	// Verify Era1 contents.
    75  	e, err := Open(f.Name())
    76  	if err != nil {
    77  		t.Fatalf("failed to open era: %v", err)
    78  	}
    79  	it, err := NewRawIterator(e)
    80  	if err != nil {
    81  		t.Fatalf("failed to make iterator: %s", err)
    82  	}
    83  	for i := uint64(0); i < uint64(len(chain.headers)); i++ {
    84  		if !it.Next() {
    85  			t.Fatalf("expected more entries")
    86  		}
    87  		if it.Error() != nil {
    88  			t.Fatalf("unexpected error %v", it.Error())
    89  		}
    90  		// Check headers.
    91  		header, err := io.ReadAll(it.Header)
    92  		if err != nil {
    93  			t.Fatalf("error reading header: %v", err)
    94  		}
    95  		if !bytes.Equal(header, chain.headers[i]) {
    96  			t.Fatalf("mismatched header: want %s, got %s", chain.headers[i], header)
    97  		}
    98  		// Check bodies.
    99  		body, err := io.ReadAll(it.Body)
   100  		if err != nil {
   101  			t.Fatalf("error reading body: %v", err)
   102  		}
   103  		if !bytes.Equal(body, chain.bodies[i]) {
   104  			t.Fatalf("mismatched body: want %s, got %s", chain.bodies[i], body)
   105  		}
   106  		// Check receipts.
   107  		receipts, err := io.ReadAll(it.Receipts)
   108  		if err != nil {
   109  			t.Fatalf("error reading receipts: %v", err)
   110  		}
   111  		if !bytes.Equal(receipts, chain.receipts[i]) {
   112  			t.Fatalf("mismatched receipts: want %s, got %s", chain.receipts[i], receipts)
   113  		}
   114  
   115  		// Check total difficulty.
   116  		rawTd, err := io.ReadAll(it.TotalDifficulty)
   117  		if err != nil {
   118  			t.Fatalf("error reading td: %v", err)
   119  		}
   120  		td := new(big.Int).SetBytes(reverseOrder(rawTd))
   121  		if td.Cmp(chain.tds[i]) != 0 {
   122  			t.Fatalf("mismatched tds: want %s, got %s", chain.tds[i], td)
   123  		}
   124  	}
   125  }
   126  
   127  func TestEraFilename(t *testing.T) {
   128  	for i, tt := range []struct {
   129  		network  string
   130  		epoch    int
   131  		root     common.Hash
   132  		expected string
   133  	}{
   134  		{"mainnet", 1, common.Hash{1}, "mainnet-00001-01000000.era1"},
   135  		{"goerli", 99999, common.HexToHash("0xdeadbeef00000000000000000000000000000000000000000000000000000000"), "goerli-99999-deadbeef.era1"},
   136  	} {
   137  		got := Filename(tt.network, tt.epoch, tt.root)
   138  		if tt.expected != got {
   139  			t.Errorf("test %d: invalid filename: want %s, got %s", i, tt.expected, got)
   140  		}
   141  	}
   142  }