mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-26 09:42:22 +00:00
1aefd7d16a
Reuse buffers. Signed-off-by: Roman Khimov <roman@nspcc.ru>
93 lines
2 KiB
Go
93 lines
2 KiB
Go
package chaindump
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
)
|
|
|
|
// DumperRestorer is an interface to get/add blocks from/to.
|
|
type DumperRestorer interface {
|
|
AddBlock(block *block.Block) error
|
|
GetBlock(hash util.Uint256) (*block.Block, error)
|
|
GetConfig() config.Blockchain
|
|
GetHeaderHash(uint32) util.Uint256
|
|
}
|
|
|
|
// Dump writes count blocks from start to the provided writer.
|
|
// Note: header needs to be written separately by a client.
|
|
func Dump(bc DumperRestorer, w *io.BinWriter, start, count uint32) error {
|
|
var buf = io.NewBufBinWriter()
|
|
|
|
for i := start; i < start+count; i++ {
|
|
bh := bc.GetHeaderHash(i)
|
|
b, err := bc.GetBlock(bh)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
b.EncodeBinary(buf.BinWriter)
|
|
bytes := buf.Bytes()
|
|
w.WriteU32LE(uint32(len(bytes)))
|
|
w.WriteBytes(bytes)
|
|
if w.Err != nil {
|
|
return w.Err
|
|
}
|
|
buf.Reset()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Restore restores blocks from the provided reader.
|
|
// f is called after addition of every block.
|
|
func Restore(bc DumperRestorer, r *io.BinReader, skip, count uint32, f func(b *block.Block) error) error {
|
|
var buf []byte
|
|
|
|
readBlock := func(r *io.BinReader) ([]byte, error) {
|
|
var size = r.ReadU32LE()
|
|
if uint32(cap(buf)) < size {
|
|
buf = make([]byte, size)
|
|
} else {
|
|
buf = buf[:size]
|
|
}
|
|
r.ReadBytes(buf)
|
|
return buf, r.Err
|
|
}
|
|
|
|
i := uint32(0)
|
|
for ; i < skip; i++ {
|
|
_, err := readBlock(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
stateRootInHeader := bc.GetConfig().StateRootInHeader
|
|
|
|
for ; i < skip+count; i++ {
|
|
buf, err := readBlock(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
b := block.New(stateRootInHeader)
|
|
r := io.NewBinReaderFromBuf(buf)
|
|
b.DecodeBinary(r)
|
|
if r.Err != nil {
|
|
return r.Err
|
|
}
|
|
if b.Index != 0 || i != 0 || skip != 0 {
|
|
err = bc.AddBlock(b)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to add block %d: %w", i, err)
|
|
}
|
|
}
|
|
if f != nil {
|
|
if err := f(b); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|