github.com/intfoundation/intchain@v0.0.0-20220727031208-4316ad31ca73/core/genesis1.go (about)

     1  package core
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"github.com/intfoundation/intchain/common"
     7  	"github.com/intfoundation/intchain/core/rawdb"
     8  	"github.com/intfoundation/intchain/core/types"
     9  	"github.com/intfoundation/intchain/intdb"
    10  	"github.com/intfoundation/intchain/log"
    11  	"github.com/intfoundation/intchain/params"
    12  	"io"
    13  	"io/ioutil"
    14  )
    15  
    16  // WriteGenesisBlock writes the genesis block to the database as block number 0
    17  func WriteGenesisBlock(chainDb intdb.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 genesis = Genesis{}
    24  
    25  	if err := json.Unmarshal(contents, &genesis); err != nil {
    26  		return nil, err
    27  	}
    28  
    29  	return SetupGenesisBlockEx(chainDb, &genesis)
    30  }
    31  
    32  func SetupGenesisBlockEx(db intdb.Database, genesis *Genesis) (*types.Block, error) {
    33  
    34  	if genesis != nil && genesis.Config == nil {
    35  		return nil, errGenesisNoConfig
    36  	}
    37  
    38  	var block *types.Block = nil
    39  	var err error = nil
    40  
    41  	// Just commit the new block if there is no stored genesis block.
    42  	stored := rawdb.ReadCanonicalHash(db, 0)
    43  	if (stored == common.Hash{}) {
    44  		if genesis == nil {
    45  			log.Info("Writing default main-net genesis block")
    46  			genesis = DefaultGenesisBlock()
    47  		} else {
    48  			log.Info("Writing custom genesis block")
    49  		}
    50  		block, err = genesis.Commit(db)
    51  		return block, err
    52  	}
    53  
    54  	// Check whether the genesis block is already written.
    55  	if genesis != nil {
    56  		block = genesis.ToBlock(nil)
    57  		hash := block.Hash()
    58  		if hash != stored {
    59  			return nil, &GenesisMismatchError{stored, hash}
    60  		}
    61  	}
    62  
    63  	// Get the existing chain configuration.
    64  	newcfg := genesis.configOrDefault(stored)
    65  	storedcfg := rawdb.ReadChainConfig(db, stored)
    66  	if storedcfg == nil {
    67  		log.Warn("Found genesis block without chain config")
    68  		rawdb.WriteChainConfig(db, stored, newcfg)
    69  		return block, err
    70  	}
    71  	// Special case: don't change the existing config of a non-mainnet chain if no new
    72  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
    73  	// if we just continued here.
    74  	if genesis == nil && stored != params.MainnetGenesisHash {
    75  		return block, nil
    76  	}
    77  
    78  	// Check config compatibility and write the config. Compatibility errors
    79  	// are returned to the caller unless we're already at block zero.
    80  	height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
    81  	if height == nil {
    82  		return nil, fmt.Errorf("missing block number for head header hash")
    83  	}
    84  	compatErr := storedcfg.CheckCompatible(newcfg, *height)
    85  	if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
    86  		return nil, compatErr
    87  	}
    88  	return block, err
    89  }
    90  
    91  // SetupGenesisBlock writes or updates the genesis block in db.
    92  // The block that will be used is:
    93  //
    94  //                          genesis == nil       genesis != nil
    95  //                       +------------------------------------------
    96  //     db has no genesis |  main-net default  |  genesis
    97  //     db has genesis    |  from DB           |  genesis (if compatible)
    98  //
    99  // The stored chain configuration will be updated if it is compatible (i.e. does not
   100  // specify a fork block below the local head block). In case of a conflict, the
   101  // error is a *params.ConfigCompatError and the new, unwritten config is returned.
   102  //
   103  // The returned chain configuration is never nil.
   104  func SetupGenesisBlockWithDefault(db intdb.Database, genesis *Genesis, isMainChain, isTestnet bool) (*params.ChainConfig, common.Hash, error) {
   105  	if genesis != nil && genesis.Config == nil {
   106  		return nil, common.Hash{}, errGenesisNoConfig
   107  	}
   108  
   109  	// Just commit the new block if there is no stored genesis block.
   110  	stored := rawdb.ReadCanonicalHash(db, 0)
   111  	if (stored == common.Hash{} && isMainChain) {
   112  		if genesis == nil {
   113  			log.Info("Writing default main-net genesis block")
   114  			if isTestnet {
   115  				genesis = DefaultGenesisBlockFromJson(DefaultTestnetGenesisJSON)
   116  			} else {
   117  				genesis = DefaultGenesisBlockFromJson(DefaultMainnetGenesisJSON)
   118  			}
   119  		} else {
   120  			log.Info("Writing custom genesis block")
   121  		}
   122  		block, err := genesis.Commit(db)
   123  		return genesis.Config, block.Hash(), err
   124  	}
   125  
   126  	// Check whether the genesis block is already written.
   127  	if genesis != nil {
   128  		hash := genesis.ToBlock(nil).Hash()
   129  		if hash != stored {
   130  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   131  		}
   132  	}
   133  
   134  	// Get the existing chain configuration.
   135  	newcfg := genesis.configOrDefault(stored)
   136  	storedcfg := rawdb.ReadChainConfig(db, stored)
   137  	if storedcfg == nil {
   138  		log.Warn("Found genesis block without chain config")
   139  		rawdb.WriteChainConfig(db, stored, newcfg)
   140  		return newcfg, stored, nil
   141  	}
   142  	// Special case: don't change the existing config of a non-mainnet chain if no new
   143  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   144  	// if we just continued here.
   145  	if genesis == nil && stored != params.MainnetGenesisHash {
   146  		return storedcfg, stored, nil
   147  	}
   148  
   149  	// Check config compatibility and write the config. Compatibility errors
   150  	// are returned to the caller unless we're already at block zero.
   151  	height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
   152  	if height == nil {
   153  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   154  	}
   155  	compatErr := storedcfg.CheckCompatible(newcfg, *height)
   156  	if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
   157  		return newcfg, stored, compatErr
   158  	}
   159  	rawdb.WriteChainConfig(db, stored, newcfg)
   160  	return newcfg, stored, nil
   161  }
   162  
   163  // DefaultGenesisBlock returns the INT Chain main net genesis block.
   164  func DefaultGenesisBlockFromJson(genesisJson string) *Genesis {
   165  
   166  	var genesis = Genesis{}
   167  
   168  	if err := json.Unmarshal([]byte(genesisJson), &genesis); err != nil {
   169  		return nil
   170  	}
   171  
   172  	return &genesis
   173  }
   174  
   175  var DefaultMainnetGenesisJSON = `{
   176  	"config": {
   177  		"intChainId": "intchain",
   178  		"chainId": 2047,
   179  		"homesteadBlock": 0,
   180  		"eip150Block": 0,
   181  		"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   182  		"eip155Block": 0,
   183  		"eip158Block": 0,
   184  		"byzantiumBlock": 0,
   185  		"constantinopleBlock": 0,
   186  		"petersburgBlock": 0,
   187  		"istanbulBlock": 0,
   188  		"ipbft": {
   189  			"epoch": 30000,
   190  			"policy": 0
   191  		}
   192  	},
   193  	"nonce": "0x0",
   194  	"timestamp": "0x611cde5c",
   195  	"extraData": "0x",
   196  	"gasLimit": "0x5f5e100",
   197  	"difficulty": "0x1",
   198  	"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   199  	"coinbase": "0x0000000000000000000000000000000000000000",
   200  	"alloc": {
   201  		"e00026f798c36ed24cc946474f92494de800c6c9": {
   202  			"balance": "0x2e7a2a7a739a67c63000000",
   203  			"amount": "0xd3c21bcecceda1000000"
   204  		}
   205  	},
   206  	"number": "0x0",
   207  	"gasUsed": "0x0",
   208  	"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
   209  }`
   210  
   211  var DefaultTestnetGenesisJSON = `{
   212  	"config": {
   213  		"intChainId": "testnet",
   214  		"chainId": 2048,
   215  		"homesteadBlock": 0,
   216  		"eip150Block": 0,
   217  		"eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   218  		"eip155Block": 0,
   219  		"eip158Block": 0,
   220  		"byzantiumBlock": 0,
   221  		"constantinopleBlock": 0,
   222  		"petersburgBlock": 0,
   223  		"istanbulBlock": 0,
   224  		"ipbft": {
   225  			"epoch": 30000,
   226  			"policy": 0
   227  		}
   228  	},
   229  	"nonce": "0x0",
   230  	"timestamp": "0x6119cecb",
   231  	"extraData": "0x",
   232  	"gasLimit": "0x5f5e100",
   233  	"difficulty": "0x1",
   234  	"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   235  	"coinbase": "0x0000000000000000000000000000000000000000",
   236  	"alloc": {
   237  		"0d3a15f869e4c50d59154ad1bc1b11702673b394": {
   238  			"balance": "0x2e7a2a7a739a67c63000000",
   239  			"amount": "0xd3c21bcecceda1000000"
   240  		}
   241  	},
   242  	"number": "0x0",
   243  	"gasUsed": "0x0",
   244  	"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
   245  }
   246  `