-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
) |