github.com/FUSIONFoundation/efsn@v3.6.2-0.20200916075423-dbb5dd5d2cc7+incompatible/consensus/datong/checkpoints.go (about)

     1  package datong
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"math/big"
     8  
     9  	"github.com/FusionFoundation/efsn/common"
    10  	"github.com/FusionFoundation/efsn/core/types"
    11  	"github.com/FusionFoundation/efsn/log"
    12  	"github.com/FusionFoundation/efsn/params"
    13  )
    14  
    15  var (
    16  	// hard coded check points
    17  	mainnetCheckPoints = map[uint64]common.Hash{
    18  		10000:   common.HexToHash("0x1830e440e17cda3a26d02ea650331a584d58a499cbbd3821c622568c8de9b470"),
    19  		100000:  common.HexToHash("0x0e4a4045c06984472f86bb8f1e40bb70dee87b6227877ffcaeab7624db745cd2"),
    20  		500000:  common.HexToHash("0xad25bc52b8e674494970aa3a1bb7e775564714cbc4798975730ad1b9c62ccc89"),
    21  		739500:  common.HexToHash("0xa64a4ecee941a7710d2942ac7e1b69e7ba6431ab38d82e6771ede7051bafee8f"),
    22  		1000000: common.HexToHash("0x4b0d0d5a0739c801c3d4fe91258d3b9ddf81f471464e221921442ea503d711a6"),
    23  		1500000: common.HexToHash("0x2808c2f24aa2280453e257970a9cf05ef9a4cf5c1a742a9a466a633aff45400a"),
    24  		1700000: common.HexToHash("0x39a997b94b24a050a3b222cd89427cdffedc8706a24160e6bab06ffa95f1c7fa"),
    25  		2680000: common.HexToHash("0x4c49d0119abea53f5cb0ba6107bf481670397e8b814fa4360353eedded9bf383"),
    26  	}
    27  	mainnetLastCheckPoint uint64 = 2680000
    28  
    29  	testnetCheckPoints = map[uint64]common.Hash{
    30  		10000:   common.HexToHash("0x26a9441584f9b312e9e42df099e5b72f06e71a6335a31b65eba48782b506af5f"),
    31  		100000:  common.HexToHash("0xfcdd0b71de9b84bf635a5b30ae4b6f483ccd49fa0c9780f49bfae030a6bc2064"),
    32  		500000:  common.HexToHash("0x710920258a903b3af92f8ac4f1cd66784cb001efa3b1c2ab4a178479ce8bdfe8"),
    33  		534500:  common.HexToHash("0xe8049f5930c8e5ebf3d79b9de9eb267666afb8225e797d24010abc2341b264b5"),
    34  		1000000: common.HexToHash("0x6165f4fd79216afc5ef3f15e01e42aff9d1f252d1b7baa4395aabeeb89368615"),
    35  		1500000: common.HexToHash("0xd984e123d3a16f754faf77b4d18afc532a9101b7a3b4cf20cd374d376223d1a5"),
    36  		1577000: common.HexToHash("0xeeec5e5781ef697e5b181bc5da8c90fe6c80624e235bbe331e19da62766e1345"),
    37  		2621077: common.HexToHash("0xada50d3c256310c2eb41127ebbb426673b6b12d7c89b5f51f973cb4c944c302c"),
    38  	}
    39  	testnetLastCheckPoint uint64 = 2621077
    40  
    41  	devnetCheckPoints           = map[uint64]common.Hash{}
    42  	devnetLastCheckPoint uint64 = 0
    43  )
    44  
    45  var (
    46  	CheckPoints    map[uint64]common.Hash
    47  	LastCheckPoint uint64
    48  )
    49  
    50  func InitCheckPoints(file string) {
    51  	if common.UseTestnetRule {
    52  		CheckPoints = testnetCheckPoints
    53  		LastCheckPoint = testnetLastCheckPoint
    54  	} else if common.UseDevnetRule {
    55  		CheckPoints = devnetCheckPoints
    56  		LastCheckPoint = devnetLastCheckPoint
    57  	} else {
    58  		CheckPoints = mainnetCheckPoints
    59  		LastCheckPoint = mainnetLastCheckPoint
    60  	}
    61  
    62  	defer func() {
    63  		log.Info("InitCheckPoints finished", "count", len(CheckPoints), "last", LastCheckPoint)
    64  	}()
    65  
    66  	// custom check points
    67  	if file == "" {
    68  		return
    69  	}
    70  	data, err := ioutil.ReadFile(file)
    71  	if err != nil {
    72  		log.Error("Could not read check ponits file", "err", err)
    73  		return
    74  	}
    75  	var cpoints map[uint64]string
    76  	if err := json.Unmarshal(data, &cpoints); err != nil {
    77  		log.Error("InitCheckPoints unmarshal json failed", "err", err)
    78  		return
    79  	}
    80  	for k, v := range cpoints {
    81  		CheckPoints[k] = common.HexToHash(v)
    82  		if k > LastCheckPoint {
    83  			LastCheckPoint = k
    84  		}
    85  	}
    86  }
    87  
    88  func IsInCheckPointsRange(blockHeight uint64) bool {
    89  	return blockHeight <= LastCheckPoint
    90  }
    91  
    92  func CheckPoint(chainID *big.Int, blockHeight uint64, blockHash common.Hash) (isInRange bool, err error) {
    93  	var defaultChainID *big.Int
    94  	switch {
    95  	case common.UseTestnetRule:
    96  		defaultChainID = params.DevnetChainConfig.ChainID
    97  	case common.UseDevnetRule:
    98  		defaultChainID = params.TestnetChainConfig.ChainID
    99  	default: // maininet
   100  		defaultChainID = params.MainnetChainConfig.ChainID
   101  	}
   102  	// private chain
   103  	if chainID == nil || chainID.Cmp(defaultChainID) != 0 {
   104  		return false, nil
   105  	}
   106  	if blockHeight > LastCheckPoint {
   107  		return false, nil
   108  	}
   109  	hash, exist := CheckPoints[blockHeight]
   110  	if exist {
   111  		if blockHash != hash {
   112  			log.Info("check point failed, block hash mismatch", "number", blockHeight, "have", blockHash, "want", hash)
   113  			return true, fmt.Errorf("check point failed, block hash mismatch: number=%v, have 0x%x, want 0x%x", blockHeight, blockHash, hash)
   114  		} else {
   115  			log.Info("check point passed", "number", blockHeight, "hash", blockHash)
   116  		}
   117  	}
   118  	return true, nil
   119  }
   120  
   121  func CheckPointsInBlockChain(chainID *big.Int, chain types.Blocks) (int, error) {
   122  	headers := make([]*types.Header, len(chain))
   123  	for i, block := range chain {
   124  		headers[i] = block.Header()
   125  	}
   126  	return CheckPointsInHeaderChain(chainID, headers)
   127  }
   128  
   129  func CheckPointsInHeaderChain(chainID *big.Int, chain []*types.Header) (int, error) {
   130  	var defaultChainID *big.Int
   131  	switch {
   132  	case common.UseTestnetRule:
   133  		defaultChainID = params.DevnetChainConfig.ChainID
   134  	case common.UseDevnetRule:
   135  		defaultChainID = params.TestnetChainConfig.ChainID
   136  	default: // maininet
   137  		defaultChainID = params.MainnetChainConfig.ChainID
   138  	}
   139  	// private chain
   140  	if chainID == nil || chainID.Cmp(defaultChainID) != 0 {
   141  		return 0, nil
   142  	}
   143  	for i, header := range chain {
   144  		blockHeight := header.Number.Uint64()
   145  		if blockHeight > LastCheckPoint {
   146  			break
   147  		}
   148  		hash, exist := CheckPoints[blockHeight]
   149  		if !exist {
   150  			continue
   151  		}
   152  		blockHash := header.Hash()
   153  		if blockHash != hash {
   154  			log.Info("check point failed, block hash mismatch", "number", blockHeight, "have", blockHash, "want", hash)
   155  			return i, fmt.Errorf("check point failed, block hash mismatch: number=%v, have 0x%x, want 0x%x", blockHeight, blockHash, hash)
   156  		} else {
   157  			log.Info("check point passed", "number", blockHeight, "hash", blockHash)
   158  		}
   159  	}
   160  	return 0, nil
   161  }