-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
services: add new service for fetching blocks from NeoFS
Close #3496 Signed-off-by: Ekaterina Pavlova <[email protected]>
- Loading branch information
1 parent
c207b9b
commit db88338
Showing
8 changed files
with
292 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
package blockfetcher | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"io" | ||
"net/url" | ||
"time" | ||
|
||
cli "github.com/nspcc-dev/neo-go/cli/server" | ||
"github.com/nspcc-dev/neo-go/pkg/core" | ||
"github.com/nspcc-dev/neo-go/pkg/core/block" | ||
"github.com/nspcc-dev/neo-go/pkg/core/chaindump" | ||
"github.com/nspcc-dev/neo-go/pkg/core/storage" | ||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" | ||
gio "github.com/nspcc-dev/neo-go/pkg/io" | ||
"github.com/nspcc-dev/neo-go/pkg/services/oracle/neofs" | ||
"github.com/nspcc-dev/neofs-sdk-go/client" | ||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id" | ||
"go.uber.org/zap" | ||
) | ||
|
||
type Service struct { | ||
chain *core.Blockchain | ||
log *zap.Logger | ||
client *client.Client | ||
db storage.Store | ||
quit chan bool | ||
containerID cid.ID | ||
//HashCid string | ||
//one more cid | ||
Timeout time.Duration | ||
Nodes []string | ||
dumpDir string | ||
} | ||
|
||
// New creates a new BlockFetcherService. | ||
func New(chain *core.Blockchain, store storage.Store, logger *zap.Logger) *Service { | ||
neofsClient, err := client.New(client.PrmInit{}) | ||
if err != nil { | ||
logger.Error("Failed to create NeoFS client", zap.Error(err)) | ||
return nil | ||
} | ||
var containerID cid.ID | ||
err = containerID.DecodeString("9iVfUg8aDHKjPC4LhQXEkVUM4HDkR7UCXYLs8NQwYfSG") | ||
if err != nil { | ||
logger.Error("Failed to decode container ID", zap.Error(err)) | ||
return nil | ||
} | ||
return &Service{ | ||
chain: chain, | ||
log: logger, | ||
client: neofsClient, | ||
db: store, | ||
quit: make(chan bool), | ||
dumpDir: "./dump", | ||
containerID: containerID, | ||
Nodes: []string{"st1.t5.fs.neo.org:8080"}, | ||
Timeout: 20 * time.Second, | ||
} | ||
} | ||
|
||
// Name implements the core.Service interface. | ||
func (bfs *Service) Name() string { | ||
return "BlockFetcherService" | ||
} | ||
|
||
// Start implements the core.Service interface. | ||
func (bfs *Service) Start() { | ||
bfs.log.Info("Starting Block Fetcher Service") | ||
err := bfs.fetchBlocks() | ||
if err != nil { | ||
return | ||
} | ||
} | ||
|
||
// Shutdown implements the core.Service interface. | ||
func (bfs *Service) Shutdown() { | ||
bfs.log.Info("Shutting down Block Fetcher Service") | ||
close(bfs.quit) | ||
} | ||
|
||
func (bfs *Service) fetchBlocks() error { | ||
for { | ||
select { | ||
case <-bfs.quit: | ||
return nil | ||
default: | ||
privateKey, err := keys.NewPrivateKey() | ||
if err != nil { | ||
bfs.log.Error("Failed to create private key", zap.Error(err)) | ||
continue | ||
} | ||
ctx, cancel := context.WithTimeout(context.Background(), bfs.Timeout) | ||
defer cancel() | ||
blocks, err := neofs.ObjectSearch(ctx, bfs.client, privateKey, bfs.containerID, bfs.Nodes[0]) | ||
fmt.Println(blocks) | ||
if err != nil { | ||
bfs.log.Error("Failed to fetch object IDs", zap.Error(err)) | ||
continue | ||
} | ||
for _, obj := range blocks { | ||
u, err := url.Parse(fmt.Sprintf("neofs:%s/%s", bfs.containerID, obj)) | ||
if err != nil { | ||
bfs.log.Error("Failed to parse URL", zap.Error(err)) | ||
continue | ||
} | ||
rc, err := neofs.Get(ctx, bfs.client, privateKey, u, bfs.Nodes[0]) | ||
if err != nil { | ||
bfs.log.Error("Failed to get object", zap.Error(err)) | ||
continue | ||
} | ||
data, err := io.ReadAll(rc) | ||
if err != nil { | ||
bfs.log.Error("Failed to read data", zap.Error(err)) | ||
continue | ||
} | ||
err = bfs.processBlock(data, 2) | ||
if err != nil { | ||
bfs.log.Error("Failed to process block", zap.Error(err)) | ||
} | ||
} | ||
cancel() | ||
close(bfs.quit) | ||
} | ||
} | ||
} | ||
|
||
func (bfs *Service) processBlock(data []byte, count uint32) error { | ||
br := gio.NewBinReaderFromBuf(data) | ||
dump := cli.NewDump() | ||
var lastIndex uint32 | ||
|
||
err := chaindump.Restore(bfs.chain, br, bfs.chain.BlockHeight(), count, func(b *block.Block) error { | ||
batch := bfs.chain.LastBatch() | ||
if batch != nil { | ||
dump.Add(b.Index, batch) | ||
lastIndex = b.Index | ||
if b.Index%1000 == 0 { | ||
//need test for this | ||
if err := dump.TryPersist(bfs.dumpDir, lastIndex); err != nil { | ||
return fmt.Errorf("can't dump storage to file: %w", err) | ||
} | ||
} | ||
} | ||
return nil | ||
}) | ||
if err != nil { | ||
return fmt.Errorf("failed to restore blocks: %w", err) | ||
} | ||
|
||
if err = dump.TryPersist(bfs.dumpDir, lastIndex); err != nil { | ||
return fmt.Errorf("final persistence failed: %w", err) | ||
} | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package blockfetcher | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/nspcc-dev/neo-go/internal/basicchain" | ||
"github.com/nspcc-dev/neo-go/pkg/config" | ||
"github.com/nspcc-dev/neo-go/pkg/core/chaindump" | ||
"github.com/nspcc-dev/neo-go/pkg/core/storage" | ||
gio "github.com/nspcc-dev/neo-go/pkg/io" | ||
"github.com/nspcc-dev/neo-go/pkg/neotest" | ||
"github.com/nspcc-dev/neo-go/pkg/neotest/chain" | ||
"github.com/stretchr/testify/require" | ||
"go.uber.org/zap/zaptest" | ||
) | ||
|
||
func TestProcessBlock(t *testing.T) { | ||
bc, validators, committee := chain.NewMultiWithCustomConfig(t, | ||
func(c *config.Blockchain) { | ||
c.P2PSigExtensions = true | ||
}) | ||
e := neotest.NewExecutor(t, bc, validators, committee) | ||
|
||
basicchain.Init(t, "../../../", e) | ||
require.True(t, bc.BlockHeight() > 5) | ||
|
||
w := gio.NewBufBinWriter() | ||
require.NoError(t, chaindump.Dump(bc, w.BinWriter, 0, bc.BlockHeight()+1)) | ||
require.NoError(t, w.Err) | ||
buf := w.Bytes() | ||
bc2, _, _ := chain.NewMultiWithCustomConfig(t, func(c *config.Blockchain) { | ||
c.P2PSigExtensions = true | ||
}) | ||
serv := New(bc2, storage.NewMemoryStore(), zaptest.NewLogger(t)) | ||
err := serv.processBlock(buf, bc.BlockHeight()+1) | ||
require.NoError(t, err) | ||
require.Equal(t, bc.BlockHeight(), bc2.BlockHeight()) | ||
} | ||
|
||
func TestService(t *testing.T) { | ||
bc, _, _ := chain.NewMultiWithCustomConfig(t, | ||
func(c *config.Blockchain) { | ||
c.P2PSigExtensions = true | ||
}) | ||
|
||
serv := New(bc, storage.NewMemoryStore(), zaptest.NewLogger(t)) | ||
require.NotNil(t, serv) | ||
require.Equal(t, "BlockFetcherService", serv.Name()) | ||
serv.Start() | ||
fmt.Println(bc.BlockHeight()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.