Skip to content

Commit

Permalink
Merge pull request #21 from datachainlab/improve-elc-spec
Browse files Browse the repository at this point in the history
Improve elc spec

Signed-off-by: Jun Kimura <[email protected]>
  • Loading branch information
bluele authored Sep 21, 2022
2 parents 2a5b4c1 + ddba97c commit 77d27b5
Show file tree
Hide file tree
Showing 19 changed files with 229 additions and 138 deletions.
8 changes: 6 additions & 2 deletions go/light-clients/lcp/types/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ func (cs ClientState) CheckHeaderAndUpdateForUpdateClient(ctx sdk.Context, cdc c
return nil, nil, err
}

if !cs.LatestHeight.IsZero() {
if cs.LatestHeight.IsZero() {
if len(commitment.NewState) == 0 {
return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidHeader, "invalid header %v: the commitment's `NewState` must be non-nil", header)
}
} else {
if commitment.PrevHeight == nil || commitment.PrevStateID == nil {
return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidHeader, "invalid header %v", header)
return nil, nil, sdkerrors.Wrapf(clienttypes.ErrInvalidHeader, "invalid header %v: the commitment's `PrevHeight` and `PrevStateID` must be non-nil", header)
}
prevConsensusState, err := GetConsensusState(store, cdc, commitment.PrevHeight)
if err != nil {
Expand Down
122 changes: 79 additions & 43 deletions go/relay/elc/tx.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions go/relay/lcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"github.com/hyperledger-labs/yui-relayer/core"
)

