github.com/theQRL/go-zond@v0.2.1/core/genesis_test.go (about)

     1  // Copyright 2017 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser 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  // The go-ethereum library 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 Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package core
    18  
    19  import (
    20  	"encoding/json"
    21  	"math/big"
    22  	"reflect"
    23  	"testing"
    24  
    25  	"github.com/davecgh/go-spew/spew"
    26  	"github.com/theQRL/go-zond/common"
    27  	"github.com/theQRL/go-zond/core/rawdb"
    28  	"github.com/theQRL/go-zond/params"
    29  	"github.com/theQRL/go-zond/trie"
    30  	"github.com/theQRL/go-zond/trie/triedb/pathdb"
    31  	"github.com/theQRL/go-zond/zonddb"
    32  )
    33  
    34  func TestSetupGenesis(t *testing.T) {
    35  	testSetupGenesis(t, rawdb.HashScheme)
    36  	testSetupGenesis(t, rawdb.PathScheme)
    37  }
    38  
    39  func testSetupGenesis(t *testing.T, scheme string) {
    40  	var (
    41  		customghash = common.HexToHash("0x512a0d99941f1551db550852bdec6c9e213595356ede9dd23d1572199a8d66ba")
    42  		customg     = Genesis{
    43  			Config: &params.ChainConfig{},
    44  			Alloc: GenesisAlloc{
    45  				{1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}},
    46  			},
    47  		}
    48  		oldcustomg = customg
    49  	)
    50  	oldcustomg.Config = &params.ChainConfig{}
    51  
    52  	tests := []struct {
    53  		name       string
    54  		fn         func(zonddb.Database) (*params.ChainConfig, common.Hash, error)
    55  		wantConfig *params.ChainConfig
    56  		wantHash   common.Hash
    57  		wantErr    error
    58  	}{
    59  		{
    60  			name: "genesis without ChainConfig",
    61  			fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) {
    62  				return SetupGenesisBlock(db, trie.NewDatabase(db, newDbConfig(scheme)), new(Genesis))
    63  			},
    64  			wantErr:    errGenesisNoConfig,
    65  			wantConfig: params.AllBeaconProtocolChanges,
    66  		},
    67  		// TODO(now.youtrack.cloud/issue/TGZ-16)
    68  		/*
    69  			{
    70  				name: "no block in DB, genesis == nil",
    71  				fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) {
    72  					return SetupGenesisBlock(db, trie.NewDatabase(db, newDbConfig(scheme)), nil)
    73  				},
    74  				// wantHash:   params.MainnetGenesisHash,
    75  				wantHash:   common.HexToHash("b3de630542cf9acf842e24f428c7c21b7824b38a7718a632e424b58ba0f562c6"),
    76  				wantConfig: params.MainnetChainConfig,
    77  			},
    78  			{
    79  				name: "mainnet block in DB, genesis == nil",
    80  				fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) {
    81  					DefaultGenesisBlock().MustCommit(db, trie.NewDatabase(db, newDbConfig(scheme)))
    82  					return SetupGenesisBlock(db, trie.NewDatabase(db, newDbConfig(scheme)), nil)
    83  				},
    84  				wantHash:   params.MainnetGenesisHash,
    85  				wantConfig: params.MainnetChainConfig,
    86  			},
    87  		*/
    88  		{
    89  			name: "custom block in DB, genesis == nil",
    90  			fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) {
    91  				tdb := trie.NewDatabase(db, newDbConfig(scheme))
    92  				customg.Commit(db, tdb)
    93  				return SetupGenesisBlock(db, tdb, nil)
    94  			},
    95  			wantHash:   customghash,
    96  			wantConfig: customg.Config,
    97  		},
    98  		// TODO(now.youtrack.cloud/issue/TGZ-16)
    99  		/*
   100  			{
   101  				name: "custom block in DB, genesis == goerli",
   102  				fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) {
   103  					tdb := trie.NewDatabase(db, newDbConfig(scheme))
   104  					customg.Commit(db, tdb)
   105  					return SetupGenesisBlock(db, tdb, DefaultGoerliGenesisBlock())
   106  				},
   107  				wantErr:    &GenesisMismatchError{Stored: customghash, New: params.GoerliGenesisHash},
   108  				wantHash:   params.GoerliGenesisHash,
   109  				wantConfig: params.GoerliChainConfig,
   110  			},
   111  		*/
   112  		{
   113  			name: "compatible config in DB",
   114  			fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) {
   115  				tdb := trie.NewDatabase(db, newDbConfig(scheme))
   116  				oldcustomg.Commit(db, tdb)
   117  				return SetupGenesisBlock(db, tdb, &customg)
   118  			},
   119  			wantHash:   customghash,
   120  			wantConfig: customg.Config,
   121  		},
   122  		// NOTE(rgeraldes24): not valid for now
   123  		/*
   124  			{
   125  				name: "incompatible config in DB",
   126  				fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) {
   127  					// Commit the 'old' genesis block with Homestead transition at #2.
   128  					// Advance to block #4, past the homestead transition block of customg.
   129  					tdb := trie.NewDatabase(db, newDbConfig(scheme))
   130  					oldcustomg.Commit(db, tdb)
   131  
   132  					bc, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), &oldcustomg, beacon.NewFullFaker(), vm.Config{}, nil, nil)
   133  					defer bc.Stop()
   134  
   135  					_, blocks, _ := GenerateChainWithGenesis(&oldcustomg, beacon.NewFaker(), 4, nil)
   136  					bc.InsertChain(blocks)
   137  
   138  					// This should return a compatibility error.
   139  					return SetupGenesisBlock(db, tdb, &customg)
   140  				},
   141  				wantHash:   customghash,
   142  				wantConfig: customg.Config,
   143  				wantErr: &params.ConfigCompatError{
   144  					What:          "Homestead fork block",
   145  					StoredBlock:   big.NewInt(2),
   146  					NewBlock:      big.NewInt(3),
   147  					RewindToBlock: 1,
   148  				},
   149  			},
   150  		*/
   151  	}
   152  
   153  	for _, test := range tests {
   154  		db := rawdb.NewMemoryDatabase()
   155  		config, hash, err := test.fn(db)
   156  		// Check the return values.
   157  		if !reflect.DeepEqual(err, test.wantErr) {
   158  			spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true}
   159  			t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(err), spew.NewFormatter(test.wantErr))
   160  		}
   161  		if !reflect.DeepEqual(config, test.wantConfig) {
   162  			t.Errorf("%s:\nreturned %v\nwant     %v", test.name, config, test.wantConfig)
   163  		}
   164  		if hash != test.wantHash {
   165  			t.Errorf("%s: returned hash %s, want %s", test.name, hash.Hex(), test.wantHash.Hex())
   166  		} else if err == nil {
   167  			// Check database content.
   168  			stored := rawdb.ReadBlock(db, test.wantHash, 0)
   169  			if stored.Hash() != test.wantHash {
   170  				t.Errorf("%s: block in DB has hash %s, want %s", test.name, stored.Hash(), test.wantHash)
   171  			}
   172  		}
   173  	}
   174  }
   175  
   176  // TestGenesisHashes checks the congruity of default genesis data to
   177  // corresponding hardcoded genesis hash values.
   178  func TestGenesisHashes(t *testing.T) {
   179  	for i, c := range []struct {
   180  		genesis *Genesis
   181  		want    common.Hash
   182  	}{
   183  		// TODO(now.youtrack.cloud/issue/TGZ-16)
   184  		{DefaultGenesisBlock(), params.MainnetGenesisHash},
   185  		{DefaultBetaNetGenesisBlock(), params.BetaNetGenesisHash},
   186  		{DefaultTestnetGenesisBlock(), params.TestnetGenesisHash},
   187  	} {
   188  		// Test via MustCommit
   189  		db := rawdb.NewMemoryDatabase()
   190  		if have := c.genesis.MustCommit(db, trie.NewDatabase(db, trie.HashDefaults)).Hash(); have != c.want {
   191  			t.Errorf("case: %d a), want: %s, got: %s", i, c.want.Hex(), have.Hex())
   192  		}
   193  		// Test via ToBlock
   194  		if have := c.genesis.ToBlock().Hash(); have != c.want {
   195  			t.Errorf("case: %d a), want: %s, got: %s", i, c.want.Hex(), have.Hex())
   196  		}
   197  	}
   198  }
   199  
   200  // TestGenesisExtraDataLen checks length of extra data
   201  // should be exactly 32 bytes
   202  func TestGenesisExtraDataLen(t *testing.T) {
   203  	for i, c := range []struct {
   204  		genesis *Genesis
   205  	}{
   206  		{DefaultGenesisBlock()},
   207  		{DefaultBetaNetGenesisBlock()},
   208  		{DefaultTestnetGenesisBlock()},
   209  	} {
   210  		if len(c.genesis.ExtraData) != 32 {
   211  			t.Errorf("case: %d a), want: %d, got: %d", i, 32, len(c.genesis.ExtraData))
   212  		}
   213  	}
   214  }
   215  
   216  func TestGenesis_Commit(t *testing.T) {
   217  	genesis := &Genesis{
   218  		Config: params.TestChainConfig,
   219  		// basefee is nil
   220  	}
   221  
   222  	db := rawdb.NewMemoryDatabase()
   223  	genesisBlock := genesis.MustCommit(db, trie.NewDatabase(db, trie.HashDefaults))
   224  
   225  	if genesis.BaseFee != nil {
   226  		t.Fatalf("assumption wrong")
   227  	}
   228  
   229  	// This value should have been set as default in the ToBlock method.
   230  	if genesisBlock.BaseFee().Cmp(new(big.Int).SetUint64(params.InitialBaseFee)) != 0 {
   231  		t.Errorf("assumption wrong: want: %d, got: %v", params.InitialBaseFee, genesisBlock.BaseFee())
   232  	}
   233  
   234  	// Expect the stored basefee to be the basefee of the genesis block.
   235  	blk := rawdb.ReadBlock(db, genesisBlock.Hash(), 0)
   236  	if blk == nil {
   237  		t.Errorf("unable to retrieve block %d for canonical hash: %s", blk.NumberU64(), blk.Hash())
   238  		return
   239  	}
   240  
   241  	if blk.BaseFee().Cmp(genesisBlock.BaseFee()) != 0 {
   242  		t.Errorf("inequal difficulty; stored: %v, genesisBlock: %v", blk.BaseFee(), genesisBlock.BaseFee())
   243  	}
   244  }
   245  
   246  func TestReadWriteGenesisAlloc(t *testing.T) {
   247  	var (
   248  		db    = rawdb.NewMemoryDatabase()
   249  		alloc = &GenesisAlloc{
   250  			{1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}},
   251  			{2}: {Balance: big.NewInt(2), Storage: map[common.Hash]common.Hash{{2}: {2}}},
   252  		}
   253  		hash, _ = alloc.deriveHash()
   254  	)
   255  	blob, _ := json.Marshal(alloc)
   256  	rawdb.WriteGenesisStateSpec(db, hash, blob)
   257  
   258  	var reload GenesisAlloc
   259  	err := reload.UnmarshalJSON(rawdb.ReadGenesisStateSpec(db, hash))
   260  	if err != nil {
   261  		t.Fatalf("Failed to load genesis state %v", err)
   262  	}
   263  	if len(reload) != len(*alloc) {
   264  		t.Fatal("Unexpected genesis allocation")
   265  	}
   266  	for addr, account := range reload {
   267  		want, ok := (*alloc)[addr]
   268  		if !ok {
   269  			t.Fatal("Account is not found")
   270  		}
   271  		if !reflect.DeepEqual(want, account) {
   272  			t.Fatal("Unexpected account")
   273  		}
   274  	}
   275  }
   276  
   277  func newDbConfig(scheme string) *trie.Config {
   278  	if scheme == rawdb.HashScheme {
   279  		return trie.HashDefaults
   280  	}
   281  	return &trie.Config{PathDB: pathdb.Defaults}
   282  }