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
privval: Switch to amino encoding in SignBytes #2459
Conversation
- currently only Vote is done
Codecov Report
@@ Coverage Diff @@
## develop #2459 +/- ##
===========================================
+ Coverage 61.72% 61.74% +0.02%
===========================================
Files 197 198 +1
Lines 16478 16380 -98
===========================================
- Hits 10171 10114 -57
+ Misses 5447 5440 -7
+ Partials 860 826 -34
|
7c8375c
to
f7a38b3
Compare
- add error description on error
@xla: I've added Errors to the reply messages such that the remote validator can add those; but would it be OK to add proper error handling (and a bunch of known error codes) in a followup PR? |
@liamsi Of course! |
privval/socket.go
Outdated
} | ||
|
||
// Error allows (remote) validators to include meaningful error descriptions in their reply. | ||
type Error struct { |
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.
s/Error/RemoteError or RemoteSignerError
types/vote.go
Outdated
@@ -108,7 +108,7 @@ func (vote *Vote) String() string { | |||
vote.Height, vote.Round, vote.Type, typeString, | |||
cmn.Fingerprint(vote.BlockID.Hash), | |||
cmn.Fingerprint(vote.Signature), | |||
CanonicalTime(vote.Timestamp)) | |||
vote.Timestamp) | |||
} |
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.
make this consistently formatted (each new line, or pairs were it makes sense)
privval/socket.go
Outdated
// SignProposalMsg is a PrivValidatorSocket message containing a Proposal. | ||
type SignProposalMsg struct { | ||
// SignVoteReply is a PrivValidatorSocket message containing a signed vote along with a potenial error message. | ||
type SignedVoteReply struct { |
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.
change to Request/Response instead.
privval/socket.go
Outdated
res = &SignProposalMsg{r.Proposal} | ||
case *SignHeartbeatMsg: | ||
if err != nil { | ||
res = &SignedProposalReply{nil, &Error{0, err.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.
this decreased the test-coverage ... add tests for these new branches too
- contains all changes besides the test-coverage / error'ing branches
f7a38b3
to
dfcb818
Compare
- add tests for each newly introduced error'ing code path
0258834
to
3aa2914
Compare
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.
👏 Would be nice to add a changelog entry and review relevant docs.
privval/socket.go
Outdated
@@ -160,7 +160,13 @@ func (sc *SocketPV) SignVote(chainID string, vote *types.Vote) error { | |||
return err | |||
} | |||
|
|||
*vote = *res.(*SignVoteMsg).Vote | |||
resp := *res.(*SignedVoteResponse) |
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 if it's not SignedVoteResponse
?
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 wasn't considered previously either, but yeah good catch! Will return an error in that case (and add a test-case). Thx.
privval/socket.go
Outdated
@@ -179,8 +185,13 @@ func (sc *SocketPV) SignProposal( | |||
if err != nil { | |||
return err | |||
} | |||
|
|||
*proposal = *res.(*SignProposalMsg).Proposal | |||
resp := *res.(*SignedProposalResponse) |
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.
same
privval/socket.go
Outdated
@@ -199,8 +210,14 @@ func (sc *SocketPV) SignHeartbeat( | |||
if err != nil { | |||
return err | |||
} | |||
|
|||
*heartbeat = *res.(*SignHeartbeatMsg).Heartbeat | |||
resp := *res.(*SignedHeartbeatResponse) |
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.
same
|
Round int `json:"round"` | ||
Timestamp time.Time `json:"timestamp"` | ||
VoteType byte `json:"type"` | ||
} |
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 understand that this might be a first step towards solving #1622
This is very different from the agreed schema (#1622 (comment))
// vanilla protobuf / amino encoded
message Vote {
Version fixed32
Height sfixed64
Round sfixed32
VoteType fixed32
Timestamp Timestamp // << using protobuf definition
BlockID BlockID // << as already defined
ChainID string // at the end because length could vary a lot
}
The order and fixed size types are important so some fields can be serialized without having to deal with amino. This has been extensively discussed in #1622
privval/socket.go
Outdated
Vote *types.Vote | ||
} | ||
|
||
// SignProposalMsg is a PrivValidatorSocket message containing a Proposal. | ||
type SignProposalMsg struct { | ||
// SignVoteReply is a PrivValidatorSocket message containing a signed vote along with a potenial error message. |
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.
SignedVoteResponse
types/heartbeat.go
Outdated
@@ -23,7 +23,7 @@ type Heartbeat struct { | |||
// SignBytes returns the Heartbeat bytes for signing. | |||
// It panics if the Heartbeat is nil. | |||
func (heartbeat *Heartbeat) SignBytes(chainID string) []byte { | |||
bz, err := cdc.MarshalJSON(CanonicalHeartbeat(chainID, heartbeat)) | |||
bz, err := cdc.MarshalJSON(CanonicalizeHeartbeat(chainID, heartbeat)) |
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.
MarshalBinary?
// NOTE: when this fails, you probably want to fix up consensus/replay_test too | ||
t.Errorf("Got unexpected sign string for Vote. Expected:\n%v\nGot:\n%v", expected, signStr) | ||
} | ||
expected, err := cdc.MarshalBinary(CanonicalizeVote("test_chain_id", vote)) |
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 might be worth hard-coding a binary representation here as an extra assurance. Helps make sure we know exactly what this looks like for other implementers and in-case we ever break 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.
Opened #2508 for this
414f396
to
8d99cb0
Compare
will resolve #2455