github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/chain/core/neat_genesis.go (about)

     1  package core
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  
     9  	"github.com/neatlab/neatio/chain/core/rawdb"
    10  	"github.com/neatlab/neatio/chain/core/types"
    11  	"github.com/neatlab/neatio/chain/log"
    12  	"github.com/neatlab/neatio/neatdb"
    13  	"github.com/neatlab/neatio/params"
    14  	"github.com/neatlab/neatio/utilities/common"
    15  )
    16  
    17  func WriteGenesisBlock(chainDb neatdb.Database, reader io.Reader) (*types.Block, error) {
    18  	contents, err := ioutil.ReadAll(reader)
    19  	if err != nil {
    20  		return nil, err
    21  	}
    22  
    23  	var (
    24  		genesis  Genesis
    25  		genesisW GenesisWrite
    26  	)
    27  
    28  	genesis.Alloc = GenesisAlloc{}
    29  
    30  	if err := json.Unmarshal(contents, &genesisW); err != nil {
    31  		return nil, err
    32  	}
    33  
    34  	genesis = Genesis{
    35  		Config:     genesisW.Config,
    36  		Nonce:      genesisW.Nonce,
    37  		Timestamp:  genesisW.Timestamp,
    38  		ParentHash: genesisW.ParentHash,
    39  		ExtraData:  genesisW.ExtraData,
    40  		GasLimit:   genesisW.GasLimit,
    41  		Difficulty: genesisW.Difficulty,
    42  		Mixhash:    genesisW.Mixhash,
    43  		Coinbase:   common.HexToAddress(genesisW.Coinbase),
    44  		Alloc:      GenesisAlloc{},
    45  	}
    46  
    47  	for k, v := range genesisW.Alloc {
    48  		genesis.Alloc[common.HexToAddress(k)] = v
    49  	}
    50  
    51  	return SetupGenesisBlockEx(chainDb, &genesis)
    52  }
    53  
    54  func SetupGenesisBlockEx(db neatdb.Database, genesis *Genesis) (*types.Block, error) {
    55  
    56  	if genesis != nil && genesis.Config == nil {
    57  		return nil, errGenesisNoConfig
    58  	}
    59  
    60  	var block *types.Block = nil
    61  	var err error = nil
    62  
    63  	stored := rawdb.ReadCanonicalHash(db, 0)
    64  	if (stored == common.Hash{}) {
    65  		if genesis == nil {
    66  			log.Info("Writing default main-net genesis block")
    67  			genesis = DefaultGenesisBlock()
    68  		} else {
    69  			log.Info("Writing custom genesis block")
    70  		}
    71  		block, err = genesis.Commit(db)
    72  		return block, err
    73  	}
    74  
    75  	if genesis != nil {
    76  		block = genesis.ToBlock(nil)
    77  		hash := block.Hash()
    78  		if hash != stored {
    79  			return nil, &GenesisMismatchError{stored, hash}
    80  		}
    81  	}
    82  
    83  	newcfg := genesis.configOrDefault(stored)
    84  	storedcfg := rawdb.ReadChainConfig(db, stored)
    85  	if storedcfg == nil {
    86  		log.Warn("Found genesis block without chain config")
    87  		rawdb.WriteChainConfig(db, stored, newcfg)
    88  		return block, err
    89  	}
    90  
    91  	if genesis == nil && stored != params.MainnetGenesisHash {
    92  		return block, nil
    93  	}
    94  
    95  	height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
    96  	if height == nil {
    97  		return nil, fmt.Errorf("missing block number for head header hash")
    98  	}
    99  	compatErr := storedcfg.CheckCompatible(newcfg, *height)
   100  	if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
   101  		return nil, compatErr
   102  	}
   103  	return block, err
   104  }
   105  
   106  func SetupGenesisBlockWithDefault(db neatdb.Database, genesis *Genesis, isMainChain, isTestnet bool) (*params.ChainConfig, common.Hash, error) {
   107  	if genesis != nil && genesis.Config == nil {
   108  
   109  		return nil, common.Hash{}, errGenesisNoConfig
   110  	}
   111  
   112  	stored := rawdb.ReadCanonicalHash(db, 0)
   113  	if (stored == common.Hash{} && isMainChain) {
   114  		if genesis == nil {
   115  			log.Info("Writing default main-net genesis block")
   116  			if isTestnet {
   117  				genesis = DefaultGenesisBlockFromJson(DefaultTestnetGenesisJSON)
   118  			} else {
   119  				genesis = DefaultGenesisBlockFromJson(DefaultMainnetGenesisJSON)
   120  			}
   121  		} else {
   122  			log.Info("Writing custom genesis block")
   123  		}
   124  		block, err := genesis.Commit(db)
   125  
   126  		return genesis.Config, block.Hash(), err
   127  	}
   128  
   129  	if genesis != nil {
   130  		hash := genesis.ToBlock(nil).Hash()
   131  		if hash != stored {
   132  
   133  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   134  		}
   135  	}
   136  
   137  	newcfg := genesis.configOrDefault(stored)
   138  	storedcfg := rawdb.ReadChainConfig(db, stored)
   139  	if storedcfg == nil {
   140  		log.Warn("Found genesis block without chain config")
   141  		rawdb.WriteChainConfig(db, stored, newcfg)
   142  
   143  		return newcfg, stored, nil
   144  	}
   145  
   146  	if genesis == nil && stored != params.MainnetGenesisHash {
   147  
   148  		return storedcfg, stored, nil
   149  	}
   150  
   151  	height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
   152  	if height == nil {
   153  
   154  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   155  	}
   156  	compatErr := storedcfg.CheckCompatible(newcfg, *height)
   157  	if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
   158  
   159  		return newcfg, stored, compatErr
   160  	}
   161  	rawdb.WriteChainConfig(db, stored, newcfg)
   162  
   163  	return newcfg, stored, nil
   164  }
   165  
   166  func DefaultGenesisBlockFromJson(genesisJson string) *Genesis {
   167  
   168  	var (
   169  		genesis  Genesis
   170  		genesisW GenesisWrite
   171  	)
   172  
   173  	genesis.Alloc = GenesisAlloc{}
   174  	if err := json.Unmarshal([]byte(genesisJson), &genesisW); err != nil {
   175  		return nil
   176  	}
   177  
   178  	genesis = Genesis{
   179  		Config:     genesisW.Config,
   180  		Nonce:      genesisW.Nonce,
   181  		Timestamp:  genesisW.Timestamp,
   182  		ParentHash: genesisW.ParentHash,
   183  		ExtraData:  genesisW.ExtraData,
   184  		GasLimit:   genesisW.GasLimit,
   185  		Difficulty: genesisW.Difficulty,
   186  		Mixhash:    genesisW.Mixhash,
   187  		Coinbase:   common.HexToAddress(genesisW.Coinbase),
   188  		Alloc:      GenesisAlloc{},
   189  	}
   190  
   191  	for i, v := range genesisW.Alloc {
   192  		genesis.Alloc[common.HexToAddress(i)] = v
   193  	}
   194  
   195  	return &genesis
   196  }
   197  
   198  var DefaultMainnetGenesisJSON = `{
   199  	"config": {
   200  			"neatChainId": "neatio",
   201  			"chainId": 515,
   202  			"homesteadBlock": 0,
   203  			"eip150Block": 0,
   204  			"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   205  			"eip155Block": 0,
   206  			"eip158Block": 0,
   207  			"byzantiumBlock": 0,
   208  			"petersburgBlock": 0,
   209  			"istanbulBlock": 0,
   210  			"neatcon": {
   211  					"epoch": 30000,
   212  					"policy": 0
   213  			}
   214  	},
   215  	"nonce": "0x0",
   216  	"timestamp": "0x6264ddcb",
   217  	"extraData": "0x",
   218  	"gasLimit": "0xe0000000",
   219  	"difficulty": "0x1",
   220  	"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   221  	"coinbase": "0x0000000000000000000000000000000000000000",
   222  	"alloc": {
   223  			"03ba7541d4484155c7d08b398d6ade9f34bd8363": {
   224  					"balance": "0x492bb173ae3d8b5300000",
   225  					"amount": "0xa968163f0a57b400000"
   226  			}
   227  	},
   228  	"number": "0x0",
   229  	"gasUsed": "0x0",
   230  	"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
   231  }`
   232  
   233  var DefaultTestnetGenesisJSON = `{
   234  	"config": {
   235  			"neatChainId": "neatio",
   236  			"chainId": 515,
   237  			"homesteadBlock": 0,
   238  			"eip150Block": 0,
   239  			"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   240  			"eip155Block": 0,
   241  			"eip158Block": 0,
   242  			"byzantiumBlock": 0,
   243  			"petersburgBlock": 0,
   244  			"istanbulBlock": 0,
   245  			"neatcon": {
   246  					"epoch": 30000,
   247  					"policy": 0
   248  			}
   249  	},
   250  	"nonce": "0x0",
   251  	"timestamp": "0x62579611",
   252  	"extraData": "0x",
   253  	"gasLimit": "0xe0000000",
   254  	"difficulty": "0x1",
   255  	"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   256  	"coinbase": "0x0000000000000000000000000000000000000000",
   257  	"alloc": {
   258  			"a67175cdaf47b91f2aa332d8ec44409a4890f0c4": {
   259  					"balance": "0x31729a3b22ff18d800000",
   260  					"amount": "0xa968163f0a57b400000"
   261  			}
   262  	},
   263  	"number": "0x0",
   264  	"gasUsed": "0x0",
   265  	"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
   266  }`