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

[Merged by Bors] - ATX handler V2 supports marriages #6010

Closed
wants to merge 17 commits into from

Conversation

poszu
Copy link
Contributor

@poszu poszu commented Jun 4, 2024

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 the identities table.

The identities.IsMalicious() function was updated to check if any IDs that are part of the equivocation set are malicious (has identities.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.

pubkey proof received marriage_atx
ALICE <proof blob> 1717500897643387339 <ATX ID>
BOB NULL 0 <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

  • Explain motivation or link existing issue(s)
  • Test changes and document test plan
  • Update documentation as needed
  • Update changelog as needed

@poszu poszu force-pushed the atx-handler-v2/marriages branch from fda5153 to fb817dc Compare June 4, 2024 11:42
Copy link

codecov bot commented Jun 5, 2024

Codecov Report

Attention: Patch coverage is 78.12500% with 28 lines in your changes missing coverage. Please review.

Project coverage is 81.4%. Comparing base (8df8e7f) to head (64efc3b).
Report is 13 commits behind head on develop.

Files Patch % Lines
activation/handler_v2.go 73.6% 10 Missing and 10 partials ⚠️
sql/identities/identities.go 87.7% 3 Missing and 3 partials ⚠️
activation/wire/wire_v2.go 50.0% 1 Missing ⚠️
malfeasance/wire/malfeasance.go 0.0% 1 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

@poszu poszu marked this pull request as ready for review June 5, 2024 11:23
proof := &mwire.MalfeasanceProof{
Proof: mwire.Proof{
Type: mwire.DoubleMarry,
Data: &mwire.DoubleMarryProof{},
Copy link
Contributor Author

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.

Copy link
Member

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.

@poszu
Copy link
Contributor Author

poszu commented Jun 5, 2024

bors try

spacemesh-bors bot added a commit that referenced this pull request Jun 5, 2024
@spacemesh-bors
Copy link

spacemesh-bors bot commented Jun 5, 2024

try

Build succeeded:

malfeasance/handler.go Outdated Show resolved Hide resolved
Comment on lines +328 to +333
type DoubleMarryProof struct {
// TODO: implement
}

func (p *DoubleMarryProof) isProof() {}

Copy link
Member

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.

Copy link
Member

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
Copy link
Member

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?

Copy link
Contributor Author

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;`,
Copy link
Member

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?

Suggested change
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);`,

Copy link
Contributor Author

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).

Copy link
Member

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)
Copy link
Member

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{},
Copy link
Member

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.

Comment on lines +1146 to +1147
// TODO: check the proof contents once its implemented
require.NotNil(t, proof)
Copy link
Member

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_test.go Outdated Show resolved Hide resolved
Comment on lines 544 to 551
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
}

Copy link
Member

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.

activation/wire/wire_v2.go Outdated Show resolved Hide resolved
Comment on lines +328 to +333
type DoubleMarryProof struct {
// TODO: implement
}

func (p *DoubleMarryProof) isProof() {}

Copy link
Member

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;`,
Copy link
Member

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.

@poszu poszu requested a review from acud as a code owner June 17, 2024 09:01
@poszu
Copy link
Contributor Author

poszu commented Jun 19, 2024

bors merge

spacemesh-bors bot pushed a commit that referenced this pull request Jun 19, 2024
@poszu
Copy link
Contributor Author

poszu commented Jun 19, 2024

bors cancel

@spacemesh-bors
Copy link

Canceled.

@poszu
Copy link
Contributor Author

poszu commented Jun 20, 2024

bors try

spacemesh-bors bot added a commit that referenced this pull request Jun 20, 2024
@spacemesh-bors
Copy link

try

Build failed:

@poszu
Copy link
Contributor Author

poszu commented Jun 20, 2024

bors try

spacemesh-bors bot added a commit that referenced this pull request Jun 20, 2024
@spacemesh-bors
Copy link

try

Build failed:

@poszu
Copy link
Contributor Author

poszu commented Jun 20, 2024

bors merge

spacemesh-bors bot pushed a commit that referenced this pull request Jun 20, 2024
@spacemesh-bors
Copy link

Build failed:

@poszu
Copy link
Contributor Author

poszu commented Jun 20, 2024

Lots of GRPC errors in the test itself. Retrying

bors merge

spacemesh-bors bot pushed a commit that referenced this pull request Jun 20, 2024
@spacemesh-bors
Copy link

Build failed:

@poszu
Copy link
Contributor Author

poszu commented Jun 20, 2024

Bors merge

spacemesh-bors bot pushed a commit that referenced this pull request Jun 20, 2024
@spacemesh-bors
Copy link

Pull request successfully merged into develop.

Build succeeded:

@spacemesh-bors spacemesh-bors bot changed the title ATX handler V2 supports marriages [Merged by Bors] - ATX handler V2 supports marriages Jun 20, 2024
@spacemesh-bors spacemesh-bors bot closed this Jun 20, 2024
@spacemesh-bors spacemesh-bors bot deleted the atx-handler-v2/marriages branch June 20, 2024 16:16
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.

support ID marriages
2 participants