github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/core/chaindump/dump.go (about) 1 package chaindump 2 3 import ( 4 "fmt" 5 6 "github.com/nspcc-dev/neo-go/pkg/config" 7 "github.com/nspcc-dev/neo-go/pkg/core/block" 8 "github.com/nspcc-dev/neo-go/pkg/io" 9 "github.com/nspcc-dev/neo-go/pkg/util" 10 ) 11 12 // DumperRestorer is an interface to get/add blocks from/to. 13 type DumperRestorer interface { 14 AddBlock(block *block.Block) error 15 GetBlock(hash util.Uint256) (*block.Block, error) 16 GetConfig() config.Blockchain 17 GetHeaderHash(uint32) util.Uint256 18 } 19 20 // Dump writes count blocks from start to the provided writer. 21 // Note: header needs to be written separately by a client. 22 func Dump(bc DumperRestorer, w *io.BinWriter, start, count uint32) error { 23 for i := start; i < start+count; i++ { 24 bh := bc.GetHeaderHash(i) 25 b, err := bc.GetBlock(bh) 26 if err != nil { 27 return err 28 } 29 buf := io.NewBufBinWriter() 30 b.EncodeBinary(buf.BinWriter) 31 bytes := buf.Bytes() 32 w.WriteU32LE(uint32(len(bytes))) 33 w.WriteBytes(bytes) 34 if w.Err != nil { 35 return w.Err 36 } 37 } 38 return nil 39 } 40 41 // Restore restores blocks from the provided reader. 42 // f is called after addition of every block. 43 func Restore(bc DumperRestorer, r *io.BinReader, skip, count uint32, f func(b *block.Block) error) error { 44 readBlock := func(r *io.BinReader) ([]byte, error) { 45 var size = r.ReadU32LE() 46 buf := make([]byte, size) 47 r.ReadBytes(buf) 48 return buf, r.Err 49 } 50 51 i := uint32(0) 52 for ; i < skip; i++ { 53 _, err := readBlock(r) 54 if err != nil { 55 return err 56 } 57 } 58 59 stateRootInHeader := bc.GetConfig().StateRootInHeader 60 61 for ; i < skip+count; i++ { 62 buf, err := readBlock(r) 63 if err != nil { 64 return err 65 } 66 b := block.New(stateRootInHeader) 67 r := io.NewBinReaderFromBuf(buf) 68 b.DecodeBinary(r) 69 if r.Err != nil { 70 return r.Err 71 } 72 if b.Index != 0 || i != 0 || skip != 0 { 73 err = bc.AddBlock(b) 74 if err != nil { 75 return fmt.Errorf("failed to add block %d: %w", i, err) 76 } 77 } 78 if f != nil { 79 if err := f(b); err != nil { 80 return err 81 } 82 } 83 } 84 return nil 85 }