Skip to content
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

[WIP] adding change verifying key functionality #3010

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions 11-cometbls/codec.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package cometbls

import (
backend_bn254 "github.com/consensys/gnark/backend/groth16/bn254"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"

"github.com/cosmos/ibc-go/v8/modules/core/exported"
)

func RegisterCodec(cdc *codec.LegacyAmino) {
cdc.RegisterConcrete(&backend_bn254.VerifyingKey{}, "my_module/VerifyingKey", nil)
}

// RegisterInterfaces registers the tendermint concrete client-related
// implementations and interfaces.
func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
Expand All @@ -25,4 +31,9 @@ func RegisterInterfaces(registry codectypes.InterfaceRegistry) {
(*exported.ClientMessage)(nil),
&Misbehaviour{},
)

// registry.RegisterImplementations(
// (*sdk.Msg)(nil),
// &MsgMyFunction{},
// )
}
32 changes: 18 additions & 14 deletions 11-cometbls/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ import (

// IBC tendermint client sentinel errors
var (
ErrInvalidChainID = errorsmod.Register(ModuleName, 2, "invalid chain-id")
ErrInvalidTrustingPeriod = errorsmod.Register(ModuleName, 3, "invalid trusting period")
ErrInvalidUnbondingPeriod = errorsmod.Register(ModuleName, 4, "invalid unbonding period")
ErrInvalidHeaderHeight = errorsmod.Register(ModuleName, 5, "invalid header height")
ErrInvalidHeader = errorsmod.Register(ModuleName, 6, "invalid header")
ErrInvalidMaxClockDrift = errorsmod.Register(ModuleName, 7, "invalid max clock drift")
ErrProcessedTimeNotFound = errorsmod.Register(ModuleName, 8, "processed time not found")
ErrProcessedHeightNotFound = errorsmod.Register(ModuleName, 9, "processed height not found")
ErrDelayPeriodNotPassed = errorsmod.Register(ModuleName, 10, "packet-specified delay period has not been reached")
ErrTrustingPeriodExpired = errorsmod.Register(ModuleName, 11, "time since latest trusted state has passed the trusting period")
ErrUnbondingPeriodExpired = errorsmod.Register(ModuleName, 12, "time since latest trusted state has passed the unbonding period")
ErrInvalidProofSpecs = errorsmod.Register(ModuleName, 13, "invalid proof specs")
ErrInvalidValidatorSet = errorsmod.Register(ModuleName, 14, "invalid validator set")
ErrInvalidHeaderTimestamp = errorsmod.Register(ModuleName, 15, "invalid header timestamp")
ErrInvalidChainID = errorsmod.Register(ModuleName, 2, "invalid chain-id")
ErrInvalidTrustingPeriod = errorsmod.Register(ModuleName, 3, "invalid trusting period")
ErrInvalidUnbondingPeriod = errorsmod.Register(ModuleName, 4, "invalid unbonding period")
ErrInvalidHeaderHeight = errorsmod.Register(ModuleName, 5, "invalid header height")
ErrInvalidHeader = errorsmod.Register(ModuleName, 6, "invalid header")
ErrInvalidMaxClockDrift = errorsmod.Register(ModuleName, 7, "invalid max clock drift")
ErrProcessedTimeNotFound = errorsmod.Register(ModuleName, 8, "processed time not found")
ErrProcessedHeightNotFound = errorsmod.Register(ModuleName, 9, "processed height not found")
ErrDelayPeriodNotPassed = errorsmod.Register(ModuleName, 10, "packet-specified delay period has not been reached")
ErrTrustingPeriodExpired = errorsmod.Register(ModuleName, 11, "time since latest trusted state has passed the trusting period")
ErrUnbondingPeriodExpired = errorsmod.Register(ModuleName, 12, "time since latest trusted state has passed the unbonding period")
ErrInvalidProofSpecs = errorsmod.Register(ModuleName, 13, "invalid proof specs")
ErrInvalidValidatorSet = errorsmod.Register(ModuleName, 14, "invalid validator set")
ErrInvalidHeaderTimestamp = errorsmod.Register(ModuleName, 15, "invalid header timestamp")
ErrUnauthorized = errorsmod.Register(ModuleName, 16, "unauthorized")
ErrVerifyingKeyNotFound = errorsmod.Register(ModuleName, 17, "verifying key not found")
ErrInvalidVerifyingKeyDecode = errorsmod.Register(ModuleName, 18, "verifying key not found")
ErrInvalidVerifyingKeyVerify = errorsmod.Register(ModuleName, 19, "verifying key not found")
)
4 changes: 4 additions & 0 deletions 11-cometbls/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ module github.com/unionlabs/union/11-cometbls

go 1.21

toolchain go1.23.1

require (
cosmossdk.io/core v0.11.0
cosmossdk.io/errors v1.0.1
Expand All @@ -24,8 +26,10 @@ require (
require (
cosmossdk.io/api v0.7.4 // indirect
cosmossdk.io/collections v0.4.0 // indirect
cosmossdk.io/core/testing v0.0.0-20240920111503-465ca23154d5 // indirect
cosmossdk.io/depinject v1.0.0-alpha.4 // indirect
cosmossdk.io/math v1.3.0 // indirect
cosmossdk.io/schema v0.3.0 // indirect
cosmossdk.io/x/tx v0.13.2 // indirect
cosmossdk.io/x/upgrade v0.1.0 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions 11-cometbls/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s=
cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0=
cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo=
cosmossdk.io/core v0.11.0/go.mod h1:LaTtayWBSoacF5xNzoF8tmLhehqlA9z1SWiPuNC6X1w=
cosmossdk.io/core v1.0.0-alpha.3 h1:pnxaYAas7llXgVz1lM7X6De74nWrhNKnB3yMKe4OUUA=
cosmossdk.io/core v1.0.0-alpha.3/go.mod h1:3u9cWq1FAVtiiCrDPpo4LhR+9V6k/ycSG4/Y/tREWCY=
cosmossdk.io/core/testing v0.0.0-20240920111503-465ca23154d5 h1:BBr8YVUiMfs3kTzVsm8HZ3aZ4yUl0kvTohe/U7OZgnk=
cosmossdk.io/core/testing v0.0.0-20240920111503-465ca23154d5/go.mod h1:8s2tPeJtSiQuoyPmr2Ag7meikonISO4Fv4MoO8+ORrs=
cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98okJopc=
cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU=
cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0=
Expand All @@ -26,6 +30,8 @@ cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI=
cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM=
cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE=
cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k=
cosmossdk.io/schema v0.3.0 h1:01lcaM4trhzZ1HQTfTV8z6Ma1GziOZ/YmdzBN3F720c=
cosmossdk.io/schema v0.3.0/go.mod h1:RDAhxIeNB4bYqAlF4NBJwRrgtnciMcyyg0DOKnhNZQQ=
cosmossdk.io/store v1.1.0 h1:LnKwgYMc9BInn9PhpTFEQVbL9UK475G2H911CGGnWHk=
cosmossdk.io/store v1.1.0/go.mod h1:oZfW/4Fc/zYqu3JmQcQdUJ3fqu5vnYTn3LZFFy8P8ng=
cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs=
Expand Down
100 changes: 100 additions & 0 deletions 11-cometbls/keeper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package cometbls

import (
"bytes"
"encoding/hex"

"cosmossdk.io/collections"
errorsmod "cosmossdk.io/errors"
storetypes "cosmossdk.io/store/types"
backend_bn254 "github.com/consensys/gnark/backend/groth16/bn254"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/errors"
)

// Keeper defines the structure for your keeper
type Keeper struct {
storeKey storetypes.StoreKey
cdc codec.BinaryCodec
authority string
checksums collections.KeySet[[]byte]
}

// NewKeeper creates a new Keeper instance with authority
func NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey, authority string) Keeper {
return Keeper{
storeKey: storeKey,
cdc: cdc,
authority: authority,
}
}

// SetAuthority sets the governance authority in the store
func (k Keeper) SetAuthority(ctx sdk.Context, address sdk.AccAddress) {
store := ctx.KVStore(k.storeKey)
store.Set([]byte(AuthorityKey), address.Bytes())
}

// GetAuthority retrieves the governance authority from the store
func (k Keeper) GetAuthority(ctx sdk.Context) (sdk.AccAddress, error) {
store := ctx.KVStore(k.storeKey)
authorityBytes := store.Get([]byte(AuthorityKey))
if authorityBytes == nil {
return nil, errorsmod.Wrapf(ErrUnauthorized, "authority not set")
}

return sdk.AccAddress(authorityBytes), nil

}

func (k Keeper) SetVerifyingKey(ctx sdk.Context, msg *MsgMyFunction) error {
authority, err := k.GetAuthority(ctx)
if err != nil {
return err
}

if !msg.Sender.Equals(authority) {
return errorsmod.Wrap(errors.ErrUnauthorized, "sender is not authorized")
}

vkHex := msg.vkHex
vkBytes, err := hex.DecodeString(vkHex)
if err != nil {
return errorsmod.Wrapf(errors.ErrInvalidRequest, "could not decode the hex verifying key: '%s'", vkHex)
}

var verifyingKey backend_bn254.VerifyingKey
_, err = verifyingKey.ReadFrom(bytes.NewReader(vkBytes))
if err != nil {
return errorsmod.Wrapf(errors.ErrInvalidRequest, "could not read the verifying key: '%s'", vkHex)
}

var keyBuffer bytes.Buffer
_, err = verifyingKey.WriteTo(&keyBuffer)
if err != nil {
return errorsmod.Wrap(err, "failed to serialize the verifying key")
}

store := ctx.KVStore(k.storeKey)
store.Set([]byte("verifyingKey"), keyBuffer.Bytes())

return nil
}

func (k Keeper) GetVerifyingKey(ctx sdk.Context) (*backend_bn254.VerifyingKey, error) {
store := ctx.KVStore(k.storeKey)

vkBytes := store.Get([]byte("verifyingKey")) // Use the same key as when we stored it
if vkBytes == nil {
return nil, errorsmod.Wrapf(ErrVerifyingKeyNotFound, "verifying key not found")
}

var verifyingKey backend_bn254.VerifyingKey
_, err := verifyingKey.ReadFrom(bytes.NewReader(vkBytes))
if err != nil {
return nil, errorsmod.Wrapf(ErrVerifyingKeyNotFound, "failed to deserialize verifying key")
}

return &verifyingKey, nil
}
90 changes: 90 additions & 0 deletions 11-cometbls/keeper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package cometbls

import (
"bytes"
"encoding/hex"
"testing"

"cosmossdk.io/log"
"cosmossdk.io/store"
"cosmossdk.io/store/metrics"
storetypes "cosmossdk.io/store/types"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
dbm "github.com/cosmos/cosmos-db"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/address"
"github.com/stretchr/testify/require"
)

var (
verifyingKeyHex = "8967072901cc7ab63357f1ddc4196c7c1feda50540d8026d7f6f0167c118a899d923def15f75234f2a6d53b566a2528441e98050b38803673e9179b834fc39a499355fd270b7601d5d88408b7e9e53d260512e2180cd260017dc941f2fc96d65153f0344c6bf2d8a891b979bc61d39a98fb11155fcd57418f30ea018ea842874a0e76be91a3148e2f8ef644222b3ce5b939a73bd2e0a40814f7f92a79c483acf2216bbe0c289e07936b4d9653b91521a24c570c808fa46dfd12ec4429e71b61999fcfb245459d63a4923b8f8c488d1e6af7ca358867b88eb0cdefe896c221f09e95e4c18d1e0475de4549b2547611d8301e1afff1047a6f5a288c9314af0b9fc05d403c8c91820a385a72c18d6a4962cef41a3ab93daa7ed289b1e95db4d04eb00000003e71843e52743864f4bb67ce94a2ce8fe82c8f61042c4c1ced8531d94305392818b0dbe71f4d60e02e9160ec2b015cae3a09cbe4f437226e2c02e1a5e5d124bcac29e93d5f47c0c7671350398ed8c40f5bc5c2f5b00363c7e2eb18a91a1c490c70000000100000000a57df6f8132cb0037f7dfdf1a29b04c1ff92ba082eda513996ba2bfa9fbd198713f0d8d8879885ca567ef99298c30c397e6fba584658f4127713a814c06de55aefbfe141a7555cf7e3e86b092660b81cfb68a025ad817e45cec0b0f2e2ca636802a104df1c015f2307fa2859627098cdf9fdb521d61d323943343a12304e5baf"
)

func setupKeeper(t *testing.T) (sdk.Context, *Keeper, sdk.AccAddress) {
key := storetypes.NewKVStoreKey("cometbls")

db := dbm.NewMemDB()

cms := store.NewCommitMultiStore(db, log.NewNopLogger(), metrics.NewNoOpMetrics())

cms.MountStoreWithDB(key, storetypes.StoreTypeIAVL, db)

err := cms.LoadLatestVersion()
require.NoError(t, err)

registry := codectypes.NewInterfaceRegistry()
registry.RegisterInterface(sdk.MsgInterfaceProtoName, (*sdk.Msg)(nil))
RegisterInterfaces(registry)
cdc := codec.NewProtoCodec(registry)

authority := sdk.AccAddress(address.Module("authority"))
keeper := NewKeeper(cdc, key, authority.String())

ctx := sdk.NewContext(cms, cmtproto.Header{}, false, log.NewNopLogger())

keeper.SetAuthority(ctx, authority)

return ctx, &keeper, authority
}

func TestSetVerifyingKeyUnauthorized(t *testing.T) {
ctx, keeper, _ := setupKeeper(t)

unauthorizedSender := sdk.AccAddress(address.Module("unauthorized"))

param := NewMsgMyFunction(unauthorizedSender, verifyingKeyHex)
err := keeper.SetVerifyingKey(ctx, &param)

require.Error(t, err)
require.Contains(t, err.Error(), "unauthorized")
}

func TestGetVerifyingKeyNotSet(t *testing.T) {
ctx, keeper, _ := setupKeeper(t)

_, err := keeper.GetVerifyingKey(ctx)

require.Error(t, err)
require.Contains(t, err.Error(), "verifying key not found")
}

func TestSetAndGetVerifyingKey(t *testing.T) {
ctx, keeper, authority := setupKeeper(t)

param := NewMsgMyFunction(authority, verifyingKeyHex)

err := keeper.SetVerifyingKey(ctx, &param)
require.NoError(t, err)

retrievedKey, err := keeper.GetVerifyingKey(ctx)
require.NoError(t, err)
var keyBuffer bytes.Buffer
_, err = retrievedKey.WriteTo(&keyBuffer)
require.NoError(t, err)

retrievedKeyHex := hex.EncodeToString(keyBuffer.Bytes())

require.Equal(t, verifyingKeyHex, retrievedKeyHex)
}
12 changes: 12 additions & 0 deletions 11-cometbls/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,16 @@ const (
ModuleName = "11-cometbls"

ClientType = ModuleName

// StoreKey is the store key string for your module
StoreKey = "anymodule"

// AuthorityKey is the key under which the governance authority is stored in the module
AuthorityKey = "authority"

// VerifyingKeyPrefix is the prefix for storing the verifying key
VerifyingKeyPrefix = "vkHex/"

// VerifyingKeyKey is the key used to store the verifying key
VerifyingKeyKey = "verifyingKey"
)
19 changes: 19 additions & 0 deletions 11-cometbls/msg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package cometbls

import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

// MsgMyFunction defines a message with sender and string parameter.
type MsgMyFunction struct {
Sender sdk.AccAddress `json:"sender" yaml:"sender"` // This is msg.sender
vkHex string `json:"vkHex" yaml:"vkHex"`
}

// NewMsgMyFunction creates a new MsgMyFunction.
func NewMsgMyFunction(sender sdk.AccAddress, vkHex string) MsgMyFunction {
return MsgMyFunction{
Sender: sender,
vkHex: vkHex,
}
}
Loading
Loading