From db376f547781d606e8153393b3cd4b7a576ad21c Mon Sep 17 00:00:00 2001
From: harry <53987565+h5law@users.noreply.github.com>
Date: Tue, 18 Jul 2023 20:24:58 +0100
Subject: [PATCH] Allow host introspection of its own ConsensusState

---
 ibc/client/queries.go               | 24 ++++++++++++++++++++++++
 shared/modules/ibc_client_module.go | 21 +++++++++++++--------
 2 files changed, 37 insertions(+), 8 deletions(-)

diff --git a/ibc/client/queries.go b/ibc/client/queries.go
index 2ea5b36dc..412e993a0 100644
--- a/ibc/client/queries.go
+++ b/ibc/client/queries.go
@@ -1,8 +1,10 @@
 package client
 
 import (
+	light_client_types "github.com/pokt-network/pocket/ibc/client/light_clients/types"
 	"github.com/pokt-network/pocket/ibc/client/types"
 	"github.com/pokt-network/pocket/ibc/path"
+	"github.com/pokt-network/pocket/shared/codec"
 	core_types "github.com/pokt-network/pocket/shared/core/types"
 	"github.com/pokt-network/pocket/shared/modules"
 )
@@ -32,3 +34,25 @@ func (c *clientManager) GetClientState(identifier string) (modules.ClientState,
 
 	return types.GetClientState(clientStore, identifier)
 }
+
+// GetHostConsensusState returns the ConsensusState at the given height for the
+// host chain, the Pocket network. It then serialises this and packs it into a
+// ConsensusState object for use in a WASM client
+func (c *clientManager) GetHostConsensusState(height modules.Height) (modules.ConsensusState, error) {
+	blockStore := c.GetBus().GetPersistenceModule().GetBlockStore()
+	block, err := blockStore.GetBlock(height.GetRevisionHeight())
+	if err != nil {
+		return nil, err
+	}
+	pocketConsState := &light_client_types.PocketConsensusState{
+		Timestamp:       block.BlockHeader.Timestamp,
+		StateHash:       block.BlockHeader.StateHash,
+		StateTreeHashes: block.BlockHeader.StateTreeHashes,
+		NextValSetHash:  block.BlockHeader.NextValSetHash,
+	}
+	consBz, err := codec.GetCodec().Marshal(pocketConsState)
+	if err != nil {
+		return nil, err
+	}
+	return types.NewConsensusState(consBz, uint64(pocketConsState.Timestamp.AsTime().UnixNano())), nil
+}
diff --git a/shared/modules/ibc_client_module.go b/shared/modules/ibc_client_module.go
index eee5aeb18..02f31a96e 100644
--- a/shared/modules/ibc_client_module.go
+++ b/shared/modules/ibc_client_module.go
@@ -23,8 +23,8 @@ type ClientManagerOption func(ClientManager)
 
 type clientManagerFactory = FactoryWithOptions[ClientManager, ClientManagerOption]
 
-// ClientManager is the interface that defines the methods needed to interact with an IBC light client
-// it manages the different lifecycle methods for the different clients
+// ClientManager is the interface that defines the methods needed to interact with an
+// IBC light client it manages the different lifecycle methods for the different clients
 // https://github.com/cosmos/ibc/tree/main/spec/core/ics-002-client-semantics
 type ClientManager interface {
 	Submodule
@@ -40,12 +40,6 @@ type ClientManager interface {
 	// the ClientMessage can be verified using the existing ClientState and ConsensusState
 	UpdateClient(identifier string, clientMessage ClientMessage) error
 
-	// GetConsensusState returns the ConsensusState at the given height for the given client
-	GetConsensusState(identifier string, height Height) (ConsensusState, error)
-
-	// GetClientState returns the ClientState for the given client
-	GetClientState(identifier string) (ClientState, error)
-
 	// UpgradeClient upgrades an existing client with the given identifier using the
 	// ClientState and ConsentusState provided. It can only do so if the new client
 	// was committed to by the old client at the specified upgrade height
@@ -54,6 +48,17 @@ type ClientManager interface {
 		clientState ClientState, consensusState ConsensusState,
 		proofUpgradeClient, proofUpgradeConsState []byte,
 	) error
+
+	// === Client Queries ===
+
+	// GetConsensusState returns the ConsensusState at the given height for the given client
+	GetConsensusState(identifier string, height Height) (ConsensusState, error)
+
+	// GetClientState returns the ClientState for the given client
+	GetClientState(identifier string) (ClientState, error)
+
+	// GetHostConsensusState returns the ConsensusState at the given height for the host chain
+	GetHostConsensusState(height Height) (ConsensusState, error)
 }
 
 // ClientState is an interface that defines the methods required by a clients