code.vegaprotocol.io/vega@v0.79.0/vegatools/checkpoint/parse.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package checkpoint 17 18 import ( 19 "errors" 20 "fmt" 21 "log" 22 "os" 23 24 "code.vegaprotocol.io/vega/libs/proto" 25 checkpoint "code.vegaprotocol.io/vega/protos/vega/checkpoint/v1" 26 27 "google.golang.org/protobuf/reflect/protoreflect" 28 ) 29 30 var ( 31 // ErrCheckpointFileEmpty obviously means the checkpoint file was empty. 32 ErrCheckpointFileEmpty = errors.New("given checkpoint file is empty or unreadable") 33 // ErrMissingOutFile no output file name argument provided. 34 ErrMissingOutFile = errors.New("output file not specified") 35 ) 36 37 // Run ... the main entry point of the command. 38 func Run(inFile, outFile string, generate, validate, dummy bool) error { 39 if generate && outFile == "" { 40 fmt.Println("No output file specified") 41 return ErrMissingOutFile 42 } 43 // generate some files to play with 44 if dummy { 45 return generateDummy(inFile, outFile) 46 } 47 48 data, err := os.ReadFile(inFile) 49 if err != nil { 50 return err 51 } 52 53 fmt.Printf("Read %d bytes from %s\n", len(data), inFile) 54 55 if len(data) == 0 { 56 return ErrCheckpointFileEmpty 57 } 58 59 if generate { 60 return generateCheckpoint(data, outFile) 61 } 62 63 cp := &checkpoint.Checkpoint{} 64 if err = proto.Unmarshal(data, cp); err != nil { 65 return err 66 } 67 68 parsed, err := unmarshalAll(cp) 69 if err != nil { 70 return err 71 } 72 // print output at the end 73 defer func() { 74 printParsed(parsed, err != nil) 75 }() 76 77 if validate { 78 if err = parsed.CheckAssetsCollateral(); err != nil { 79 return err 80 } 81 } 82 83 return writeOut(parsed, outFile) 84 } 85 86 func generateDummy(cpF, jsonFName string) error { 87 d := dummy() 88 89 cp, h, err := d.CheckpointData() // get the data as checkpoint 90 if err != nil { 91 log.Printf("Could not convert dummy to checkpoint data to write to file: %+v\n", err) 92 return err 93 } 94 95 if err = writeCheckpoint(cp, h, cpF); err != nil { 96 log.Printf("Error writing checkpoint data to file '%s': %+v\n", cpF, err) 97 return err 98 } 99 100 if err = writeOut(d, jsonFName); err != nil { 101 log.Printf("Error writing JSON file '%s' from dummy: %+v\n", jsonFName, err) 102 return err 103 } 104 return nil 105 } 106 107 func generateCheckpoint(data []byte, outF string) error { 108 of, err := os.Create(outF) 109 if err != nil { 110 log.Printf("Failed to create output file %s: %+v\n", outF, err) 111 return err 112 } 113 114 defer func() { _ = of.Close() }() 115 116 a, err := fromJSON(data) 117 if err != nil { 118 log.Printf("Could not unmarshal input: %+v\n", err) 119 return err 120 } 121 122 out, h, err := a.CheckpointData() 123 if err != nil { 124 log.Printf("Could not generate checkpoint data: %+v\n", err) 125 return err 126 } 127 128 n, err := of.Write(out) 129 if err != nil { 130 log.Printf("Failed to write output to file: %+v\n", err) 131 return err 132 } 133 134 fmt.Printf("Successfully wrote %d bytes to file %s\n", n, outF) 135 fmt.Printf("hash for checkpoint is %s\n", h) 136 return nil 137 } 138 139 func writeCheckpoint(data []byte, h string, outF string) error { 140 of, err := os.Create(outF) 141 if err != nil { 142 fmt.Printf("Failed to create output file %s: %+v\n", outF, err) 143 return err 144 } 145 146 defer func() { _ = of.Close() }() 147 148 n, err := of.Write(data) 149 if err != nil { 150 fmt.Printf("Failed to write output to file '%s': %+v\n", outF, err) 151 return err 152 } 153 154 fmt.Printf("Successfully wrote %d bytes to file %s\n", n, outF) 155 fmt.Printf("Checkpoint hash is %s\n", h) 156 return nil 157 } 158 159 func printParsed(a *all, isErr bool) { 160 data, err := a.JSON() 161 if err != nil { 162 log.Printf("Failed to marshal data to JSON: %+v\n", err) 163 return 164 } 165 166 if isErr { 167 if _, err = os.Stderr.WriteString(string(data)); err == nil { 168 return 169 } 170 fmt.Printf("Could not write to stderr: %+v\n", err) 171 } 172 173 fmt.Printf("Output:\n%s\n", string(data)) 174 } 175 176 func writeOut(a *all, path string) error { 177 if path == "" { 178 return nil 179 } 180 181 data, err := a.JSON() 182 if err != nil { 183 return err 184 } 185 186 f, err := os.Create(path) 187 if err != nil { 188 return err 189 } 190 191 defer func() { _ = f.Close() }() 192 193 n, err := f.Write(data) 194 if err != nil { 195 return err 196 } 197 198 fmt.Printf("Wrote %d bytes to %s\n", n, path) 199 return nil 200 } 201 202 func unmarshalAll(cp *checkpoint.Checkpoint) (ret *all, err error) { 203 ret = newAll() 204 205 cp.ProtoReflect().Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { 206 name := string(fd.Name()) 207 msg, ok := ret.messages[name] 208 if ok { 209 if err = proto.Unmarshal(v.Bytes(), msg); err != nil { 210 return false 211 } 212 } 213 return true 214 }) 215 216 return ret, err 217 }