-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
implement solo machine client #6267
Conversation
…-solo-machine-client
…-solo-machine-client
…-solo-machine-client
I think a spec directory should still be added, but I don't think they need to block merge of this pr. I probably won't get to it until after finishing proto migration in |
// current sequence of the consensus state | ||
uint64 sequence = 1; | ||
// public key of the solo machine | ||
cosmos.base.crypto.v1beta1.PublicKey public_key = 2 |
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 will likely become Any
in the near future, but I didn't want to block this pr on the sdk supporting that functionality
} | ||
|
||
// Signature contains the signature and the timestamp of the signature. | ||
message 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.
would SignatureAndTimestamp
be more clear? Other suggestions?
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.
TimestampedSignature
?
if len(sd.Signature) == 0 { | ||
return sdkerrors.Wrap(ErrInvalidSignatureAndData, "signature cannot be empty") | ||
} | ||
if len(sd.Data) == 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.
what happens if the solo machine signs over just the sequence @cwgoes ? should I remove this check?
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.
At the moment that would be invalid, so this check is fine
|
||
// VerifyClientState verifies a proof of the client state of the running chain | ||
// stored on the solo machine. | ||
func (cs ClientState) VerifyClientState( |
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.
@cwgoes @AdityaSripal please verify this is correct, it hasn't been updated in the ICS spec yet
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.
At first glance this seems fine. I'll update the spec.
consensusState := &ConsensusState{ | ||
// increment sequence number | ||
Sequence: clientState.ConsensusState.Sequence + 1, | ||
PublicKey: header.NewPublicKey, |
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.
Timestamp is missing here. Do I need to add timestamp to the header? This is missing on the ICS spec as well
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'd make sense to address this in a followup. Would prefer to have this pr merged so all future changes are easier to review and so merge conflicts don't stack up
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 won't really be up to date since a header update is only used to change the public key
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.
Nice work!! One main issue regarding VerifyClientConsensusState
} | ||
|
||
// Signature contains the signature and the timestamp of the signature. | ||
message 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.
TimestampedSignature
?
message MsgCreateClient { | ||
option (gogoproto.goproto_getters) = false; | ||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; | ||
string chain_id = 2 [(gogoproto.moretags) = "yaml:\"chain_id\""]; |
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 a solo-machine have a chain-id?
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 too convinced of its usefulness which is why I have left off any validation of it (it can be blank)
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, my response was just because it seemed we needed to have that function, I don't think it needs to be in the message - where is that function used anyways? There shouldn't need to be client-external reference to a chain ID
@@ -169,14 +176,16 @@ type ClientType byte | |||
|
|||
// available client types | |||
const ( | |||
Tendermint ClientType = iota + 1 // 1 | |||
Localhost | |||
SoloMachine ClientType = 6 |
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 like this change 👍
func NewClientState(chainID string, consensusState *ConsensusState) *ClientState { | ||
return &ClientState{ | ||
ChainId: chainID, | ||
FrozenHeight: 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.
Easier to understand if this is FrozenSequence
} | ||
} | ||
|
||
// GetChainID returns an empty 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.
doc says it should return empty string and I agree. ClientState
shouldn't have ChainID and this should return ""
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.
Agreed (also see above). Sorry for my confusing comment before. Why do we have this interface function in the first place?
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 seems there is partial consensus on removing ChainID. cc/ @fedekunze
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.
good question. I don't think it is being used outside of tendermint (but it can remain a tm client state specific func). I think we can just remove it in another pr
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 #7143
return err | ||
} | ||
|
||
data, err := ConsensusStateSignBytes(cdc, sequence, signature.Timestamp, path, cs.ConsensusState) |
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.
data, err := ConsensusStateSignBytes(cdc, sequence, signature.Timestamp, path, cs.ConsensusState) | |
data, err := ConsensusStateSignBytes(cdc, sequence, signature.Timestamp, path, consState) |
) | ||
} | ||
|
||
if cs.ConsensusState.GetTimestamp() > signature.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.
if cs.ConsensusState.GetTimestamp() > signature.Timestamp { | |
if cs.ConsensusState.GetTimestamp() >= signature.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.
this is currently correct based on ICS spec
abortTransactionUnless(proof.timestamp >= clientState.consensusState.timestamp)
cc/ @cwgoes
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 timestamp needs to be non-decreasing; it does not need to be increasing technically (though usually it will be)
|
||
// sets the client state to the store | ||
func setClientState(store sdk.KVStore, cdc codec.BinaryMarshaler, clientState clientexported.ClientState) { | ||
bz, err := codec.MarshalAny(cdc, clientState) |
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.
nit: You can use clienttypes.MustMarshalClientState
pubKey := clientState.ConsensusState.GetPubKey() | ||
|
||
// assert that provided signature data are different | ||
if bytes.Equal(evidence.SignatureOne.Data, evidence.SignatureTwo.Data) { |
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.
Hasn't this check happened in ValidateBasic
?
// EvidenceSignBytes returns the sign bytes for verification of misbehaviour. | ||
// | ||
// Format: {sequence}{data} | ||
func EvidenceSignBytes(sequence uint64, data []byte) []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.
nit: This function can be renamed to be more general
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.
agreed. But I'm not sure what a good replacement would be. I guess I could do SignBytes
? but that feels a little too vague. Going to leave for now since it is only used by evidence
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.
Mostly LGTM; see comments. Agreed that most can be addressed in a follow-up.
message MsgCreateClient { | ||
option (gogoproto.goproto_getters) = false; | ||
string client_id = 1 [(gogoproto.moretags) = "yaml:\"client_id\""]; | ||
string chain_id = 2 [(gogoproto.moretags) = "yaml:\"chain_id\""]; |
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, my response was just because it seemed we needed to have that function, I don't think it needs to be in the message - where is that function used anyways? There shouldn't need to be client-external reference to a chain ID
} | ||
} | ||
|
||
// GetChainID returns an empty 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.
Agreed (also see above). Sorry for my confusing comment before. Why do we have this interface function in the first place?
} | ||
|
||
// Validate performs basic validation of the client state fields. | ||
func (cs ClientState) Validate() 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.
Agreed, see above comments.
|
||
// VerifyClientState verifies a proof of the client state of the running chain | ||
// stored on the solo machine. | ||
func (cs ClientState) VerifyClientState( |
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.
At first glance this seems fine. I'll update the spec.
return nil | ||
} | ||
|
||
// VerifyClientConsensusState verifies a proof of the consensus state of the |
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.
Aye. This is true of all of the verifyXYZ
functions; they all verify some state stored by the solo machine.
if len(sd.Signature) == 0 { | ||
return sdkerrors.Wrap(ErrInvalidSignatureAndData, "signature cannot be empty") | ||
} | ||
if len(sd.Data) == 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.
At the moment that would be invalid, so this check is fine
@@ -0,0 +1,217 @@ | |||
package types |
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 should have thought about this earlier, but I wonder if we should make these all proto structs instead of this kinda-arbitrary bytestring concatenation encoding? cc @warner any thoughts?
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 can be deferred to a follow-up, though, since this file is nicely abstracted (thanks)
consensusState := &ConsensusState{ | ||
// increment sequence number | ||
Sequence: clientState.ConsensusState.Sequence + 1, | ||
PublicKey: header.NewPublicKey, |
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 won't really be up to date since a header update is only used to change the public key
…-solo-machine-client
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.
ACK modulo follow-ups
Finally! this is awesome 🙌 So excited |
Description
closes: #5382
old-pr: #6115
Before we can merge this PR, please make sure that all the following items have been checked off. If any of the checklist items are not applicable, please leave them but write a little note why.
docs/
) or specification (x/<module>/spec/
)godoc
comments.Unreleased
section inCHANGELOG.md
Files changed
in the Github PR explorer