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 }