-
Notifications
You must be signed in to change notification settings - Fork 212
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
[Merged by Bors] - ATX handler V2 supports marriages #6010
Conversation
fda5153
to
fb817dc
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #6010 +/- ##
=========================================
+ Coverage 81.3% 81.4% +0.1%
=========================================
Files 296 299 +3
Lines 31632 32172 +540
=========================================
+ Hits 25741 26219 +478
- Misses 4210 4243 +33
- Partials 1681 1710 +29 ☔ View full report in Codecov by Sentry. |
proof := &mwire.MalfeasanceProof{ | ||
Proof: mwire.Proof{ | ||
Type: mwire.DoubleMarry, | ||
Data: &mwire.DoubleMarryProof{}, |
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.
Note: the proof must be implemented first to fill it here.
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 would also create one proof for every identity with a certificate in the ATX which is not necessary. There should only be one proof that one identity married twice - and a list of certificates that all married that identity and become malicious too.
bors try |
tryBuild succeeded: |
type DoubleMarryProof struct { | ||
// TODO: implement | ||
} | ||
|
||
func (p *DoubleMarryProof) isProof() {} | ||
|
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 belongs in the activation
package.
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 added the general process for this to #6043
@@ -24,6 +24,7 @@ const ( | |||
BALLOT = 2 | |||
HARE = 3 | |||
POET = 4 | |||
MARRIAGE = 5 |
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.
Should this be its own domain? For me this belongs to ATX
?
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'm not sure. The ATX domain is used for signing ATXs. The MARRIAGE domain is used to sign the marriage certs. It's included in an ATX but it's a different thing. I think there's no harm in it being a separate domain, is there?
|
||
rows, err := db.Exec(` | ||
SELECT pubkey FROM identities | ||
WHERE marriage_atx = (SELECT marriage_atx FROM identities WHERE pubkey = ?1) AND marriage_atx IS NOT NULL;`, |
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.
The second half seems redundant?
WHERE marriage_atx = (SELECT marriage_atx FROM identities WHERE pubkey = ?1) AND marriage_atx IS NOT NULL;`, | |
WHERE marriage_atx = (SELECT marriage_atx FROM identities WHERE pubkey = ?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.
This is required to handle a case when the ID is not married (marriage_atx = NULL) to avoid returning all non-married IDs from the DB. In this case rows == 0
and the function returns a single ID (non-married IDs form a set with just themselves).
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.
Theoretically an identity could publish an ATX only containing a certificate signed by itself creating an equivocation set that only contains themselves. The "self marry" certificate is unfortunately required, but we could syntactically check that the MarriageCertificates
a) contains at least 2 entries and b) only contains distinct entries.
@@ -44,6 +44,7 @@ const ( | |||
InvalidActivation MalfeasanceType = iota + 10 | |||
InvalidBallot | |||
InvalidHareMsg | |||
DoubleMarry = MalfeasanceType(wire.DoubleMarry) |
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.
Lets sync on this tomorrow and try to integrate - the double marry type isn't defined here. I outlined the basic structure here with the first malfeasance proofs: #6043
proof := &mwire.MalfeasanceProof{ | ||
Proof: mwire.Proof{ | ||
Type: mwire.DoubleMarry, | ||
Data: &mwire.DoubleMarryProof{}, |
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 would also create one proof for every identity with a certificate in the ATX which is not necessary. There should only be one proof that one identity married twice - and a list of certificates that all married that identity and become malicious too.
// TODO: check the proof contents once its implemented | ||
require.NotNil(t, proof) |
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 think it would be better here not to return the proof but rather call a service (mock) with the instruction to publish the proof. I outlined the basic idea as part of this PR: #6043
activation/handler_v2.go
Outdated
proof, err := h.checkDoubleMarry(tx, watx) | ||
if err != nil { | ||
return false, nil, fmt.Errorf("checking double marry: %w", err) | ||
} | ||
if proof != nil { | ||
return true, proof, nil | ||
} | ||
|
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 don't think we should return the proof
here and bubble it up all the way until the handler
to then publish and persist it. Instead after successfully persisting the (syntactically valid) ATX. We check for malfeasance and just and publish a proof when we have one - only reporting back to the caller that the check was positive.
type DoubleMarryProof struct { | ||
// TODO: implement | ||
} | ||
|
||
func (p *DoubleMarryProof) isProof() {} | ||
|
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 added the general process for this to #6043
|
||
rows, err := db.Exec(` | ||
SELECT pubkey FROM identities | ||
WHERE marriage_atx = (SELECT marriage_atx FROM identities WHERE pubkey = ?1) AND marriage_atx IS NOT NULL;`, |
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.
Theoretically an identity could publish an ATX only containing a certificate signed by itself creating an equivocation set that only contains themselves. The "self marry" certificate is unfortunately required, but we could syntactically check that the MarriageCertificates
a) contains at least 2 entries and b) only contains distinct entries.
bors merge |
## Motivation Closes #6007
bors cancel |
Canceled. |
bors try |
tryBuild failed: |
bors try |
tryBuild failed: |
bors merge |
## Motivation Closes #6007
Build failed: |
Lots of GRPC errors in the test itself. Retrying bors merge |
## Motivation Closes #6007
Build failed: |
Bors merge |
## Motivation Closes #6007
Pull request successfully merged into develop. Build succeeded: |
Motivation
Closes #6007
Description
Implements the first step for merging ATXs - ID marriage.
Married IDs form an equivocation set. This set is identified by looking up all rows with the same
marriage_atx
column in theidentities
table.The
identities.IsMalicious()
function was updated to check if any IDs that are part of the equivocation set are malicious (hasidentities.proof
column populated).For example, given below 2 rows, both Alice and Bob are malicious because they share
marriage_atx
and one of them has proof.<proof blob>
<ATX ID>
<ATX ID>
The
identities.EquivocationSet()
function returns the complete set the given ID belongs to. For an ID that is not married, it returns just this ID as it forms a 1-element equivocation set.Note: in the current implementation, an ID may be malicious but doesn't have a proof explicitly assigned - it could be assigned to a different ID in its set.
Test Plan
Added tests
TODO