Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/push object meta to contracts #3044

Merged
merged 13 commits into from
Dec 23, 2024

Conversation

carpawell
Copy link
Member

No description provided.

@carpawell carpawell self-assigned this Dec 10, 2024
@carpawell carpawell force-pushed the feat/push-object-meta-to-contracts branch from 83dbf8a to da38df6 Compare December 10, 2024 21:12
Copy link

codecov bot commented Dec 10, 2024

Codecov Report

Attention: Patch coverage is 10.53922% with 365 lines in your changes missing coverage. Please review.

Project coverage is 22.36%. Comparing base (4f4840c) to head (ae6e37d).
Report is 26 commits behind head on master.

Files with missing lines Patch % Lines
pkg/services/object/put/distributed.go 0.00% 77 Missing ⚠️
pkg/morph/client/container/nodes.go 0.00% 47 Missing ⚠️
pkg/morph/client/notary.go 0.00% 46 Missing ⚠️
pkg/morph/event/container/put_notary.go 0.00% 45 Missing ⚠️
pkg/innerring/processors/netmap/process_epoch.go 0.00% 38 Missing ⚠️
...nnerring/processors/container/process_container.go 0.00% 28 Missing ⚠️
pkg/morph/client/container/meta.go 0.00% 15 Missing ⚠️
pkg/morph/client/container/put.go 0.00% 11 Missing ⚠️
pkg/morph/client/static.go 0.00% 8 Missing ⚠️
pkg/morph/event/opcodes.go 0.00% 8 Missing ⚠️
... and 15 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3044      +/-   ##
==========================================
- Coverage   22.41%   22.36%   -0.06%     
==========================================
  Files         791      793       +2     
  Lines       58405    58698     +293     
==========================================
+ Hits        13093    13127      +34     
- Misses      44416    44669     +253     
- Partials      896      902       +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@carpawell carpawell force-pushed the feat/push-object-meta-to-contracts branch 5 times, most recently from 1c01505 to aa415c2 Compare December 11, 2024 17:01
return fmt.Errorf("can't get containers list: %w", err)
}

for _, cID := range cids {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@roman-khimov, i think this is the only thing that we may discuss: IMO if netmap is changed, many containers change their placement and it is easier to recalculate them all once in a single epoch (and not touch them for many-many epochs) than to cache the whole map from the previous epoch OR to fetch it, calculate and compare every vector in every container to see if anything has changed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for now.

@carpawell
Copy link
Member Author

Need some decisions there. In any case, will not be hard to fix. Overall it is ready.

@carpawell carpawell marked this pull request as ready for review December 11, 2024 17:07
Copy link
Contributor

@cthulhu-rider cthulhu-rider left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sequence of commits is inconvenient for review. Some subsequent commits answer questions about the previous ones, and sometimes it seems they even fix them. And looks like the whole desired behavior achieved only by having them all at once

anyway, i'll leave all the comments accumulated by the middle just in case

// AddNextEpochNodes registers public keys as a container's placement vector
// with specified index. Registration must be finished with final
// [Client.CommitContainerListUpdate] call. Always sends a notary request with
// Alphabet multi-signature.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

request to sign by the Alphabet to be more precise

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and is always signed by one of the Alphabet node in fact. i added this like because we have AsAlphabet and smth like this option for the client. this line highlights that it is always sent by the alphabet node, SN and any other client should not so this

)

// AddNextEpochNodes registers public keys as a container's placement vector
// with specified index. Registration must be finished with final
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this registers, and then 2nd statetement follows. To me, this means 'call CommitContainerListUpdate right after this method'. I'd paraphrase

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can suggest "registers candidates". you mean it is not clear that it is possible to call it more that once before Submit...?

// with specified index. Registration must be finished with final
// [Client.CommitContainerListUpdate] call. Always sends a notary request with
// Alphabet multi-signature.
func (c *Client) AddNextEpochNodes(cid []byte, placementIndex int, nodesKeys [][]byte) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no specific idea. since it is a real go code, i wanted indexes to be int while REPs in our SDK are uint32. i wanted it to be something special but there are no types in neo VM. i even had to change something on the contract side just because it did not compile
about this thread: it was not a mistake, made intentionally, if you do not agree, ping me one more time and i will change

