github.com/Gessiux/neatchain@v1.3.1/chain/core/genesis1.go (about)

     1  package core
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  
     9  	"github.com/Gessiux/neatchain/chain/core/rawdb"
    10  	"github.com/Gessiux/neatchain/chain/core/types"
    11  	"github.com/Gessiux/neatchain/chain/log"
    12  	"github.com/Gessiux/neatchain/neatdb"
    13  	"github.com/Gessiux/neatchain/params"
    14  	"github.com/Gessiux/neatchain/utilities/common"
    15  )
    16  
    17  // WriteGenesisBlock writes the genesis block to the database as block number 0
    18  //func WriteGenesisBlock(chainDb neatdb.Database, reader io.Reader) (*types.Block, error) {
    19  //	contents, err := ioutil.ReadAll(reader)
    20  //	if err != nil {
    21  //		return nil, err
    22  //	}
    23  //
    24  //	var genesis = Genesis{}
    25  //
    26  //	if err := json.Unmarshal(contents, &genesis); err != nil {
    27  //		return nil, err
    28  //	}
    29  //
    30  //	return SetupGenesisBlockEx(chainDb, &genesis)
    31  //}
    32  
    33  func WriteGenesisBlock(chainDb neatdb.Database, reader io.Reader) (*types.Block, error) {
    34  	contents, err := ioutil.ReadAll(reader)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  
    39  	var (
    40  		genesis  Genesis
    41  		genesisW GenesisWrite
    42  	)
    43  
    44  	genesis.Alloc = GenesisAlloc{}
    45  
    46  	if err := json.Unmarshal(contents, &genesisW); err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	genesis = Genesis{
    51  		Config:     genesisW.Config,
    52  		Nonce:      genesisW.Nonce,
    53  		Timestamp:  genesisW.Timestamp,
    54  		ParentHash: genesisW.ParentHash,
    55  		ExtraData:  genesisW.ExtraData,
    56  		GasLimit:   genesisW.GasLimit,
    57  		Difficulty: genesisW.Difficulty,
    58  		Mixhash:    genesisW.Mixhash,
    59  		Coinbase:   common.StringToAddress(genesisW.Coinbase),
    60  		Alloc:      GenesisAlloc{},
    61  	}
    62  
    63  	for k, v := range genesisW.Alloc {
    64  		genesis.Alloc[common.StringToAddress(k)] = v
    65  	}
    66  
    67  	return SetupGenesisBlockEx(chainDb, &genesis)
    68  }
    69  
    70  func SetupGenesisBlockEx(db neatdb.Database, genesis *Genesis) (*types.Block, error) {
    71  
    72  	if genesis != nil && genesis.Config == nil {
    73  		return nil, errGenesisNoConfig
    74  	}
    75  
    76  	var block *types.Block = nil
    77  	var err error = nil
    78  
    79  	// Just commit the new block if there is no stored genesis block.
    80  	stored := rawdb.ReadCanonicalHash(db, 0)
    81  	if (stored == common.Hash{}) {
    82  		if genesis == nil {
    83  			log.Info("Writing default main-net genesis block")
    84  			genesis = DefaultGenesisBlock()
    85  		} else {
    86  			log.Info("Writing custom genesis block")
    87  		}
    88  		block, err = genesis.Commit(db)
    89  		return block, err
    90  	}
    91  
    92  	// Check whether the genesis block is already written.
    93  	if genesis != nil {
    94  		block = genesis.ToBlock(nil)
    95  		hash := block.Hash()
    96  		if hash != stored {
    97  			return nil, &GenesisMismatchError{stored, hash}
    98  		}
    99  	}
   100  
   101  	// Get the existing chain configuration.
   102  	newcfg := genesis.configOrDefault(stored)
   103  	storedcfg := rawdb.ReadChainConfig(db, stored)
   104  	if storedcfg == nil {
   105  		log.Warn("Found genesis block without chain config")
   106  		rawdb.WriteChainConfig(db, stored, newcfg)
   107  		return block, err
   108  	}
   109  	// Special case: don't change the existing config of a non-mainnet chain if no new
   110  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   111  	// if we just continued here.
   112  	if genesis == nil && stored != params.MainnetGenesisHash {
   113  		return block, nil
   114  	}
   115  
   116  	// Check config compatibility and write the config. Compatibility errors
   117  	// are returned to the caller unless we're already at block zero.
   118  	height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
   119  	if height == nil {
   120  		return nil, fmt.Errorf("missing block number for head header hash")
   121  	}
   122  	compatErr := storedcfg.CheckCompatible(newcfg, *height)
   123  	if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
   124  		return nil, compatErr
   125  	}
   126  	return block, err
   127  }
   128  
   129  // SetupGenesisBlock writes or updates the genesis block in db.
   130  // The block that will be used is:
   131  //
   132  //                          genesis == nil       genesis != nil
   133  //                       +------------------------------------------
   134  //     db has no genesis |  main-net default  |  genesis
   135  //     db has genesis    |  from DB           |  genesis (if compatible)
   136  //
   137  // The stored chain configuration will be updated if it is compatible (i.e. does not
   138  // specify a fork block below the local head block). In case of a conflict, the
   139  // error is a *params.ConfigCompatError and the new, unwritten config is returned.
   140  //
   141  // The returned chain configuration is never nil.
   142  func SetupGenesisBlockWithDefault(db neatdb.Database, genesis *Genesis, isMainChain, isTestnet bool) (*params.ChainConfig, common.Hash, error) {
   143  	if genesis != nil && genesis.Config == nil {
   144  		//fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 1\n")
   145  		return nil, common.Hash{}, errGenesisNoConfig
   146  	}
   147  
   148  	// Just commit the new block if there is no stored genesis block.
   149  	stored := rawdb.ReadCanonicalHash(db, 0)
   150  	if (stored == common.Hash{} && isMainChain) {
   151  		if genesis == nil {
   152  			log.Info("Writing default main-net genesis block")
   153  			if isTestnet {
   154  				genesis = DefaultGenesisBlockFromJson(DefaultTestnetGenesisJSON)
   155  			} else {
   156  				genesis = DefaultGenesisBlockFromJson(DefaultMainnetGenesisJSON)
   157  			}
   158  		} else {
   159  			log.Info("Writing custom genesis block")
   160  		}
   161  		block, err := genesis.Commit(db)
   162  		//fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 2\n")
   163  		return genesis.Config, block.Hash(), err
   164  	}
   165  
   166  	// Check whether the genesis block is already written.
   167  	if genesis != nil {
   168  		hash := genesis.ToBlock(nil).Hash()
   169  		if hash != stored {
   170  			//fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 3\n")
   171  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   172  		}
   173  	}
   174  
   175  	// Get the existing chain configuration.
   176  	newcfg := genesis.configOrDefault(stored)
   177  	storedcfg := rawdb.ReadChainConfig(db, stored)
   178  	if storedcfg == nil {
   179  		log.Warn("Found genesis block without chain config")
   180  		rawdb.WriteChainConfig(db, stored, newcfg)
   181  		//fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 4\n")
   182  		return newcfg, stored, nil
   183  	}
   184  	// Special case: don't change the existing config of a non-mainnet chain if no new
   185  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   186  	// if we just continued here.
   187  	if genesis == nil && stored != params.MainnetGenesisHash {
   188  		//fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 5\n")
   189  		return storedcfg, stored, nil
   190  	}
   191  
   192  	// Check config compatibility and write the config. Compatibility errors
   193  	// are returned to the caller unless we're already at block zero.
   194  	height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
   195  	if height == nil {
   196  		//fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 6\n")
   197  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   198  	}
   199  	compatErr := storedcfg.CheckCompatible(newcfg, *height)
   200  	if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
   201  		//fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 7\n")
   202  		return newcfg, stored, compatErr
   203  	}
   204  	rawdb.WriteChainConfig(db, stored, newcfg)
   205  	//fmt.Printf("core genesis1 SetupGenesisBlockWithDefault 8\n")
   206  	return newcfg, stored, nil
   207  }
   208  
   209  // DefaultGenesisBlock returns the Ethereum main net genesis block.
   210  func DefaultGenesisBlockFromJson(genesisJson string) *Genesis {
   211  
   212  	var (
   213  		genesis  Genesis
   214  		genesisW GenesisWrite
   215  	)
   216  
   217  	genesis.Alloc = GenesisAlloc{}
   218  	if err := json.Unmarshal([]byte(genesisJson), &genesisW); err != nil {
   219  		return nil
   220  	}
   221  
   222  	genesis = Genesis{
   223  		Config:     genesisW.Config,
   224  		Nonce:      genesisW.Nonce,
   225  		Timestamp:  genesisW.Timestamp,
   226  		ParentHash: genesisW.ParentHash,
   227  		ExtraData:  genesisW.ExtraData,
   228  		GasLimit:   genesisW.GasLimit,
   229  		Difficulty: genesisW.Difficulty,
   230  		Mixhash:    genesisW.Mixhash,
   231  		Coinbase:   common.StringToAddress(genesisW.Coinbase),
   232  		Alloc:      GenesisAlloc{},
   233  	}
   234  
   235  	for i, v := range genesisW.Alloc {
   236  		genesis.Alloc[common.StringToAddress(i)] = v
   237  	}
   238  
   239  	return &genesis
   240  }
   241  
   242  var DefaultMainnetGenesisJSON = `{
   243  	"config": {
   244  		"NeatChainId": "neatchain",
   245  		"chainId": 1,
   246  		"homesteadBlock": 0,
   247  		"eip150Block": 0,
   248  		"eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
   249  		"eip155Block": 0,
   250  		"eip158Block": 0,
   251  		"byzantiumBlock": 0,
   252  		"neatcon": {
   253  			"epoch": 30000,
   254  			"policy": 0
   255  		}
   256  	},
   257  	"nonce": "0xdeadbeefdeadbeef",
   258  	"timestamp": "0x610055f7",
   259  	"extraData": "0x",
   260  	"gasLimit": "0x7270e00",
   261  	"difficulty": "0x1",
   262  	"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   263  	"coinbase": "NEATAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
   264  	"alloc": {
   265  		"NEATbNkySqxehp2vT1AmPhNqoMTciv1B": {
   266  			"balance": "0x33b2e3c9fd0803ce8000000",
   267  			"amount": "0x152d02c7e14af6800000"
   268  		}
   269  	},
   270  	"number": "0x0",
   271  	"gasUsed": "0x0",
   272  	"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
   273  }`
   274  
   275  var DefaultTestnetGenesisJSON = `{
   276  	"config": {
   277  		"NeatChainId": "testnet",
   278  		"chainId": 2,
   279  		"homesteadBlock": 0,
   280  		"eip150Block": 0,
   281  		"eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0",
   282  		"eip155Block": 0,
   283  		"eip158Block": 0,
   284  		"byzantiumBlock": 0,
   285  		"neatcon": {
   286  			"epoch": 30000,
   287  			"policy": 0
   288  		}
   289  	},
   290  	"nonce": "0xdeadbeefdeadbeef",
   291  	"timestamp": "0x5fa278cc",
   292  	"extraData": "0x",
   293  	"gasLimit": "0x7270e00",
   294  	"difficulty": "0x1",
   295  	"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
   296  	"coinbase": "NEATAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
   297  	"alloc": {
   298  		"NEATcfoFiNW3i5pBxPpjSs6m1YJzjQMU": {
   299  			"balance": "0x29569e2db20e16b46000000",
   300  			"amount": "0x54b40b1f852bda000000"
   301  		}
   302  	},
   303  	"number": "0x0",
   304  	"gasUsed": "0x0",
   305  	"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
   306  }
   307  `