@@ -20,6 +20,7 @@ import (
2020 "context"
2121 "fmt"
2222 "io"
23+ "io/ioutil"
2324 "net/http"
2425 "os"
2526 "strconv"
@@ -29,10 +30,13 @@ import (
2930 "github.com/spf13/cobra"
3031
3132 "github.com/algorand/go-algorand/config"
33+ "github.com/algorand/go-algorand/data/bookkeeping"
3234 "github.com/algorand/go-algorand/ledger"
3335 "github.com/algorand/go-algorand/ledger/ledgercore"
3436 "github.com/algorand/go-algorand/logging"
3537 "github.com/algorand/go-algorand/network"
38+ "github.com/algorand/go-algorand/protocol"
39+ "github.com/algorand/go-algorand/rpcs"
3640 tools "github.com/algorand/go-algorand/tools/network"
3741 "github.com/algorand/go-algorand/util"
3842)
@@ -81,12 +85,19 @@ var netCmd = &cobra.Command{
8185 }
8286
8387 for _ , addr := range addrs {
84- tarName , err := downloadCatchpoint (addr , round )
88+ tarName , proto , err := downloadCatchpoint (addr , round )
8589 if err != nil {
8690 reportInfof ("failed to download catchpoint from '%s' : %v" , addr , err )
8791 continue
8892 }
89- err = makeFileDump (addr , tarName )
93+ genesisInitState := ledgercore.InitState {
94+ Block : bookkeeping.Block {BlockHeader : bookkeeping.BlockHeader {
95+ UpgradeState : bookkeeping.UpgradeState {
96+ CurrentProtocol : proto ,
97+ },
98+ }},
99+ }
100+ err = makeFileDump (addr , tarName , genesisInitState )
90101 if err != nil {
91102 reportInfof ("failed to make a dump from tar file for '%s' : %v" , addr , err )
92103 continue
@@ -147,36 +158,67 @@ func printDownloadProgressLine(progress int, barLength int, url string, dld int6
147158 fmt .Printf (escapeCursorUp + escapeDeleteLine + outString + " %s\n " , formatSize (dld ))
148159}
149160
150- func downloadCatchpoint (addr string , round int ) (tarName string , err error ) {
151- genesisID := strings .Split (networkName , "." )[0 ] + "-v1.0"
152- url := "http://" + addr + "/v1/" + genesisID + "/ledger/" + strconv .FormatUint (uint64 (round ), 36 )
153- fmt .Printf ("downloading from %s\n " , url )
161+ func getRemoteDataStream (url string , hint string ) (result io.ReadCloser , ctxCancel context.CancelFunc , err error ) {
162+ fmt .Printf ("downloading %s from %s\n " , hint , url )
154163 request , err := http .NewRequest (http .MethodGet , url , nil )
155164 if err != nil {
156165 return
157166 }
158167
159- timeoutContext , timeoutContextCancel := context .WithTimeout (context .Background (), config .GetDefaultLocal ().MaxCatchpointDownloadDuration )
160- defer timeoutContextCancel ()
168+ timeoutContext , ctxCancel := context .WithTimeout (context .Background (), config .GetDefaultLocal ().MaxCatchpointDownloadDuration )
161169 request = request .WithContext (timeoutContext )
162170 network .SetUserAgentHeader (request .Header )
163171 response , err := http .DefaultClient .Do (request )
164172 if err != nil {
165173 return
166174 }
167- defer response .Body .Close ()
168175
169176 // check to see that we had no errors.
170177 switch response .StatusCode {
171178 case http .StatusOK :
172179 case http .StatusNotFound : // server could not find a block with that round numbers.
173- err = fmt .Errorf ("no catchpoint file for round %d" , round )
180+ err = fmt .Errorf ("no %s for round %d" , hint , round )
174181 return
175182 default :
176183 err = fmt .Errorf ("error response status code %d" , response .StatusCode )
177184 return
178185 }
179186
187+ result = response .Body
188+ return
189+ }
190+
191+ func downloadCatchpoint (addr string , round int ) (tarName string , proto protocol.ConsensusVersion , err error ) {
192+ genesisID := strings .Split (networkName , "." )[0 ] + "-v1.0"
193+ urlTemplate := "http://" + addr + "/v1/" + genesisID + "/%s/" + strconv .FormatUint (uint64 (round ), 36 )
194+ catchpointURL := fmt .Sprintf (urlTemplate , "ledger" )
195+ blockURL := fmt .Sprintf (urlTemplate , "block" )
196+
197+ blockStream , blockCtxCancel , err := getRemoteDataStream (blockURL , "block" )
198+ defer blockCtxCancel ()
199+ defer blockStream .Close ()
200+ if err != nil {
201+ return
202+ }
203+
204+ rawBlock , err := ioutil .ReadAll (blockStream )
205+ if err != nil {
206+ return
207+ }
208+ var rpcsBlock rpcs.EncodedBlockCert
209+ err = protocol .Decode (rawBlock , & rpcsBlock )
210+ if err != nil {
211+ return
212+ }
213+ proto = rpcsBlock .Block .CurrentProtocol
214+
215+ catchpointStream , catchpointCtxCancel , err := getRemoteDataStream (catchpointURL , "catchpoint" )
216+ defer catchpointCtxCancel ()
217+ defer catchpointStream .Close ()
218+ if err != nil {
219+ return
220+ }
221+
180222 dirName := "./" + strings .Split (networkName , "." )[0 ] + "/" + strings .Split (addr , "." )[0 ]
181223 os .RemoveAll (dirName )
182224 err = os .MkdirAll (dirName , 0777 )
@@ -186,20 +228,20 @@ func downloadCatchpoint(addr string, round int) (tarName string, err error) {
186228 tarName = dirName + "/" + strconv .FormatUint (uint64 (round ), 10 ) + ".tar"
187229 file , err2 := os .Create (tarName ) // will create a file with 0666 permission.
188230 if err2 != nil {
189- return tarName , err2
231+ return tarName , proto , err2
190232 }
191233 defer func () {
192234 err = file .Close ()
193235 }()
194236 writeChunkSize := 64 * 1024
195237
196- wdReader := util .MakeWatchdogStreamReader (response . Body , 4096 , 4096 , 2 * time .Second )
238+ wdReader := util .MakeWatchdogStreamReader (catchpointStream , 4096 , 4096 , 2 * time .Second )
197239 var totalBytes int
198240 tempBytes := make ([]byte , writeChunkSize )
199241 lastProgressUpdate := time .Now ()
200242 progress := - 25
201- printDownloadProgressLine (progress , 50 , url , 0 )
202- defer printDownloadProgressLine (0 , 0 , url , 0 )
243+ printDownloadProgressLine (progress , 50 , catchpointURL , 0 )
244+ defer printDownloadProgressLine (0 , 0 , catchpointURL , 0 )
203245 var n int
204246 for {
205247 n , err = wdReader .Read (tempBytes )
@@ -209,26 +251,25 @@ func downloadCatchpoint(addr string, round int) (tarName string, err error) {
209251 totalBytes += n
210252 writtenBytes , err2 := file .Write (tempBytes [:n ])
211253 if err2 != nil || n != writtenBytes {
212- return tarName , err2
254+ return tarName , proto , err2
213255 }
214256
215257 err = wdReader .Reset ()
216258 if err != nil {
217259 if err == io .EOF {
218- return tarName , nil
260+ return tarName , proto , nil
219261 }
220262 return
221263 }
222264 if time .Since (lastProgressUpdate ) > 50 * time .Millisecond {
223265 lastProgressUpdate = time .Now ()
224- printDownloadProgressLine (progress , 50 , url , int64 (totalBytes ))
266+ printDownloadProgressLine (progress , 50 , catchpointURL , int64 (totalBytes ))
225267 progress ++
226268 }
227269 }
228270}
229271
230- func makeFileDump (addr string , tarFile string ) error {
231- genesisInitState := ledgercore.InitState {}
272+ func makeFileDump (addr string , tarFile string , genesisInitState ledgercore.InitState ) error {
232273 deleteLedgerFiles := func () {
233274 os .Remove ("./ledger.block.sqlite" )
234275 os .Remove ("./ledger.block.sqlite-shm" )
0 commit comments