func (pr *Prover) syncUpstreamHeader(height int64) (*elc.MsgUpdateClientResponse, error) {
func (pr *Prover) syncUpstreamHeader(height int64, includeState bool) (*elc.MsgUpdateClientResponse, error) {

// 1. check if the latest height of the client is less than the given height

Expand Down Expand Up @@ -52,8 +52,9 @@ func (pr *Prover) syncUpstreamHeader(height int64) (*elc.MsgUpdateClientResponse
// 3. send a request that contains a header from 2 to update the client in ELC

return pr.lcpServiceClient.UpdateClient(context.TODO(), &elc.MsgUpdateClient{
ClientId: pr.config.ElcClientId,
Header: anyHeader,
ClientId: pr.config.ElcClientId,
Header: anyHeader,
IncludeState: includeState,
})
}

Expand Down Expand Up @@ -103,7 +104,7 @@ func activateClient(pathEnd *core.PathEnd, src, dst *core.ProvableChain) error {

// LCP synchronizes with the latest header of the upstream chain

res, err := srcProver.syncUpstreamHeader(latestHeight)
res, err := srcProver.syncUpstreamHeader(latestHeight, true)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions go/relay/prover.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ func (pr *Prover) QueryPacketCommitmentWithProof(height int64, seq uint64) (comR
if err := pr.initServiceClient(); err != nil {
return nil, err
}
if _, err := pr.syncUpstreamHeader(height); err != nil {
if _, err := pr.syncUpstreamHeader(height, false); err != nil {
return nil, err
}

Expand Down Expand Up @@ -360,7 +360,7 @@ func (pr *Prover) QueryPacketAcknowledgementCommitmentWithProof(height int64, se
if err := pr.initServiceClient(); err != nil {
return nil, err
}
if _, err := pr.syncUpstreamHeader(height); err != nil {
if _, err := pr.syncUpstreamHeader(height, false); err != nil {
return nil, err
}

Expand Down
19 changes: 19 additions & 0 deletions modules/commitments/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,28 @@ pub struct UpdateClientCommitmentProof {
}

impl UpdateClientCommitmentProof {
pub fn new(commitment_bytes: Vec<u8>, signer: Vec<u8>, signature: Vec<u8>) -> Self {
Self {
commitment_bytes,
signer,
signature,
}
}

pub fn new_with_no_signature(commitment_bytes: Vec<u8>) -> Self {
Self {
commitment_bytes,
..Default::default()
}
}

pub fn commitment(&self) -> UpdateClientCommitment {
UpdateClientCommitment::from_bytes(&self.commitment_bytes).unwrap()
}

pub fn is_proven(&self) -> bool {
!self.signature.is_empty()
}
}

#[derive(Serialize, Deserialize, Debug, Default)]
Expand Down
6 changes: 3 additions & 3 deletions modules/commitments/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ pub fn prove_update_client_commitment(
signer.use_verifier(&mut |verifier: &dyn Verifier| {
signer_address = verifier.get_address();
});
Ok(UpdateClientCommitmentProof {
Ok(UpdateClientCommitmentProof::new(
commitment_bytes,
signer: signer_address,
signer_address,
signature,
})
))
}

pub fn prove_state_commitment(
Expand Down
2 changes: 2 additions & 0 deletions modules/enclave-commands/src/light_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl TryFrom<MsgCreateClient> for InitClientInput {
pub struct UpdateClientInput {
pub client_id: ClientId,
pub any_header: Any,
pub include_state: bool,
pub current_timestamp: Time,
}

Expand All @@ -70,6 +71,7 @@ impl TryFrom<MsgUpdateClient> for UpdateClientInput {
Ok(Self {
client_id,
any_header,
include_state: msg.include_state,
current_timestamp: Time::now(),
})
}
Expand Down
14 changes: 10 additions & 4 deletions modules/handler/src/light_client/init_client.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::light_client::LightClientHandlerError as Error;
use commitments::prover::prove_update_client_commitment;
use commitments::UpdateClientCommitmentProof;
use context::Context;
use core::str::FromStr;
use enclave_commands::{InitClientInput, InitClientResult, LightClientResult};
Expand All @@ -17,9 +18,10 @@ pub fn init_client<'l, S: KVStore, L: LightClientSource<'l>>(
ctx.set_timestamp(input.current_timestamp);

let any_client_state: Any = input.any_client_state.into();
let any_consensus_state: Any = input.any_consensus_state.into();
let lc = L::get_light_client(&any_client_state.type_url).unwrap();
let ek = ctx.get_enclave_key();
let res = lc.create_client(ctx, any_client_state, input.any_consensus_state.into())?;
let res = lc.create_client(ctx, any_client_state.clone(), any_consensus_state.clone())?;
let client_id = gen_client_id(
lc.client_type(),
ctx.client_counter().map_err(Error::ICS02Error)?,
Expand All @@ -28,17 +30,21 @@ pub fn init_client<'l, S: KVStore, L: LightClientSource<'l>>(

ctx.store_client_type(client_id.clone(), lc.client_type())
.map_err(Error::ICS02Error)?;
ctx.store_any_client_state(client_id.clone(), res.any_client_state)
ctx.store_any_client_state(client_id.clone(), any_client_state)
.map_err(Error::ICS02Error)?;
ctx.store_any_consensus_state(client_id.clone(), res.height, res.any_consensus_state)
ctx.store_any_consensus_state(client_id.clone(), res.height, any_consensus_state)
.map_err(Error::ICS02Error)?;
ctx.increase_client_counter();
ctx.store_update_time(client_id.clone(), res.height, ctx.host_timestamp())
.map_err(Error::ICS02Error)?;
ctx.store_update_height(client_id.clone(), res.height, ctx.host_height())
.map_err(Error::ICS02Error)?;

let proof = prove_update_client_commitment(ek, res.commitment)?;
let proof = if res.prove {
prove_update_client_commitment(ek, res.commitment)?
} else {
UpdateClientCommitmentProof::new_with_no_signature(res.commitment.to_vec())
};
Ok(LightClientResult::InitClient(InitClientResult {
client_id,
proof,
Expand Down
13 changes: 10 additions & 3 deletions modules/handler/src/light_client/update_client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::registry::get_light_client_by_client_id;
use crate::light_client::LightClientHandlerError as Error;
use commitments::prover::prove_update_client_commitment;
use commitments::{prover::prove_update_client_commitment, UpdateClientCommitmentProof};
use context::Context;
use enclave_commands::{LightClientResult, UpdateClientInput, UpdateClientResult};
use light_client::{ClientKeeper, ClientReader, LightClientSource};
Expand All @@ -15,7 +15,10 @@ pub fn update_client<'l, S: KVStore, L: LightClientSource<'l>>(
let lc = get_light_client_by_client_id::<_, L>(ctx, &input.client_id)?;

let ek = ctx.get_enclave_key();
let res = lc.update_client(ctx, input.client_id.clone(), input.any_header.into())?;
let mut res = lc.update_client(ctx, input.client_id.clone(), input.any_header.into())?;
if input.include_state && res.commitment.new_state.is_none() {
res.commitment.new_state = Some(res.new_any_client_state.clone());
}

ctx.store_any_client_state(input.client_id.clone(), res.new_any_client_state)
.map_err(Error::ICS02Error)?;
Expand All @@ -30,6 +33,10 @@ pub fn update_client<'l, S: KVStore, L: LightClientSource<'l>>(
ctx.store_update_height(input.client_id, res.height, ctx.host_height())
.map_err(Error::ICS02Error)?;

let proof = prove_update_client_commitment(ek, res.commitment)?;
let proof = if res.prove {
prove_update_client_commitment(ek, res.commitment)?
} else {
UpdateClientCommitmentProof::new_with_no_signature(res.commitment.to_vec())
};
Ok(LightClientResult::UpdateClient(UpdateClientResult(proof)))
}
7 changes: 5 additions & 2 deletions modules/ibc-client/src/client_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,11 @@ impl LCPClient {
) -> Result<(ClientState, ConsensusState), Ics02Error> {
// TODO return an error instead of assertion

if !client_state.latest_height.is_zero() {
// if the client state's latest height is zero, the header's prev_* must be non-nil
if client_state.latest_height.is_zero() {
// if the client state's latest height is zero, the commitment's new_state must be non-nil
assert!(header.commitment.new_state.is_some());
} else {
// if the client state's latest height is non-zero, the commitment's prev_* must be non-nil
assert!(header.prev_height().is_some() && header.prev_state_id().is_some());
// check if the previous consensus state exists in the store
let prev_consensus_state: ConsensusState = ctx
Expand Down
Loading

0 comments on commit 77d27b5

Please sign in to comment.