-
Notifications
You must be signed in to change notification settings - Fork 38
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
Conversation
83dbf8a
to
da38df6
Compare
Codecov ReportAttention: Patch coverage is
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. |
1c01505
to
aa415c2
Compare
return fmt.Errorf("can't get containers list: %w", err) | ||
} | ||
|
||
for _, cID := range cids { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for now.
Need some decisions there. In any case, will not be hard to fix. Overall it is ready. |
There was a problem hiding this 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
pkg/morph/client/container/nodes.go
Outdated
// 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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
pkg/morph/client/container/nodes.go
Outdated
) | ||
|
||
// AddNextEpochNodes registers public keys as a container's placement vector | ||
// with specified index. Registration must be finished with final |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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...
?
pkg/morph/client/container/nodes.go
Outdated
// 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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why placement index is not uint8
as in https://github.com/nspcc-dev/neofs-contract/blob/36dd7a25087993a6b71011056f1c1d2291d4efd4/contracts/container/contract.go#L575?
There was a problem hiding this comment.
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
pkg/morph/client/container/nodes.go
Outdated
// [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 { |
There was a problem hiding this comment.
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
pkg/morph/client/container/nodes.go
Outdated
// 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 { |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
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 != "" { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
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
Some extend morph client without behavior changes. Some prepare IR. Some prepare SN. |
aa415c2
to
8ce846c
Compare
@@ -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 |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for now.
59fb40b
to
74d32f1
Compare
Added meta validity based on blocks, not epochs. |
continue | ||
} | ||
|
||
if !sig.Verify(t.objSharedMeta) { |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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
Signed-off-by: Pavel Karpy <[email protected]>
Follows nspcc-dev/neofs-contract#438. Signed-off-by: Pavel Karpy <[email protected]>
Signed-off-by: Pavel Karpy <[email protected]>
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]>
Follows nspcc-dev/neofs-contract#414. 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]>
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]>
74d32f1
to
8679044
Compare
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]>
8679044
to
ae6e37d
Compare
|
||
// 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 { |
There was a problem hiding this comment.
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)
No description provided.