-
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/exchange object meta's signatures #2928
Conversation
d6037df
to
a30127e
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2928 +/- ##
==========================================
+ Coverage 23.88% 23.91% +0.03%
==========================================
Files 775 776 +1
Lines 45610 45714 +104
==========================================
+ Hits 10892 10932 +40
- Misses 33861 33922 +61
- Partials 857 860 +3 ☔ View full report in Codecov by Sentry. |
Format, @AnnaShaleva, could you, please, also take a peek at what we are planning to use as a standard message? (see #2876 also) |
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 general it's OK for the first version, we just need to catch the basic relations provided by NeoFS.
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.
quite a large amount of work has been done, I like how it fits into the old concepts
in the commit desc u indicate that the signatures are only partially used for now, do we have any pledged proposals for further use? I would also refer to them in order to confirm the motivation for the preliminary changes
pkg/core/object/replicate.go
Outdated
validInterval = 10 // in epoches | ||
currentVersion = 6 // it is also a number of fields | ||
|
||
cidKey = "cid" |
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 critical but i'd make a separate group for these consts
pkg/core/object/replicate.go
Outdated
) | ||
|
||
const ( | ||
validInterval = 10 // in epoches |
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.
validInterval = 10 // in epoches | |
validInterval = 10 // in epochs |
pkg/core/object/replicate.go
Outdated
// "validuntil": last valid epoch number for meta information | ||
// | ||
// Last valid epoch is object's creation epoch + 10. | ||
func MetaInfo(cID cid.ID, oID oid.ID, pSize uint64, deleted []oid.ID, locked []oid.ID, createdAt uint64) []byte { |
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.
func MetaInfo(cID cid.ID, oID oid.ID, pSize uint64, deleted []oid.ID, locked []oid.ID, createdAt uint64) []byte { | |
func EncodeReplicationMetaInfo(cID cid.ID, oID oid.ID, pSize uint64, deleted []oid.ID, locked []oid.ID, createdAt uint64) []byte { |
would be more clear imo
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.
dont mind
pkg/core/object/replicate.go
Outdated
// Last valid epoch is object's creation epoch + 10. | ||
func MetaInfo(cID cid.ID, oID oid.ID, pSize uint64, deleted []oid.ID, locked []oid.ID, createdAt uint64) []byte { | ||
kvs := make([]stackitem.MapElement, 0, currentVersion) | ||
kvs = append(kvs, kv(cidKey, cID[:])) |
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.
appends look redundant here, kvs
can be initialized in one assignment
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.
ok
pkg/core/object/replicate.go
Outdated
// all the errors in the stackitem relate only cases when it is | ||
// impossible to use serialized values (too many values, unsupported | ||
// types, etc.), unexpected errors at all | ||
panic(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.
i'd also add context like
panic(err) | |
panic(fmt.Errorf("unexpected stackitem map serialization failure: %v", err)) |
|
||
locked = make([]oid.ID, l.NumberOfMembers()) | ||
l.ReadMembers(locked) | ||
default: |
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.
forgot code or redundant?
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, why? if we are replicating a lock/tomb object, we add IDs, but if we are adding a regular object, nothing should be done in this switch
or what you suggest here?
@@ -178,7 +180,20 @@ func (s *Server) Replicate(_ context.Context, req *objectGRPC.ReplicateRequest) | |||
}}, nil | |||
} | |||
|
|||
return new(objectGRPC.ReplicateResponse), nil | |||
resp := new(objectGRPC.ReplicateResponse) | |||
if req.GetSignObject() { |
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.
do u plan to add tests for these cases? there are few of them now
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.
added some
fmt.Println("DEBUG: trying to verify signatures") | ||
|
||
if !sig.Verify(t.objSharedMeta) { | ||
return apistatus.ErrSignatureVerification |
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.
quite a few signatures are checked during communication, so I would add context what exact verification has failed
default: | ||
} | ||
|
||
t.objSharedMeta = object.MetaInfo(t.obj.GetContainerID(), t.obj.GetID(), t.obj.PayloadSize(), deletedObjs, lockedObjs, t.obj.CreationEpoch()) |
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.
t.objSharedMeta
is used conditionally while calculated unconditionally. Lets sync
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.
can you elaborate a little? this is calculated before any concurrent code, but is read concurrently, yes. do you mean some comments about it? or you want to see a lock here?
return fmt.Errorf("could not close object stream: %w", err) | ||
} | ||
|
||
if !node.local { |
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.
shouldnt this be
if !node.local { | |
if t.localNodeInContainer && !node.local { |
? Seems like ur proposal would fail when request goes through a non-container node
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.
hm, that's interesting. what a non-contianer node should do if it faces an object whose meta signatures it should check? @roman-khimov
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 would it be involved in replication?
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.
what does a node do when it is asked to sign with session key objects of a container it does not belong to?
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.
It's signing and passing the object to container node.
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.
oh, i have overthought some things in this code but yes, t.localNodeInContainer
is enough, added. (also added nil signature check)
metaInfo := objectcore.MetaInfo(o.GetContainerID(), o.GetID(), o.PayloadSize(), deleted, locked, o.CreationEpoch()) | ||
|
||
var sig neofscrypto.Signature | ||
err := sig.Calculate(s.signer, metaInfo) |
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 differs from the original protocol definition
do I understand correctly that we decided to limit the amount of information being signed, and this approach will eventually be "backported" into the protocol?
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, things have changed with time (or i did not get them from the beginning). we have discussed it with @roman-khimov, a custom message should be provided (see the 2. in the comment mostly)
and this approach will eventually be "backported" into the protocol?
yes, that is right. not release was done since so it should not be a problem
Yes, there should be some event contracts and contract-side validation. This is kinda the first iteration, all the other work will be done soon after this PR is discussed and approved.
Added contract issues to the commit desc. |
a30127e
to
96f271f
Compare
96f271f
to
0bcc540
Compare
It has `Replicate` with meta signatures. Signed-off-by: Pavel Karpy <[email protected]>
Initial replication requires nodes to sign object's main meta information and respond with it. Meta information is not sent on wire and treated as a fixed ordered NEO's map. Signatures are verified, not stored/send anywhere yet. It follows the recent API extension: nspcc-dev/neofs-api#299. Further, this extension is planned to have a contract adoption: nspcc-dev/neofs-contract#413 and nspcc-dev/neofs-contract#414. Closes #2876. Signed-off-by: Pavel Karpy <[email protected]>
When I wanted to use it, I wrote all the code based on `uint32` (because I knew it should be this way), and at the last moment I found that `client` package returns it as `uint64` for no reason. Signed-off-by: Pavel Karpy <[email protected]>
It saves from replay attacks and makes replication operation (and meta information in particular) more explicit. Signed-off-by: Pavel Karpy <[email protected]>
0bcc540
to
d7b63cb
Compare
No description provided.