BlockFetcher/BlockUploader: fix and add additional attributes

Capitalize block objects and index file objects attributes.
Add network magic attribute to container.

Close #3631

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
This commit is contained in:
Ekaterina Pavlova 2024-10-21 23:49:09 +03:00
parent e82d9a179c
commit c47d4e6c5b
4 changed files with 46 additions and 28 deletions

View file

@ -18,6 +18,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/nspcc-dev/neofs-sdk-go/checksum" "github.com/nspcc-dev/neofs-sdk-go/checksum"
"github.com/nspcc-dev/neofs-sdk-go/client" "github.com/nspcc-dev/neofs-sdk-go/client"
"github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id" cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/object" "github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id" oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
@ -83,12 +84,6 @@ func uploadBin(ctx *cli.Context) error {
return cli.Exit(fmt.Sprintf("failed to create RPC client: %v", err), 1) return cli.Exit(fmt.Sprintf("failed to create RPC client: %v", err), 1)
} }
currentBlockHeight, err := rpc.GetBlockCount()
if err != nil {
return cli.Exit(fmt.Sprintf("failed to get current block height from RPC: %v", err), 1)
}
fmt.Fprintln(ctx.App.Writer, "Chain block height:", currentBlockHeight)
signer := user.NewAutoIDSignerRFC6979(acc.PrivateKey().PrivateKey) signer := user.NewAutoIDSignerRFC6979(acc.PrivateKey().PrivateKey)
params := pool.DefaultOptions() params := pool.DefaultOptions()
@ -109,6 +104,31 @@ func uploadBin(ctx *cli.Context) error {
return cli.Exit(fmt.Errorf("failed to get network info: %w", err), 1) return cli.Exit(fmt.Errorf("failed to get network info: %w", err), 1)
} }
homomorphicHashingDisabled := net.HomomorphicHashingDisabled() homomorphicHashingDisabled := net.HomomorphicHashingDisabled()
var containerObj container.Container
err = retry(func() error {
containerObj, err = p.ContainerGet(ctx.Context, containerID, client.PrmContainerGet{})
return err
})
if err != nil {
return cli.Exit(fmt.Errorf("failed to get container with ID %s: %w", containerID, err), 1)
}
containerMagic := containerObj.Attribute("Magic")
v, err := rpc.GetVersion()
if err != nil {
return cli.Exit(fmt.Sprintf("failed to get version from RPC: %v", err), 1)
}
magic := strconv.Itoa(int(v.Protocol.Network))
if containerMagic != magic {
return cli.Exit(fmt.Sprintf("Container magic %s does not match the network magic %s", containerMagic, magic), 1)
}
currentBlockHeight, err := rpc.GetBlockCount()
if err != nil {
return cli.Exit(fmt.Sprintf("failed to get current block height from RPC: %v", err), 1)
}
fmt.Fprintln(ctx.App.Writer, "Chain block height:", currentBlockHeight)
lastMissingBlockIndex, err := fetchLatestMissingBlockIndex(ctx.Context, p, containerID, acc.PrivateKey(), attr, int(currentBlockHeight)) lastMissingBlockIndex, err := fetchLatestMissingBlockIndex(ctx.Context, p, containerID, acc.PrivateKey(), attr, int(currentBlockHeight))
if err != nil { if err != nil {
return cli.Exit(fmt.Errorf("failed to fetch the latest missing block index from container: %w", err), 1) return cli.Exit(fmt.Errorf("failed to fetch the latest missing block index from container: %w", err), 1)
@ -158,10 +178,10 @@ func uploadBin(ctx *cli.Context) error {
} }
attrs := []object.Attribute{ attrs := []object.Attribute{
*object.NewAttribute(attr, strconv.Itoa(int(blk.Index))), *object.NewAttribute(attr, strconv.Itoa(int(blk.Index))),
*object.NewAttribute("primary", strconv.Itoa(int(blk.PrimaryIndex))), *object.NewAttribute("Primary", strconv.Itoa(int(blk.PrimaryIndex))),
*object.NewAttribute("hash", blk.Hash().StringLE()), *object.NewAttribute("Hash", blk.Hash().StringLE()),
*object.NewAttribute("prevHash", blk.PrevHash.StringLE()), *object.NewAttribute("PrevHash", blk.PrevHash.StringLE()),
*object.NewAttribute("timestamp", strconv.FormatUint(blk.Timestamp, 10)), *object.NewAttribute("Timestamp", strconv.FormatUint(blk.Timestamp, 10)),
} }
objBytes := bw.Bytes() objBytes := bw.Bytes()
@ -293,7 +313,7 @@ func updateIndexFiles(ctx *cli.Context, p *pool.Pool, containerID cid.ID, accoun
prm := client.PrmObjectSearch{} prm := client.PrmObjectSearch{}
filters := object.NewSearchFilters() filters := object.NewSearchFilters()
filters.AddFilter(attributeKey, fmt.Sprintf("%d", 0), object.MatchNumGE) filters.AddFilter(attributeKey, fmt.Sprintf("%d", 0), object.MatchNumGE)
filters.AddFilter("size", fmt.Sprintf("%d", indexFileSize), object.MatchStringEqual) filters.AddFilter("IndexSize", fmt.Sprintf("%d", indexFileSize), object.MatchStringEqual)
prm.SetFilters(filters) prm.SetFilters(filters)
var ( var (
objectIDs []oid.ID objectIDs []oid.ID
@ -395,7 +415,7 @@ func updateIndexFiles(ctx *cli.Context, p *pool.Pool, containerID cid.ID, accoun
} }
attrs := []object.Attribute{ attrs := []object.Attribute{
*object.NewAttribute(attributeKey, strconv.Itoa(int(i))), *object.NewAttribute(attributeKey, strconv.Itoa(int(i))),
*object.NewAttribute("size", strconv.Itoa(int(indexFileSize))), *object.NewAttribute("IndexSize", strconv.Itoa(int(indexFileSize))),
} }
err = uploadObj(ctx.Context, p, signer, account.PrivateKey().GetScriptHash(), containerID, buffer, attrs, homomorphicHashingDisabled) err = uploadObj(ctx.Context, p, signer, account.PrivateKey().GetScriptHash(), containerID, buffer, attrs, homomorphicHashingDisabled)
if err != nil { if err != nil {

View file

@ -208,7 +208,5 @@ func TestUploadBin(t *testing.T) {
e.In.WriteString("one\r") e.In.WriteString("one\r")
e.RunWithErrorCheckExit(t, "failed to create RPC client", append(args, "--cid", "9iVfUg8aDHKjPC4LhQXEkVUM4HDkR7UCXYLs8NQwYfSG", "--wallet", testcli.ValidatorWallet, "--rpc-endpoint", "https://test")...) e.RunWithErrorCheckExit(t, "failed to create RPC client", append(args, "--cid", "9iVfUg8aDHKjPC4LhQXEkVUM4HDkR7UCXYLs8NQwYfSG", "--wallet", testcli.ValidatorWallet, "--rpc-endpoint", "https://test")...)
e.In.WriteString("one\r") e.In.WriteString("one\r")
e.RunWithErrorCheck(t, "failed to dial NeoFS pool", append(args, "--cid", "9iVfUg8aDHKjPC4LhQXEkVUM4HDkR7UCXYLs8NQwYfSG", "--wallet", testcli.ValidatorWallet, "--rpc-endpoint", "http://"+e.RPC.Addresses()[0])...) e.RunWithErrorCheckExit(t, "failed to dial NeoFS pool", append(args, "--cid", "9iVfUg8aDHKjPC4LhQXEkVUM4HDkR7UCXYLs8NQwYfSG", "--wallet", testcli.ValidatorWallet, "--rpc-endpoint", "http://"+e.RPC.Addresses()[0])...)
e.CheckNextLine(t, "Chain block height:")
e.CheckEOF(t)
} }

View file

@ -111,5 +111,5 @@ ApplicationConfiguration:
SkipIndexFilesSearch: false SkipIndexFilesSearch: false
IndexFileSize: 128000 IndexFileSize: 128000
ContainerID: "EPGuD26wYgQJbmDdVBoYoNZiMKHwFMJT3A5WqPjdUHxH" ContainerID: "EPGuD26wYgQJbmDdVBoYoNZiMKHwFMJT3A5WqPjdUHxH"
BlockAttribute: "block" BlockAttribute: "Block"
IndexFileAttribute: "index" IndexFileAttribute: "Index"

View file

@ -9,20 +9,20 @@ efficiency and reduce node storage size.
### Block storage schema ### Block storage schema
A single NeoFS container is used to store blocks and index files. Each block A single NeoFS container is used to store blocks and index files. Each container
is stored in a binary form as a separate object with a unique OID and a set of has network magic attribute (`Magic:56753`). Each block is stored in a binary
attributes: form as a separate object with a unique OID and a set of attributes:
- block object identifier with block index value (`block:1`) - block object identifier with block index value (`Block:1`)
- primary node index (`primary:0`) - primary node index (`Primary:0`)
- block hash in the LE form (`hash:5412a781caf278c0736556c0e544c7cfdbb6e3c62ae221ef53646be89364566b`) - block hash in the LE form (`Hash:5412a781caf278c0736556c0e544c7cfdbb6e3c62ae221ef53646be89364566b`)
- previous block hash in the LE form (`prevHash:3654a054d82a8178c7dfacecc2c57282e23468a42ee407f14506368afe22d929`) - previous block hash in the LE form (`PrevHash:3654a054d82a8178c7dfacecc2c57282e23468a42ee407f14506368afe22d929`)
- millisecond-precision block timestamp (`timestamp:1627894840919`) - millisecond-precision block timestamp (`Timestamp:1627894840919`)
Each index file is an object containing a constant-sized batch of raw block object Each index file is an object containing a constant-sized batch of raw block object
IDs in binary form ordered by block index. Each index file is marked with the IDs in binary form ordered by block index. Each index file is marked with the
following attributes: following attributes:
- index file identifier with consecutive file index value (`index:0`) - index file identifier with consecutive file index value (`Index:0`)
- the number of OIDs included into index file (`size:128000`) - the number of OIDs included into index file (`IndexSize:128000`)
### NeoFS BlockFetcher ### NeoFS BlockFetcher
@ -79,7 +79,7 @@ them to the NeoFS container.
It also creates and uploads index files. Below is an example usage of the command: It also creates and uploads index files. Below is an example usage of the command:
```shell ```shell
./bin/neo-go util upload-bin --cid 9iVfUg8aDHKjPC4LhQXEkVUM4HDkR7UCXYLs8NQwYfSG --wallet-config ./wallet-config.yml --block-attribute block --index-attribute index --rpc-endpoint https://rpc.t5.n3.nspcc.ru:20331 -fsr st1.t5.fs.neo.org:8080 -fsr st2.t5.fs.neo.org:8080 -fsr st3.t5.fs.neo.org:8080 ./bin/neo-go util upload-bin --cid 9iVfUg8aDHKjPC4LhQXEkVUM4HDkR7UCXYLs8NQwYfSG --wallet-config ./wallet-config.yml --block-attribute Block --index-attribute Index --rpc-endpoint https://rpc.t5.n3.nspcc.ru:20331 -fsr st1.t5.fs.neo.org:8080 -fsr st2.t5.fs.neo.org:8080 -fsr st3.t5.fs.neo.org:8080
``` ```
The command supports the following options: The command supports the following options:
``` ```