Skip to content

Commit

Permalink
feat(ccev): implement mutilchain light client
Browse files Browse the repository at this point in the history
  • Loading branch information
happycoder9345 committed Sep 21, 2024
1 parent ee65c41 commit 375822f
Show file tree
Hide file tree
Showing 22 changed files with 6,093 additions and 0 deletions.
20 changes: 20 additions & 0 deletions proto/lorenzo/ccev/v1/genesis.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
syntax = "proto3";
package lorenzo.ccev.v1;

import "lorenzo/ccev/v1/params.proto";
import "lorenzo/ccev/v1/state.proto";

option go_package = "github.com/Lorenzo-Protocol/lorenzo/v3/x/ccev/types";

message ChainState {
lorenzo.ccev.v1.Client client = 1;
repeated lorenzo.ccev.v1.TinyHeader headers = 2;
repeated lorenzo.ccev.v1.CrossChainContract contracts = 3;
}

// GenesisState defines the ccev state
message GenesisState {
lorenzo.ccev.v1.Params params = 1;
// chain_states defines the chain state
repeated lorenzo.ccev.v1.ChainState chain_states = 2;
}
14 changes: 14 additions & 0 deletions proto/lorenzo/ccev/v1/params.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
syntax = "proto3";
package lorenzo.ccev.v1;

import "gogoproto/gogo.proto";

option go_package = "github.com/Lorenzo-Protocol/lorenzo/v3/x/ccev/types";

// Params defines the parameters for the module.
message Params {
option (gogoproto.equal) = true;

// list of people who can update client state information
repeated string allow_list = 1;
}
25 changes: 25 additions & 0 deletions proto/lorenzo/ccev/v1/query.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
syntax = "proto3";
package lorenzo.ccev.v1;

import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "lorenzo/ccev/v1/params.proto";

option go_package = "github.com/Lorenzo-Protocol/lorenzo/v3/x/ccev/types";

// Query defines the gRPC querier service.
service Query {
// Params queries the parameters of the module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/lorenzo/ccev/v1/params";
}
}

// QueryParamsRequest is the request type for the Query/Params RPC method.
message QueryParamsRequest {}

// QueryParamsResponse is the response type for the Query/Params RPC method.
message QueryParamsResponse {
// params holds all the parameters of this module.
Params params = 1 [ (gogoproto.nullable) = false ];
}
40 changes: 40 additions & 0 deletions proto/lorenzo/ccev/v1/state.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
syntax = "proto3";
package lorenzo.ccev.v1;

import "gogoproto/gogo.proto";

option go_package = "github.com/Lorenzo-Protocol/lorenzo/v3/x/ccev/types";

message TinyHeader {
option (gogoproto.goproto_getters) = false;

// hash defines the header hash
bytes hash = 1;
// number defines the block number
uint64 number = 2;
// receipt_root defines the receipts merkle root hash
bytes receipt_root = 4;
}

// Client defines the chain light client state
message Client {
// chain_id defines the target chain id
uint32 chain_id = 1;
// chain_name defines the target chain name
string chain_name = 2;
// the initial block
lorenzo.ccev.v1.TinyHeader initial_block = 3 [ (gogoproto.nullable) = false ];
;
}

// CrossChainContract defines the cross chain contract
message CrossChainContract {
// chain_id defines the target chain id
uint32 chain_id = 1;
// the stake plan hub contract address
bytes address = 2;
// event_name defines the event name
string event_name = 3;
// abi defines the contract abi
bytes abi = 4;
}
107 changes: 107 additions & 0 deletions proto/lorenzo/ccev/v1/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
syntax = "proto3";
package lorenzo.ccev.v1;

import "gogoproto/gogo.proto";
import "cosmos/msg/v1/msg.proto";
import "lorenzo/ccev/v1/params.proto";
import "lorenzo/ccev/v1/state.proto";
import "cosmos_proto/cosmos.proto";

option go_package = "github.com/Lorenzo-Protocol/lorenzo/v3/x/ccev/types";

// Msg defines the Msg service.
service Msg {
option (cosmos.msg.v1.service) = true;

// CreateClient defines the message for creating a lightclient for target
// chain
rpc CreateClient(MsgCreateClient) returns (MsgCreateClientResponse) {};

// UploadCrossChainContract defines the message for uploading a
// CrossChainContract
rpc UploadCrossChainContract(MsgUploadCrossChainContract)
returns (MsgUploadCrossChainContractResponse) {};

// UploadHeaders adds a batch of headers to the bnb light client chain
rpc UploadHeaders(MsgUploadHeaders) returns (MsgUploadHeadersResponse) {};

// UpdateParams defines a method for updating bnb light client module
// parameters.
rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse);