// [Client.CommitContainerListUpdate] call. Always sends a notary request with
// Alphabet multi-signature.
func (c *Client) AddNextEpochNodes(cid []byte, placementIndex int, nodesKeys [][]byte) error {
if len(cid) == 0 || len(nodesKeys) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not rly useful check for cid, better to accept cid.ID

// CommitContainerListUpdate finishes container placement updates for the current
// epoch made by former [Client.AddNextEpochNodes] calls. Always sends a notary
// request with Alphabet multi-signature.
func (c *Client) CommitContainerListUpdate(cid []byte, replicas []uint32) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and here it's uint32 instead of uint8

@@ -10,6 +10,7 @@ import (

"github.com/nspcc-dev/neofs-node/pkg/core/client"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
chaintcontainer "github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chaint?

}

if t.localNodeInContainer {
t.metaMtx.RLock()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no more concurrent access at this point, isn't it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is right but still, mutex saves exactly this field so lets read it safely too, if you don't mind. mb, it will save us in future changes


err = t.cnrClient.SubmitObjectPut(t.objSharedMeta, t.collectedSignatures)
if err != nil {
t.placementIterator.log.Info("submitting meta information", zap.Stringer("oid", id), zap.Error(err))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

failed to submit

@@ -154,7 +155,7 @@ func (t *distributedTarget) Close() (oid.ID, error) {
return oid.ID{}, err
}

if t.localNodeInContainer {
if t.localNodeInContainer && t.metainfoConsistencyAttr != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could u pls remind is t.metainfoConsistencyAttr != "" == enabled meta-on-chain?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in practice yes. but non-zero also varies so i added a switch later

@@ -33,7 +33,8 @@ type distributedTarget struct {
objMeta object.ContentMeta
networkMagicNumber uint32

cnrClient *chaintcontainer.Client
cnrClient *chaintcontainer.Client
metainfoConsistencyAttr string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now it's handled as boolean, will behavior ever depend on the particular value?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, in the latter commit. hm, i see, lets squash some commits

@carpawell
Copy link
Member Author

sequence of commits is inconvenient for review

IMO, it is the opposite, i tired to highlight step by step what should be changed to be possible it to work. Squashed few commits not to repeat some things

And looks like the whole desired behavior achieved only by having them all at once

Some extend morph client without behavior changes. Some prepare IR. Some prepare SN.

@carpawell carpawell force-pushed the feat/push-object-meta-to-contracts branch from aa415c2 to 8ce846c Compare December 12, 2024 15:31
pkg/innerring/processors/container/process_container.go Outdated Show resolved Hide resolved
@@ -64,6 +68,14 @@ func (c *cleanupTable) update(snapshot netmap.NetMap, now uint64) {
}

c.lastAccess = newMap

// order is expected to be the same from epoch to epoch
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VM is stable in every aspect of it given that inputs/outputs are the same.

return fmt.Errorf("can't get containers list: %w", err)
}

for _, cID := range cids {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for now.

@carpawell carpawell force-pushed the feat/push-object-meta-to-contracts branch 2 times, most recently from 59fb40b to 74d32f1 Compare December 18, 2024 17:41
@carpawell
Copy link
Member Author

Added meta validity based on blocks, not epochs.

pkg/innerring/processors/container/process_container.go Outdated Show resolved Hide resolved
continue
}

if !sig.Verify(t.objSharedMeta) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works for node in N+1 and peers in N, but not the other way around (if not in N objSharedMeta is for N, but the first signature from peers will already be for N+1).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@roman-khimov, hm, that is right. but i am not sure what else can be done here, we cannot collect two different signatures since we cannot send half signatures for the "outdated" nodes and half for the "actual" one, server-side always needs to get a single version for vub (or we need contract updates again). i can suggest sending three signatures and the server can always try currentEpoch + 1 (btw, this is even better, since we can get an object in the last block of the epoch, and then handling may break in the next block on the contract side), which handles every kind of epoch divergence that is not bigger than 1 epoch

After nspcc-dev/neofs-contract#438 Container contract
now has API for container-side placement/verification operations. But building
placement vectors and updating when needed is still a complex operation that
should be done on a Go application side. This commit adds such a responsibility
for Alphabet nodes. For simplicity, updating is done every epoch and once for
_every_ container if netmap has been changed. Additional optimization can be
considered.

Signed-off-by: Pavel Karpy <[email protected]>
Refs nspcc-dev/neofs-contract#414. Push meta only if
consistency policy asks for it

Signed-off-by: Pavel Karpy <[email protected]>
According to nspcc-dev/neofs-api#309, "strict" must wait
for meta-data handling on the contract-side and every PUT request is responded
only with transaction acceptance.

Signed-off-by: Pavel Karpy <[email protected]>
Will be helpful for new meta-data handling policies.

Signed-off-by: Pavel Karpy <[email protected]>
It is the most secure way to ensure changes are done in sync and either all at
once, or none of them. It is still can be a problem to update too long
placement vectors in a single TX since there is always a certain limit, but it
can be reconsidered separately.

Signed-off-by: Pavel Karpy <[email protected]>
It now may have additional arg that enables meta-on-chain support and be named,
see nspcc-dev/neofs-contract#451. Closes #2877.

Signed-off-by: Pavel Karpy <[email protected]>
Add logs about successful operation. Also, log empty signatures and do not try
to continue sending when there are no signatures.

Signed-off-by: Pavel Karpy <[email protected]>
@carpawell carpawell force-pushed the feat/push-object-meta-to-contracts branch from 74d32f1 to 8679044 Compare December 23, 2024 12:12
It is more natural for on-chain operations. Also, it requires handling sync
problems when different blocks are used for the same objects on different nodes:
two signatures are always attached with epoch duration difference.
Refs nspcc-dev/neofs-contract#451.

Signed-off-by: Pavel Karpy <[email protected]>
@carpawell carpawell force-pushed the feat/push-object-meta-to-contracts branch from 8679044 to ae6e37d Compare December 23, 2024 13:15

// arrays take parts in transaction that should be multi-singed, so order
// is important to be the same
slices.SortFunc(res, func(a, b []byte) int {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slices.SortFunc(res, bytes.Compare)

@roman-khimov roman-khimov merged commit 3a10bc1 into master Dec 23, 2024
19 of 22 checks passed
@roman-khimov roman-khimov deleted the feat/push-object-meta-to-contracts branch December 23, 2024 19:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants