diff --git a/go.mod b/go.mod index 40c278c..f48e981 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/datachainlab/lcp-go go 1.21 require ( + cosmossdk.io/core v0.11.0 cosmossdk.io/errors v1.0.1 cosmossdk.io/store v1.0.2 github.com/cosmos/cosmos-sdk v0.50.5 @@ -10,9 +11,8 @@ require ( github.com/cosmos/ibc-go/v8 v8.2.0 github.com/deckarep/golang-set/v2 v2.1.0 github.com/ethereum/go-ethereum v1.12.0 - github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/hyperledger-labs/yui-relayer v0.5.1 + github.com/hyperledger-labs/yui-relayer v0.5.3 github.com/oasisprotocol/oasis-core/go v0.2201.11 github.com/spf13/cobra v1.8.0 github.com/spf13/viper v1.18.2 @@ -28,7 +28,6 @@ require ( cloud.google.com/go/storage v1.36.0 // indirect cosmossdk.io/api v0.7.3 // indirect cosmossdk.io/collections v0.4.0 // indirect - cosmossdk.io/core v0.11.0 // indirect cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/log v1.3.1 // indirect cosmossdk.io/math v1.3.0 // indirect @@ -103,6 +102,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/handlers v1.5.2 // indirect + github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect diff --git a/go.sum b/go.sum index 5159921..393cc00 100644 --- a/go.sum +++ b/go.sum @@ -707,8 +707,8 @@ github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0Jr github.com/huandu/skiplist v1.2.0 h1:gox56QD77HzSC0w+Ws3MH3iie755GBJU1OER3h5VsYw= github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXMrPiHF9w= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/hyperledger-labs/yui-relayer v0.5.1 h1:3F5PEdyV4VyHOjW4s8KFja9acNMm6zmu5JEEGP+zeB0= -github.com/hyperledger-labs/yui-relayer v0.5.1/go.mod h1:GeCb1dtZjtQdkBNw1L9+LAUHzNQQhQK+kkoOnZYffw0= +github.com/hyperledger-labs/yui-relayer v0.5.3 h1:K7lcqkaqsGtpXImcz/cuClZsTtWCobLC9zh76KGzhP8= +github.com/hyperledger-labs/yui-relayer v0.5.3/go.mod h1:GeCb1dtZjtQdkBNw1L9+LAUHzNQQhQK+kkoOnZYffw0= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= diff --git a/light-clients/lcp/types/message.go b/light-clients/lcp/types/message.go index b5eca91..1c05948 100644 --- a/light-clients/lcp/types/message.go +++ b/light-clients/lcp/types/message.go @@ -3,6 +3,7 @@ package types import ( "bytes" "encoding/binary" + "encoding/json" "fmt" "math/big" "time" @@ -95,18 +96,26 @@ var ( type StateID [32]byte +func (id StateID) String() string { + return fmt.Sprintf("0x%x", id[:]) +} + func (id StateID) EqualBytes(bz []byte) bool { return bytes.Equal(id[:], bz) } +func (id StateID) MarshalJSON() ([]byte, error) { + return []byte(fmt.Sprintf("\"%s\"", id.String())), nil +} + type UpdateStateProxyMessage struct { - PrevHeight *clienttypes.Height - PrevStateID *StateID - PostHeight clienttypes.Height - PostStateID StateID - Timestamp *big.Int - Context ValidationContext - EmittedStates []EmittedState + PrevHeight *clienttypes.Height `json:"prev_height"` + PrevStateID *StateID `json:"prev_state_id"` + PostHeight clienttypes.Height `json:"post_height"` + PostStateID StateID `json:"post_state_id"` + Timestamp *big.Int `json:"timestamp"` + Context ValidationContext `json:"context"` + EmittedStates []EmittedState `json:"emitted_states"` } type EmittedState struct { @@ -114,6 +123,20 @@ type EmittedState struct { State codectypes.Any } +func (es EmittedState) MarshalJSON() ([]byte, error) { + var es2 struct { + Height clienttypes.Height `json:"height"` + State struct { + TypeUrl string `json:"type_url"` + Value []byte `json:"value"` + } `json:"state"` + } + es2.Height = es.Height + es2.State.TypeUrl = es.State.TypeUrl + es2.State.Value = es.State.Value + return json.Marshal(es2) +} + type MisbehaviourProxyMessage struct { PrevStates []struct { Height clienttypes.Height @@ -139,10 +162,24 @@ func (EmptyValidationContext) Validate(time.Time) error { // TrustingPeriodValidationContext is the commitment context for a commitment that requires the current time to be within the trusting period. type TrustingPeriodValidationContext struct { - UntrustedHeaderTimestamp time.Time - TrustedStateTimestamp time.Time - TrustingPeriod big.Int - ClockDrift big.Int + UntrustedHeaderTimestamp time.Time `json:"untrusted_header_timestamp"` + TrustedStateTimestamp time.Time `json:"trusted_state_timestamp"` + TrustingPeriod big.Int `json:"trusting_period"` + ClockDrift big.Int `json:"clock_drift"` +} + +func (c TrustingPeriodValidationContext) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + UntrustedHeaderTimestamp *big.Int `json:"untrusted_header_timestamp"` + TrustedStateTimestamp *big.Int `json:"trusted_state_timestamp"` + TrustingPeriod *big.Int `json:"trusting_period"` + ClockDrift *big.Int `json:"clock_drift"` + }{ + UntrustedHeaderTimestamp: big.NewInt(c.UntrustedHeaderTimestamp.UnixNano()), + TrustedStateTimestamp: big.NewInt(c.TrustedStateTimestamp.UnixNano()), + TrustingPeriod: &c.TrustingPeriod, + ClockDrift: &c.ClockDrift, + }) } func DecodeTrustingPeriodValidationContext(timestamps, params [32]byte) *TrustingPeriodValidationContext { diff --git a/relay/cmd.go b/relay/cmd.go index 0e68083..a82949e 100644 --- a/relay/cmd.go +++ b/relay/cmd.go @@ -2,6 +2,8 @@ package relay import ( "context" + "encoding/json" + "fmt" "github.com/hyperledger-labs/yui-relayer/config" "github.com/hyperledger-labs/yui-relayer/core" @@ -110,7 +112,16 @@ func createELCCmd(ctx *config.Context) *cobra.Command { target = c[dst] } prover := target.Prover.(*Prover) - return prover.doCreateELC(viper.GetUint64(flagHeight)) + out, err := prover.doCreateELC(viper.GetUint64(flagHeight)) + if err != nil { + return err + } + bz, err := json.Marshal(out) + if err != nil { + return err + } + fmt.Println(string(bz)) + return nil }, } return heightFlag(srcFlag(cmd)) @@ -138,7 +149,16 @@ func updateELCCmd(ctx *config.Context) *cobra.Command { counterparty = c[src] } prover := target.Prover.(*Prover) - return prover.doUpdateELC(viper.GetString(flagELCClientID), counterparty) + out, err := prover.doUpdateELC(viper.GetString(flagELCClientID), counterparty) + if err != nil { + return err + } + bz, err := json.Marshal(out) + if err != nil { + return err + } + fmt.Println(string(bz)) + return nil }, } return elcClientIDFlag(srcFlag(cmd)) diff --git a/relay/db.go b/relay/db.go index 79fc67a..438b7fc 100644 --- a/relay/db.go +++ b/relay/db.go @@ -5,12 +5,12 @@ import ( "encoding/json" "errors" "fmt" - "log" "os" "path/filepath" "github.com/datachainlab/lcp-go/relay/enclave" "github.com/hyperledger-labs/yui-relayer/core" + "github.com/hyperledger-labs/yui-relayer/log" ) const ( @@ -37,7 +37,7 @@ func (pr *Prover) lastEnclaveKeyInfoFilePath(finalized bool) string { } } -func (pr *Prover) loadLastFinalizedEnclaveKey(ctx context.Context) (*enclave.EnclaveKeyInfo, error) { +func (pr *Prover) loadLastFinalizedEnclaveKey(context.Context) (*enclave.EnclaveKeyInfo, error) { path := pr.lastEnclaveKeyInfoFilePath(true) bz, err := os.ReadFile(path) if err != nil { @@ -53,7 +53,7 @@ func (pr *Prover) loadLastFinalizedEnclaveKey(ctx context.Context) (*enclave.Enc return &eki, nil } -func (pr *Prover) loadLastUnfinalizedEnclaveKey(ctx context.Context) (*enclave.EnclaveKeyInfo, core.MsgID, error) { +func (pr *Prover) loadLastUnfinalizedEnclaveKey(context.Context) (*enclave.EnclaveKeyInfo, core.MsgID, error) { path := pr.lastEnclaveKeyInfoFilePath(false) bz, err := os.ReadFile(path) if err != nil { @@ -73,8 +73,8 @@ func (pr *Prover) loadLastUnfinalizedEnclaveKey(ctx context.Context) (*enclave.E return ueki.Info, unfinalizedMsgID, nil } -func (pr *Prover) saveFinalizedEnclaveKeyInfo(ctx context.Context, eki *enclave.EnclaveKeyInfo) error { - log.Println("save finalized enclave key info") +func (pr *Prover) saveFinalizedEnclaveKeyInfo(_ context.Context, eki *enclave.EnclaveKeyInfo) error { + log.GetLogger().Info("save finalized enclave key info") bz, err := json.Marshal(eki) if err != nil { return err @@ -82,8 +82,8 @@ func (pr *Prover) saveFinalizedEnclaveKeyInfo(ctx context.Context, eki *enclave. return os.WriteFile(pr.lastEnclaveKeyInfoFilePath(true), bz, 0600) } -func (pr *Prover) saveUnfinalizedEnclaveKeyInfo(ctx context.Context, eki *enclave.EnclaveKeyInfo, msgID core.MsgID) error { - log.Println("save unfinalized enclave key info") +func (pr *Prover) saveUnfinalizedEnclaveKeyInfo(_ context.Context, eki *enclave.EnclaveKeyInfo, msgID core.MsgID) error { + log.GetLogger().Info("save unfinalized enclave key info") msgIDBytes, err := pr.codec.MarshalInterface(msgID) if err != nil { return err @@ -98,9 +98,9 @@ func (pr *Prover) saveUnfinalizedEnclaveKeyInfo(ctx context.Context, eki *enclav return os.WriteFile(pr.lastEnclaveKeyInfoFilePath(false), bz, 0600) } -func (pr *Prover) removeFinalizedEnclaveKeyInfo(ctx context.Context) error { +func (pr *Prover) removeFinalizedEnclaveKeyInfo(context.Context) error { path := pr.lastEnclaveKeyInfoFilePath(true) - log.Printf("remove finalized enclave key info: %v", path) + log.GetLogger().Info("remove finalized enclave key info", "path", path) if _, err := os.Stat(path); err != nil { if os.IsNotExist(err) { return nil @@ -110,9 +110,9 @@ func (pr *Prover) removeFinalizedEnclaveKeyInfo(ctx context.Context) error { return os.Remove(path) } -func (pr *Prover) removeUnfinalizedEnclaveKeyInfo(ctx context.Context) error { +func (pr *Prover) removeUnfinalizedEnclaveKeyInfo(context.Context) error { path := pr.lastEnclaveKeyInfoFilePath(false) - log.Printf("remove unfinalized enclave key info: %v", path) + log.GetLogger().Info("remove unfinalized enclave key info", "path", path) if _, err := os.Stat(path); err != nil { if os.IsNotExist(err) { return nil diff --git a/relay/lcp.go b/relay/lcp.go index 2de88cd..4754217 100644 --- a/relay/lcp.go +++ b/relay/lcp.go @@ -2,9 +2,9 @@ package relay import ( "context" + "encoding/hex" "errors" "fmt" - "log" "time" sdk "github.com/cosmos/cosmos-sdk/types" @@ -13,6 +13,7 @@ import ( ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" mapset "github.com/deckarep/golang-set/v2" "github.com/hyperledger-labs/yui-relayer/core" + "github.com/hyperledger-labs/yui-relayer/log" oias "github.com/oasisprotocol/oasis-core/go/common/sgx/ias" lcptypes "github.com/datachainlab/lcp-go/light-clients/lcp/types" @@ -27,7 +28,7 @@ func (pr *Prover) UpdateEKIfNeeded(ctx context.Context, verifier core.FinalityAw if err != nil { return err } - log.Printf("loadEKIAndCheckUpdateNeeded: updateNeeded=%v", updateNeeded) + log.GetLogger().Info("loadEKIAndCheckUpdateNeeded", "updateNeeded", updateNeeded) if !updateNeeded { return nil } @@ -37,13 +38,13 @@ func (pr *Prover) UpdateEKIfNeeded(ctx context.Context, verifier core.FinalityAw pr.activeEnclaveKey, pr.unfinalizedMsgID = nil, nil - log.Println("need to get a new enclave key") + log.GetLogger().Info("need to get a new enclave key") eki, err := pr.selectNewEnclaveKey(ctx) if err != nil { return err } - log.Printf("selected available enclave key: %#v", eki) + log.GetLogger().Info("selected available enclave key", "eki", eki) msgID, err := pr.registerEnclaveKey(verifier, eki) if err != nil { @@ -82,17 +83,17 @@ func (pr *Prover) checkEKIUpdateNeeded(ctx context.Context, timestamp time.Time, // TODO consider appropriate buffer time updateTime := attestationTime.Add(time.Duration(pr.config.KeyExpiration) * time.Second / 2) - log.Printf("checkEKIUpdateNeeded: enclave_key=%x now=%v attestation_time=%v expiration=%v update_time=%v", eki.EnclaveKeyAddress, timestamp.Unix(), attestationTime.Unix(), pr.config.KeyExpiration, updateTime.Unix()) + log.GetLogger().Info("checkEKIUpdateNeeded", "enclave_key", hex.EncodeToString(eki.EnclaveKeyAddress), "now", timestamp.Unix(), "attestation_time", attestationTime.Unix(), "expiration", pr.config.KeyExpiration, "update_time", updateTime.Unix()) // For now, a half of expiration is used as a buffer time if timestamp.After(updateTime) { - log.Printf("checkEKIUpdateNeeded: enclave key '%x' is expired", eki.EnclaveKeyAddress) + log.GetLogger().Info("checkEKIUpdateNeeded: enclave key is expired", "enclave_key", hex.EncodeToString(eki.EnclaveKeyAddress)) return true } // check if the enclave key is still available in the LCP service _, err := pr.lcpServiceClient.EnclaveKey(ctx, &enclave.QueryEnclaveKeyRequest{EnclaveKeyAddress: eki.EnclaveKeyAddress}) if err != nil { - log.Printf("checkEKIUpdateNeeded: enclave key '%x' not found: error=%v", eki.EnclaveKeyAddress, err) + log.GetLogger().Warn("checkEKIUpdateNeeded: enclave key not found", "enclave_key", hex.EncodeToString(eki.EnclaveKeyAddress), "error", err) return true } return false @@ -112,7 +113,7 @@ func checkMsgStatus(verifier core.FinalityAwareChain, msgID core.MsgID) (bool, b if err != nil { return false, false, err } else if ok, failureReason := msgRes.Status(); !ok { - log.Printf("msg(%s) execution failed: %v", msgID.String(), failureReason) + log.GetLogger().Warn("msg execution failed", "msg_id", msgID.String(), "reason", failureReason) return false, false, nil } return msgRes.BlockHeight().LTE(lfHeader.GetHeight()), true, nil @@ -128,23 +129,23 @@ func (pr *Prover) loadEKIAndCheckUpdateNeeded(ctx context.Context, verifier core // 2: load the last finalized enclave key if exists // 3: select a new enclave key from the LCP service (i.e. return true) - log.Println("no active enclave key in memory") + log.GetLogger().Info("no active enclave key in memory") if eki, msgID, err := pr.loadLastUnfinalizedEnclaveKey(ctx); err == nil { - log.Println("load last unfinalized enclave key into memory") + log.GetLogger().Info("load last unfinalized enclave key into memory") pr.activeEnclaveKey = eki pr.unfinalizedMsgID = msgID } else if errors.Is(err, ErrEnclaveKeyInfoNotFound) { - log.Println("no unfinalized enclave key info found") + log.GetLogger().Info("no unfinalized enclave key info found") eki, err := pr.loadLastFinalizedEnclaveKey(ctx) if err != nil { if errors.Is(err, ErrEnclaveKeyInfoNotFound) { - log.Println("no enclave key info found") + log.GetLogger().Info("no enclave key info found") return true, nil } return false, err } - log.Println("load last finalized enclave key into memory") + log.GetLogger().Info("load last finalized enclave key into memory") pr.activeEnclaveKey = eki pr.unfinalizedMsgID = nil } else { @@ -154,18 +155,18 @@ func (pr *Prover) loadEKIAndCheckUpdateNeeded(ctx context.Context, verifier core // finalized enclave key if pr.unfinalizedMsgID == nil { - log.Println("active enclave key is finalized") + log.GetLogger().Info("active enclave key is finalized") // check if the enclave key is still available in the LCP service and not expired return pr.checkEKIUpdateNeeded(ctx, now, pr.activeEnclaveKey), nil } // unfinalized enclave key - log.Println("active enclave key is unfinalized") + log.GetLogger().Info("active enclave key is unfinalized") if _, err := verifier.GetMsgResult(pr.unfinalizedMsgID); err != nil { // err means that the msg is not included in the latest block - log.Printf("msg(%s) is not included in the latest block: error=%v", pr.unfinalizedMsgID.String(), err) + log.GetLogger().Info("the msg is not included in the latest block", "msg_id", pr.unfinalizedMsgID.String(), "error", err) if err := pr.removeUnfinalizedEnclaveKeyInfo(ctx); err != nil { return false, err } @@ -173,27 +174,27 @@ func (pr *Prover) loadEKIAndCheckUpdateNeeded(ctx context.Context, verifier core } finalized, success, err := checkMsgStatus(verifier, pr.unfinalizedMsgID) - log.Printf("check unfinalized msg(%s) status: finalized=%v success=%v error=%v", pr.unfinalizedMsgID.String(), finalized, success, err) + log.GetLogger().Info("check the unfinalized msg status", "msg_id", pr.unfinalizedMsgID.String(), "finalized", finalized, "success", success, "error", err) if err != nil { return false, err } else if !success { // tx is failed, so remove the unfinalized enclave key info - log.Printf("msg(%s) execution failed", pr.unfinalizedMsgID.String()) + log.GetLogger().Warn("the msg execution failed", "msg_id", pr.unfinalizedMsgID.String()) if err := pr.removeUnfinalizedEnclaveKeyInfo(ctx); err != nil { return false, err } return true, nil } else if finalized { // tx is successfully executed and finalized - log.Printf("msg(%s) is finalized", pr.unfinalizedMsgID.String()) + log.GetLogger().Info("the msg is finalized", "msg_id", pr.unfinalizedMsgID.String()) if pr.checkEKIUpdateNeeded(ctx, now, pr.activeEnclaveKey) { return true, nil } - log.Printf("save enclave key info as finalized: enclave key address=%x", pr.activeEnclaveKey.EnclaveKeyAddress) + log.GetLogger().Info("save enclave key info as finalized", "enclave_key", hex.EncodeToString(pr.activeEnclaveKey.EnclaveKeyAddress)) if err := pr.saveFinalizedEnclaveKeyInfo(ctx, pr.activeEnclaveKey); err != nil { return false, err } - log.Printf("remove old unfinalized enclave key info: enclave key address=%x", pr.activeEnclaveKey.EnclaveKeyAddress) + log.GetLogger().Info("remove old unfinalized enclave key info", "enclave_key", hex.EncodeToString(pr.activeEnclaveKey.EnclaveKeyAddress)) if err := pr.removeUnfinalizedEnclaveKeyInfo(ctx); err != nil { return false, err } @@ -201,7 +202,7 @@ func (pr *Prover) loadEKIAndCheckUpdateNeeded(ctx context.Context, verifier core return false, nil } else { // tx is successfully executed but not finalized yet - log.Printf("msg(%s) is not finalized yet", pr.unfinalizedMsgID.String()) + log.GetLogger().Info("the msg is not finalized yet", "msg_id", pr.unfinalizedMsgID.String()) return pr.checkEKIUpdateNeeded(ctx, now, pr.activeEnclaveKey), nil } } @@ -224,15 +225,15 @@ func (pr *Prover) selectNewEnclaveKey(ctx context.Context) (*enclave.EnclaveKeyI return nil, err } if pr.checkEKIUpdateNeeded(ctx, time.Now(), eki) { - log.Printf("key '%x' is not allowed to use because of expiration", eki.EnclaveKeyAddress) + log.GetLogger().Info("the key is not allowed to use because of expiration", "enclave_key", hex.EncodeToString(eki.EnclaveKeyAddress)) continue } if !pr.validateISVEnclaveQuoteStatus(avr.ISVEnclaveQuoteStatus) { - log.Printf("key '%x' is not allowed to use because of ISVEnclaveQuoteStatus: %v", eki.EnclaveKeyAddress, avr.ISVEnclaveQuoteStatus) + log.GetLogger().Info("the key is not allowed to use because of ISVEnclaveQuoteStatus", "enclave_key", hex.EncodeToString(eki.EnclaveKeyAddress), "quote_status", avr.ISVEnclaveQuoteStatus) continue } if !pr.validateAdvisoryIDs(avr.AdvisoryIDs) { - log.Printf("key '%x' is not allowed to use because of advisory IDs: %v", eki.EnclaveKeyAddress, avr.AdvisoryIDs) + log.GetLogger().Info("the key is not allowed to use because of advisory IDs", "enclave_key", hex.EncodeToString(eki.EnclaveKeyAddress), "advisory_ids", avr.AdvisoryIDs) continue } return eki, nil @@ -282,7 +283,7 @@ func (pr *Prover) updateELC(elcClientID string, includeState bool) ([]*elc.MsgUp return nil, nil } - log.Printf("try to setup headers: elc_client_id=%v current=%v latest=%v", elcClientID, clientState.GetLatestHeight(), latestHeader.GetHeight()) + log.GetLogger().Info("try to setup headers", "elc_client_id", elcClientID, "current", clientState.GetLatestHeight(), "latest", latestHeader.GetHeight()) // 2. query the header from the upstream chain @@ -346,66 +347,84 @@ func (pr *Prover) registerEnclaveKey(verifier core.Chain, eki *enclave.EnclaveKe return ids[0], nil } +type CreateELCResult struct { + ELCClientID string `json:"elc_client_id"` + Message *lcptypes.UpdateStateProxyMessage `json:"message"` +} + // height: 0 means the latest height -func (pr *Prover) doCreateELC(height uint64) error { +func (pr *Prover) doCreateELC(height uint64) (*CreateELCResult, error) { header, err := pr.originProver.GetLatestFinalizedHeader() if err != nil { - return err + return nil, err } latestHeight := header.GetHeight() if height == 0 { height = latestHeight.GetRevisionHeight() } else if height >= latestHeight.GetRevisionHeight() { - return fmt.Errorf("height %v is greater than the latest height %v", height, latestHeight.GetRevisionHeight()) + return nil, fmt.Errorf("height %v is greater than the latest height %v", height, latestHeight.GetRevisionHeight()) } h := clienttypes.NewHeight(latestHeight.GetRevisionNumber(), height) - log.Printf("try to create ELC client: height=%v", h) + log.GetLogger().Info("try to create ELC client", "height", h) res, err := pr.createELC(h) if err != nil { - return err + return nil, err } - log.Printf("created ELC client: %v", res.ClientId) + log.GetLogger().Info("created ELC client", "client_id", res.ClientId) // ensure the message is valid msg, err := lcptypes.EthABIDecodeHeaderedProxyMessage(res.Message) if err != nil { - return err + return nil, err } m, err := msg.GetUpdateStateProxyMessage() if err != nil { - return err + return nil, err } - log.Printf("created state: post_height=%v post_state_id=0x%x timestamp=%v", m.PostHeight, m.PostStateID, m.Timestamp.String()) - return err + log.GetLogger().Info("created state", "post_height", m.PostHeight, "post_state_id", m.PostStateID.String(), "timestamp", m.Timestamp.String()) + return &CreateELCResult{ + ELCClientID: res.ClientId, + Message: m, + }, nil +} + +type UpdateELCResult struct { + Messages []*lcptypes.UpdateStateProxyMessage `json:"messages"` } -func (pr *Prover) doUpdateELC(elcClientID string, counterparty core.FinalityAwareChain) error { +func (pr *Prover) doUpdateELC(elcClientID string, counterparty core.FinalityAwareChain) (*UpdateELCResult, error) { if err := pr.UpdateEKIfNeeded(context.TODO(), counterparty); err != nil { - return err + return nil, err } if elcClientID == "" { elcClientID = pr.config.ElcClientId } - log.Printf("try to update the ELC client: elc_client_id=%v", elcClientID) + log.GetLogger().Info("try to update the ELC client", "elc_client_id", elcClientID) updates, err := pr.updateELC(elcClientID, false) if err != nil { - return err + return nil, err } if len(updates) == 0 { - log.Println("no update is needed") - return nil + log.GetLogger().Info("no update is needed") + return &UpdateELCResult{ + Messages: []*lcptypes.UpdateStateProxyMessage{}, + }, nil } + var msgs []*lcptypes.UpdateStateProxyMessage for _, update := range updates { commitment, err := lcptypes.EthABIDecodeHeaderedProxyMessage(update.Message) if err != nil { - return err + return nil, err } - usm, err := commitment.GetUpdateStateProxyMessage() + msg, err := commitment.GetUpdateStateProxyMessage() if err != nil { - return err + return nil, err } - log.Printf("updated state: prev_height=%v prev_state_id=0x%x post_height=%v post_state_id=0x%x timestamp=%v", usm.PrevHeight, *usm.PrevStateID, usm.PostHeight, usm.PostStateID, usm.Timestamp.String()) + log.GetLogger().Info("updated state", "prev_height", msg.PrevHeight, "prev_state_id", msg.PrevStateID.String(), "post_height", msg.PostHeight, "post_state_id", msg.PostStateID.String(), "timestamp", msg.Timestamp.String()) + msgs = append(msgs, msg) } - return nil + return &UpdateELCResult{ + Messages: msgs, + }, nil } func (pr *Prover) createELC(height exported.Height) (*elc.MsgCreateClientResponse, error) { diff --git a/relay/restore.go b/relay/restore.go index d6aec16..e3de05d 100644 --- a/relay/restore.go +++ b/relay/restore.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "fmt" - "log" "reflect" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" @@ -12,6 +11,7 @@ import ( lcptypes "github.com/datachainlab/lcp-go/light-clients/lcp/types" "github.com/datachainlab/lcp-go/relay/elc" "github.com/hyperledger-labs/yui-relayer/core" + "github.com/hyperledger-labs/yui-relayer/log" ) func (pr *Prover) restoreELCState(ctx context.Context, counterparty core.FinalityAwareChain, height uint64) error { @@ -44,7 +44,7 @@ func (pr *Prover) restoreELCState(ctx context.Context, counterparty core.Finalit restoreHeight = clienttypes.NewHeight(cs.GetLatestHeight().GetRevisionNumber(), height) } - log.Printf("try to restore ELC state: height=%v", restoreHeight) + log.GetLogger().Info("try to restore ELC state", "height", restoreHeight) counterpartyConsRes, err := counterparty.QueryClientConsensusState(core.NewQueryContext(context.TODO(), cplatestHeight), restoreHeight) if err != nil { @@ -123,7 +123,7 @@ func (pr *Prover) restoreELCState(ctx context.Context, counterparty core.Finalit return fmt.Errorf("you must specify '%v' as elc_client_id, but got %v", res.ClientId, pr.config.ElcClientId) } - log.Printf("successfully restored ELC state: client_id=%v, state_id=%v, height=%v", res.ClientId, usm.PostStateID, usm.PostHeight) + log.GetLogger().Info("successfully restored ELC state", "client_id", res.ClientId, "state_id", usm.PostStateID.String(), "height", usm.PostHeight) return nil } diff --git a/tests/e2e/cases/tm2tm/configs/path.json b/tests/e2e/cases/tm2tm/configs/path.json index f8e0b89..1cf5cdd 100644 --- a/tests/e2e/cases/tm2tm/configs/path.json +++ b/tests/e2e/cases/tm2tm/configs/path.json @@ -1,18 +1,18 @@ { "src": { "chain-id": "ibc0", - "client-id": "lcp-client-0", - "connection-id": "connection-0", - "channel-id": "channel-0", + "client-id": "", + "connection-id": "", + "channel-id": "", "port-id": "transfer", "order": "unordered", "version": "ics20-1" }, "dst": { "chain-id": "ibc1", - "client-id": "lcp-client-0", - "connection-id": "connection-0", - "channel-id": "channel-0", + "client-id": "", + "connection-id": "", + "channel-id": "", "port-id": "transfer", "order": "unordered", "version": "ics20-1" diff --git a/tests/e2e/cases/tm2tm/scripts/test-elc-update b/tests/e2e/cases/tm2tm/scripts/test-elc-update index d69dd13..8af8cf9 100755 --- a/tests/e2e/cases/tm2tm/scripts/test-elc-update +++ b/tests/e2e/cases/tm2tm/scripts/test-elc-update @@ -4,19 +4,14 @@ set -eu RLY="${RLY_BIN} --debug" -output=$(${RLY} lcp create-elc ibc01 --src 2>&1) -if [[ ! $output =~ "created ELC client: 07-tendermint-2" ]]; then - echo "unexpected output: $output" - exit 1 -fi -output=$(${RLY} lcp create-elc ibc01 --src=false 2>&1) -if [[ ! $output =~ "created ELC client: 07-tendermint-3" ]]; then - echo "unexpected output: $output" - exit 1 -fi +src_elc_client_id=$(${RLY} lcp create-elc ibc01 --src | jq -r '.elc_client_id') +dst_elc_client_id=$(${RLY} lcp create-elc ibc01 --src=false | jq -r '.elc_client_id') + +echo "src: ELC client id: ${src_elc_client_id}" +echo "dst: ELC client id: ${dst_elc_client_id}" echo "sleeping for 5 seconds" sleep 5 -${RLY} lcp update-elc ibc01 --src --elc_client_id=07-tendermint-2 -${RLY} lcp update-elc ibc01 --src=false --elc_client_id=07-tendermint-3 +${RLY} lcp update-elc ibc01 --src --elc_client_id=${src_elc_client_id} +${RLY} lcp update-elc ibc01 --src=false --elc_client_id=${dst_elc_client_id}