// UpdateHeader defines a method for updating bnb light client header.
rpc UpdateHeader(MsgUpdateHeader) returns (MsgUpdateHeaderResponse);
}

// MsgCreateClient defines the message for creating a lightclient for target
// chain
message MsgCreateClient {
option (cosmos.msg.v1.signer) = "sender";

lorenzo.ccev.v1.Client client = 1 [ (gogoproto.nullable) = false ];
string sender = 2 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
}

// MsgCreateClientResponse defines the response for the CreateClient
// transaction
message MsgCreateClientResponse {}

// MsgUploadCrossChainContract defines the message for uploading a
// CrossChainContract
message MsgUploadCrossChainContract {
option (cosmos.msg.v1.signer) = "sender";

uint32 chain_id = 1;
string address = 2;
string event_name = 3;
bytes abi = 4;
string sender = 5 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
}

message MsgUploadCrossChainContractResponse {}

// MsgUploadHeaders defines the message for multiple incoming header bytes
message MsgUploadHeaders {
option (cosmos.msg.v1.signer) = "sender";

uint32 chain_id = 1;
repeated lorenzo.ccev.v1.TinyHeader headers = 2
[ (gogoproto.nullable) = false ];
string sender = 3 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
}

// MsgUploadHeadersResponse defines the response for the UploadHeaders
// transaction
message MsgUploadHeadersResponse {}

// MsgUpdateHeader defines the message for updating bnb light client header.
message MsgUpdateHeader {
option (cosmos.msg.v1.signer) = "sender";

uint32 chain_id = 1;
lorenzo.ccev.v1.TinyHeader header = 2 [ (gogoproto.nullable) = false ];
string sender = 3 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];
}

// MsgUpdateHeaderResponse defines the response for the UpdateHeader
// transaction
message MsgUpdateHeaderResponse {}

// MsgUpdateParams defines a message for updating fee module parameters.
message MsgUpdateParams {
option (cosmos.msg.v1.signer) = "authority";

// authority is the address of the governance account.
// just FYI: cosmos.AddressString marks that this field should use type alias
// for AddressString instead of string, but the functionality is not yet
// implemented in cosmos-proto
string authority = 1 [ (cosmos_proto.scalar) = "cosmos.AddressString" ];

// params defines the bnb light client parameters.
//
// NOTE: All parameters must be supplied.
lorenzo.ccev.v1.Params params = 2 [ (gogoproto.nullable) = false ];
}

// MsgUpdateParamsResponse is the response to the MsgUpdateParams message.
message MsgUpdateParamsResponse {}
58 changes: 58 additions & 0 deletions x/ccev/keeper/contract.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package keeper

import (
"github.com/Lorenzo-Protocol/lorenzo/v3/x/ccev/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
)

// UploadContract uploads a cross chain contract and saves it to the store.
// If the contract already exists, it will be overwritten.
func (k Keeper) UploadContract(
ctx sdk.Context,
chainID uint32,
address string,
eventName string,
abi []byte,
) {
contract := &types.CrossChainContract{
ChainId: chainID,
Address: common.Hex2Bytes(address),
EventName: eventName,
Abi: abi,
}
k.setCrossChainContract(ctx, contract)
}

func (k Keeper) setCrossChainContract(ctx sdk.Context, contract *types.CrossChainContract) {
store := k.clientStore(ctx, contract.ChainId)
store.Set(
types.KeyCrossChainContract(common.BytesToAddress(contract.Address)),
k.cdc.MustMarshal(contract),
)
}

func (k Keeper) getCrossChainContract(
ctx sdk.Context,
chainID uint32,
address common.Address,
) *types.CrossChainContract {
store := k.clientStore(ctx, chainID)
bz := store.Get(types.KeyCrossChainContract(address))
if bz == nil {
return nil
}
var contract types.CrossChainContract
k.cdc.MustUnmarshal(bz, &contract)
return &contract
}

func (k Keeper) setEvent(ctx sdk.Context, chainID uint32, contract []byte, identify string) {
store := k.clientStore(ctx, chainID)
store.Set(types.KeyEvent(contract, identify), []byte{0x01})
}

func (k Keeper) hasEvent(ctx sdk.Context, chainID uint32, contract []byte, identify string) bool {
store := k.clientStore(ctx, chainID)
return store.Has(types.KeyEvent(contract, identify))
}
Loading

0 comments on commit 375822f

Please sign in to comment.