github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/checkpoints/checkpoints.go (about) 1 // Copyright 2017-2018 DERO Project. All rights reserved. 2 // Use of this source code in any form is governed by RESEARCH license. 3 // license can be found in the LICENSE file. 4 // GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8 5 // 6 // 7 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 8 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 9 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 10 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 11 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 12 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 13 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 14 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 15 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 17 package checkpoints 18 19 // generate checksums automatically from file mainnet_checksums.dat 20 21 // generate blank file if no testnet checkpoints 22 //go:generate sh -c "echo package checkpoints > testnet_checksums.go" 23 //go:generate sh -c "if [ ! -s testnet_checksums.dat ]; then echo var testnet_checksums_base64 = \"\" >> testnet_checksums.go; fi;" 24 //go:generate sh -c " if [ -s testnet_checksums.dat ]; then echo var testnet_checksums_base64 = \\\x60 >> testnet_checksums.go; fi" 25 //go:generate sh -c "if [ -s testnet_checksums.dat ]; then base64 -w 80 < testnet_checksums.dat >> testnet_checksums.go;fi" 26 //go:generate sh -c "if [ -s testnet_checksums.dat ]; then echo \\\x60 >> testnet_checksums.go;fi " 27 28 //go:generate sh -c "echo // Code generated by go generate DO NOT EDIT. > mainnet_checksums.go" 29 //go:generate sh -c "echo // This file contains all the mainnet checksums > mainnet_checksums.go" 30 //go:generate sh -c "echo // please read checkpoints.go comments > mainnet_checksums.go" 31 //go:generate sh -c "echo package checkpoints >> mainnet_checksums.go" 32 //go:generate sh -c "echo >> mainnet_checksums.go" 33 //go:generate sh -c "echo var mainnet_checksums_base64 = \\\x60 >> mainnet_checksums.go" 34 //go:generate sh -c "base64 -w 80 < mainnet_checksums.dat >> mainnet_checksums.go" 35 //go:generate sh -c "echo \\\x60 >> mainnet_checksums.go" 36 37 import "fmt" 38 39 //import "bytes" 40 import "io/ioutil" 41 import "path/filepath" 42 import "encoding/base64" 43 44 import "github.com/romana/rlog" 45 import log "github.com/sirupsen/logrus" 46 import "github.com/armon/go-radix" 47 48 //import "github.com/deroproject/derosuite/crypto" 49 import "github.com/deroproject/derosuite/globals" 50 51 // this file handles and maintains checkpoints which are used by blockchain to skip some checks on known parts of the chain 52 // the skipping of the checks can be disabled by command line arguments 53 54 //var mainnet_checkpoints_height uint64 = uint64(len(mainnet_checkpoints) / 32) // each checkpoint is 32 bytes in size 55 //var testnet_checkpoints_height uint64 = uint64(len(testnet_checkpoints) / 32) // each checkpoint is 32 bytes in size 56 57 var mainnet_checksums_height uint64 = uint64(len(mainnet_checksums) / 32) // each checksum is 32 bytes in size 58 var testnet_checksums_height uint64 = uint64(len(testnet_checksums) / 32) // each checksum is 32 bytes in size 59 60 var checksum_tree *radix.Tree 61 62 func init() { 63 // rlog.Tracef(1, "Loaded %d checkpoints for mainnet hardcoded", mainnet_checkpoints_height) 64 // rlog.Tracef(1, "Loaded %d checkpoints for testnet hardcoded", testnet_checkpoints_height) 65 66 rlog.Tracef(1, "Loaded %d checksums for mainnet hardcoded", mainnet_checksums_height) 67 rlog.Tracef(1, "Loaded %d checksums for testnet hardcoded", mainnet_checksums_height) 68 checksum_tree = radix.New() 69 } 70 71 var mainnet_checksums = load_base64(mainnet_checksums_base64) 72 var testnet_checksums = load_base64(testnet_checksums_base64) 73 74 func load_base64(input string) []byte { 75 76 data, err := base64.StdEncoding.DecodeString(input) 77 if err != nil { 78 rlog.Tracef(1, "Loaded checksums failed base64 decoding input length %d", len(input)) 79 } 80 81 return data 82 83 } 84 85 // load checkpoints from the data directory 86 // a line should be printed on console when we are doing this 87 func LoadCheckPoints(logger *log.Entry) { 88 /* 89 if globals.IsMainnet() { // load mainnet checkpoints 90 data_loaded, err := ioutil.ReadFile(filepath.Join(globals.GetDataDirectory(), "mainnet_checkpoints.dat")) 91 if err == nil && uint64(len(data_loaded)%32) == 0 { 92 mainnet_checkpoints = data_loaded 93 mainnet_checkpoints_height = uint64(len(mainnet_checkpoints) / 32) 94 rlog.Tracef(1, "Loaded %d checkpoints for mainnet from file mainnet_checkpoints.dat", mainnet_checkpoints_height) 95 logger.Infof("Loaded %d checkpoints for mainnet from file mainnet_checkpoints.dat", mainnet_checkpoints_height) 96 } else { 97 rlog.Warnf("Loading checkpoints for mainnet from file mainnet_checkpoints.dat failed err %s len %d", err, uint64(len(mainnet_checkpoints))) 98 if len(data_loaded) > 0 { 99 logger.Warnf("Loading checkpoints for mainnet from file mainnet_checkpoints.dat failed err %s len %d", err, uint64(len(mainnet_checkpoints))) 100 } 101 } 102 } 103 104 if !globals.IsMainnet() { // load testnet checkpoints 105 data_loaded, err := ioutil.ReadFile(filepath.Join(globals.GetDataDirectory(), "testnet_checkpoints.dat")) 106 if err == nil && uint64(len(data_loaded)%32) == 0 { 107 testnet_checkpoints = data_loaded 108 testnet_checkpoints_height = uint64(len(testnet_checkpoints) / 32) 109 rlog.Tracef(1, "Loaded %d checkpoints for testnet from file testnet_checkpoints.dat", testnet_checkpoints_height) 110 logger.Info(1, "Loaded %d checkpoints for testnet from file testnet_checkpoints.dat", testnet_checkpoints_height) 111 } else { 112 rlog.Warnf("Loading checkpoints for testnet from file testnet_checkpoints.dat failed err %s len %d", err, uint64(len(testnet_checkpoints))) 113 if len(data_loaded) > 0 { 114 logger.Warnf("Loading checkpoints for testnet from file testnet_checkpoints.dat failed err %s len %d", err, uint64(len(testnet_checkpoints))) 115 } 116 } 117 } 118 */ 119 if globals.IsMainnet() { // load mainnet checksum 120 data_loaded, err := ioutil.ReadFile(filepath.Join(globals.GetDataDirectory(), "mainnet_checksums.dat")) 121 if err == nil && uint64(len(data_loaded)%32) == 0 { 122 mainnet_checksums = data_loaded 123 mainnet_checksums_height = uint64(len(mainnet_checksums) / 32) 124 rlog.Tracef(1, "Loaded %d checksums for mainnet from file mainnet_checksum.dat", mainnet_checksums_height) 125 logger.Infof("Loaded %d checksums for mainnet from file mainnet_checksum.dat", mainnet_checksums_height) 126 } else { 127 rlog.Warnf("Loading checksums for mainnet from file mainnet_checksum.dat failed err %s len %d", err, uint64(len(mainnet_checksums))) 128 if len(data_loaded) > 0 { 129 logger.Warnf("Loading checksums for mainnet from file mainnet_checksum.dat failed err %s len %d", err, uint64(len(mainnet_checksums))) 130 } 131 } 132 } 133 134 if !globals.IsMainnet() { // load testnet checksum 135 data_loaded, err := ioutil.ReadFile(filepath.Join(globals.GetDataDirectory(), "testnet_checksums.dat")) 136 if err == nil && uint64(len(data_loaded)%32) == 0 { 137 testnet_checksums = data_loaded 138 testnet_checksums_height = uint64(len(testnet_checksums) / 32) 139 rlog.Tracef(1, "Loaded %d checksums for testnet from file testnet_checksum.dat", testnet_checksums_height) 140 logger.Infof("Loaded %d checksums for testnet from file testnet_checksum.dat", testnet_checksums_height) 141 } else { 142 rlog.Warnf("Loading checksums for testnet from file testnet_checksums.dat failed err %s len %d", err, uint64(len(testnet_checksums))) 143 if len(data_loaded) > 0 { 144 logger.Warnf("Loading checksums for testnet from file testnet_checksums.dat failed err %s len %d", err, uint64(len(testnet_checksums))) 145 } 146 } 147 } 148 149 // lets build a trie for checksums for faster lookup 150 checksum_tree = radix.New() 151 if globals.IsMainnet() { 152 for i := uint64(0); i < mainnet_checksums_height; i++ { 153 checksum_tree.Insert(string(mainnet_checksums[32*i:32*(i+1)]), nil) 154 } 155 } else { 156 for i := uint64(0); i < testnet_checksums_height; i++ { 157 checksum_tree.Insert(string(testnet_checksums[32*i:32*(i+1)]), nil) 158 } 159 } 160 161 logger.Debugf("Succesfully built checksum tree count %d", checksum_tree.Len()) 162 163 } 164 165 /* 166 // gives length of currently available checkpoints 167 func Length() uint64 { 168 switch globals.Config.Name { 169 case "mainnet": 170 return mainnet_checkpoints_height 171 case "testnet": 172 return testnet_checkpoints_height 173 default: 174 return 0 175 } 176 177 // we can never reach here 178 //return 0 179 } 180 */ 181 func ChecksumLength() uint64 { 182 switch globals.Config.Name { 183 case "mainnet": 184 return mainnet_checksums_height 185 case "testnet": 186 return testnet_checksums_height // no checksums for testnet 187 default: 188 return 0 189 } 190 191 // we can never reach here 192 //return 0 193 } 194 195 /* 196 // tell whether a checkpoint is known in the current selected network 197 func IsCheckPointKnown(hash crypto.Hash, height uint64) (result bool) { 198 199 var known_hash crypto.Hash 200 201 switch globals.Config.Name { 202 case "mainnet": 203 if height < mainnet_checkpoints_height { 204 copy(known_hash[:], mainnet_checkpoints[32*height:]) 205 if known_hash == hash { 206 result = true 207 return 208 } 209 } 210 211 case "testnet": 212 if height < testnet_checkpoints_height { 213 copy(known_hash[:], testnet_checkpoints[32*height:]) 214 if known_hash == hash { 215 result = true 216 return 217 } 218 } 219 220 default: 221 panic(fmt.Sprintf("Unknown Network \"%s\"", globals.Config.Name)) 222 } 223 return 224 } 225 226 */ 227 // tell whether a checkpoint is known in the current selected network 228 func IsCheckSumKnown(hash []byte) (result bool) { 229 switch globals.Config.Name { 230 case "mainnet": 231 if _, ok := checksum_tree.Get(string(hash)); ok { 232 return true 233 } 234 235 case "testnet": 236 if _, ok := checksum_tree.Get(string(hash)); ok { 237 return true 238 } 239 return false 240 241 default: 242 panic(fmt.Sprintf("Unknown Network \"%s\"", globals.Config.Name)) 243 } 244 return 245 }