Skip to content

Commit

Permalink
add client
Browse files Browse the repository at this point in the history
  • Loading branch information
mossid committed Jun 7, 2019
1 parent 792c727 commit 30232f8
Show file tree
Hide file tree
Showing 3 changed files with 271 additions and 0 deletions.
146 changes: 146 additions & 0 deletions x/ibc/02-client/manager.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package client

import (
"errors"
"strconv"

"github.com/cosmos/cosmos-sdk/store/mapping"
sdk "github.com/cosmos/cosmos-sdk/types"
)

type IDGenerator func(sdk.Context /*Header,*/, mapping.Value) string

func IntegerIDGenerator(ctx sdk.Context, v mapping.Value) string {
id := mapping.NewInteger(v, mapping.Dec).Incr(ctx)
return strconv.FormatUint(id, 10)
}

type Manager struct {
protocol mapping.Mapping

idval mapping.Value
idgen IDGenerator
}

func NewManager(protocol, free mapping.Base, idgen IDGenerator) Manager {
return Manager{
protocol: mapping.NewMapping(protocol, []byte("/")),
idval: mapping.NewValue(free, []byte("/id")),
idgen: idgen,
}
}

/*
func (man Manager) RegisterKind(kind Kind, pred ValidityPredicate) Manager {
if _, ok := man.pred[kind]; ok {
panic("Kind already registered")
}
man.pred[kind] = pred
return man
}
*/
func (man Manager) object(id string) Object {
return Object{
id: id,
client: man.protocol.Value([]byte(id)),
freeze: mapping.NewBoolean(man.protocol.Value([]byte(id + "/freeze"))),
}
}

func (man Manager) Create(ctx sdk.Context, cs Client) string {
id := man.idgen(ctx, man.idval)
err := man.object(id).create(ctx, cs)
if err != nil {
panic(err)
}
return id
}

func (man Manager) Query(ctx sdk.Context, id string) (Object, error) {
res := man.object(id)
if !res.exists(ctx) {
return Object{}, errors.New("client not exists")
}
return res, nil
}

type Object struct {
id string
client mapping.Value
freeze mapping.Boolean
}

func (obj Object) create(ctx sdk.Context, st Client) error {
if obj.exists(ctx) {
return errors.New("Create client on already existing id")
}
obj.client.Set(ctx, st)
return nil
}

func (obj Object) exists(ctx sdk.Context) bool {
return obj.client.Exists(ctx)
}

func (obj Object) ID() string {
return obj.id
}

func (obj Object) Value(ctx sdk.Context) (res Client) {
obj.client.Get(ctx, &res)
return
}

func (obj Object) Is(ctx sdk.Context, client Client) bool {
return obj.client.Is(ctx, client)
}

func (obj Object) Update(ctx sdk.Context, header Header) error {
if !obj.exists(ctx) {
panic("should not update nonexisting client")
}

if obj.freeze.Get(ctx) {
return errors.New("client is frozen")
}

var stored Client
obj.client.GetIfExists(ctx, &stored)
updated, err := stored.Validate(header)
if err != nil {
return err
}

obj.client.Set(ctx, updated)

return nil
}

func (obj Object) Freeze(ctx sdk.Context) error {
if !obj.exists(ctx) {
panic("should not freeze nonexisting client")
}

if obj.freeze.Get(ctx) {
return errors.New("client is already frozen")
}

obj.freeze.Set(ctx, true)

return nil
}

func (obj Object) Delete(ctx sdk.Context) error {
if !obj.exists(ctx) {
panic("should not delete nonexisting client")
}

if !obj.freeze.Get(ctx) {
return errors.New("client is not frozen")
}

obj.client.Delete(ctx)
obj.freeze.Delete(ctx)

return nil
}
79 changes: 79 additions & 0 deletions x/ibc/02-client/tendermint/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package tendermint

import (
"bytes"

"github.com/tendermint/tendermint/types"

"github.com/cosmos/cosmos-sdk/x/ibc/02-client"
"github.com/cosmos/cosmos-sdk/x/ibc/23-commitment"
)

// Ref tendermint/lite/base_verifier.go

var _ client.ValidityPredicateBase = ValidityPredicateBase{}

type ValidityPredicateBase struct {
Height int64
NextValidatorSet *types.ValidatorSet
}

func (ValidityPredicateBase) Kind() client.Kind {
return client.Tendermint
}

func (base ValidityPredicateBase) GetHeight() int64 {
return base.Height
}

func (base ValidityPredicateBase) Equal(cbase client.ValidityPredicateBase) bool {
base0, ok := cbase.(ValidityPredicateBase)
if !ok {
return false
}
return base.Height == base0.Height &&
bytes.Equal(base.NextValidatorSet.Hash(), base0.NextValidatorSet.Hash())
}

var _ client.Client = Client{}

type Client struct {
Base ValidityPredicateBase
Root commitment.Root
}

func (Client) Kind() client.Kind {
return client.Tendermint
}

func (client Client) GetBase() client.ValidityPredicateBase {
return client.Base
}

func (client Client) GetRoot() commitment.Root {
return client.Root
}

func (client Client) Validate(header client.Header) (client.Client, error) {
return client, nil // XXX
}

var _ client.Header = Header{}

type Header struct {
Base ValidityPredicateBase
Root commitment.Root
Votes []*types.CommitSig
}

func (header Header) Kind() client.Kind {
return client.Tendermint
}

func (header Header) GetBase() client.ValidityPredicateBase {
return header.Base
}

func (header Header) GetRoot() commitment.Root {
return header.Root
}
46 changes: 46 additions & 0 deletions x/ibc/02-client/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package client

import (
"github.com/cosmos/cosmos-sdk/x/ibc/23-commitment"
)

// TODO: types in this file should be (de/)serialized with proto in the future

type AminoMarshaler interface {
MarshalAmino() (string, error)
UnmarshalAmino(string) error
}

type ValidityPredicateBase interface {
Kind() Kind
GetHeight() int64
Equal(ValidityPredicateBase) bool
}

// ConsensusState
type Client interface {
Kind() Kind
GetBase() ValidityPredicateBase
GetRoot() commitment.Root
Validate(Header) (Client, error) // ValidityPredicate
}

func Equal(client1, client2 Client) bool {
return client1.Kind() == client2.Kind() &&
client1.GetBase().Equal(client2.GetBase())
}

type Header interface {
Kind() Kind
// Proof() HeaderProof
GetBase() ValidityPredicateBase // can be nil
GetRoot() commitment.Root
}

// XXX: Kind should be enum?

type Kind byte

const (
Tendermint Kind = iota
)

0 comments on commit 30232f8

Please sign in to comment.