Remvoed old ibc code
This commit is contained in:
parent
b7f31ad70a
commit
89a8c0bf08
|
@ -1,600 +0,0 @@
|
||||||
package ibc
|
|
||||||
|
|
||||||
// import (
|
|
||||||
// "bytes"
|
|
||||||
// "encoding/json"
|
|
||||||
// "errors"
|
|
||||||
// "fmt"
|
|
||||||
// "net/url"
|
|
||||||
// "strconv"
|
|
||||||
// "strings"
|
|
||||||
|
|
||||||
// abci "github.com/tendermint/abci/types"
|
|
||||||
// "github.com/tendermint/go-wire"
|
|
||||||
// merkle "github.com/tendermint/merkleeyes/iavl"
|
|
||||||
// cmn "github.com/tendermint/tmlibs/common"
|
|
||||||
|
|
||||||
// "github.com/tendermint/basecoin/types"
|
|
||||||
// tm "github.com/tendermint/tendermint/types"
|
|
||||||
// )
|
|
||||||
|
|
||||||
// const (
|
|
||||||
// // Key parts
|
|
||||||
// _IBC = "ibc"
|
|
||||||
// _BLOCKCHAIN = "blockchain"
|
|
||||||
// _GENESIS = "genesis"
|
|
||||||
// _STATE = "state"
|
|
||||||
// _HEADER = "header"
|
|
||||||
// _EGRESS = "egress"
|
|
||||||
// _INGRESS = "ingress"
|
|
||||||
// _CONNECTION = "connection"
|
|
||||||
// )
|
|
||||||
|
|
||||||
// type IBCPluginState struct {
|
|
||||||
// // @[:ibc, :blockchain, :genesis, ChainID] <~ BlockchainGenesis
|
|
||||||
// // @[:ibc, :blockchain, :state, ChainID] <~ BlockchainState
|
|
||||||
// // @[:ibc, :blockchain, :header, ChainID, Height] <~ tm.Header
|
|
||||||
// // @[:ibc, :egress, Src, Dst, Sequence] <~ Packet
|
|
||||||
// // @[:ibc, :ingress, Dst, Src, Sequence] <~ Packet
|
|
||||||
// // @[:ibc, :connection, Src, Dst] <~ Connection # TODO - keep connection state
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type BlockchainGenesis struct {
|
|
||||||
// ChainID string
|
|
||||||
// Genesis string
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type BlockchainState struct {
|
|
||||||
// ChainID string
|
|
||||||
// Validators []*tm.Validator
|
|
||||||
// LastBlockHash []byte
|
|
||||||
// LastBlockHeight uint64
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type Packet struct {
|
|
||||||
// SrcChainID string
|
|
||||||
// DstChainID string
|
|
||||||
// Sequence uint64
|
|
||||||
// Type string // redundant now that Type() is a method on Payload ?
|
|
||||||
// Payload Payload
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func NewPacket(src, dst string, seq uint64, payload Payload) Packet {
|
|
||||||
// return Packet{
|
|
||||||
// SrcChainID: src,
|
|
||||||
// DstChainID: dst,
|
|
||||||
// Sequence: seq,
|
|
||||||
// Type: payload.Type(),
|
|
||||||
// Payload: payload,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // GetSequenceNumber gets the sequence number for packets being sent from the src chain to the dst chain.
|
|
||||||
// // The sequence number counts how many packets have been sent.
|
|
||||||
// // The next packet must include the latest sequence number.
|
|
||||||
// func GetSequenceNumber(store state.SimpleDB, src, dst string) uint64 {
|
|
||||||
// sequenceKey := toKey(_IBC, _EGRESS, src, dst)
|
|
||||||
// seqBytes := store.Get(sequenceKey)
|
|
||||||
// if seqBytes == nil {
|
|
||||||
// return 0
|
|
||||||
// }
|
|
||||||
// seq, err := strconv.ParseUint(string(seqBytes), 10, 64)
|
|
||||||
// if err != nil {
|
|
||||||
// cmn.PanicSanity(err.Error())
|
|
||||||
// }
|
|
||||||
// return seq
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // SetSequenceNumber sets the sequence number for packets being sent from the src chain to the dst chain
|
|
||||||
// func SetSequenceNumber(store state.SimpleDB, src, dst string, seq uint64) {
|
|
||||||
// sequenceKey := toKey(_IBC, _EGRESS, src, dst)
|
|
||||||
// store.Set(sequenceKey, []byte(strconv.FormatUint(seq, 10)))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // SaveNewIBCPacket creates an IBC packet with the given payload from the src chain to the dst chain
|
|
||||||
// // using the correct sequence number. It also increments the sequence number by 1
|
|
||||||
// func SaveNewIBCPacket(state state.SimpleDB, src, dst string, payload Payload) {
|
|
||||||
// // fetch sequence number and increment by 1
|
|
||||||
// seq := GetSequenceNumber(state, src, dst)
|
|
||||||
// SetSequenceNumber(state, src, dst, seq+1)
|
|
||||||
|
|
||||||
// // save ibc packet
|
|
||||||
// packetKey := toKey(_IBC, _EGRESS, src, dst, cmn.Fmt("%v", seq))
|
|
||||||
// packet := NewPacket(src, dst, uint64(seq), payload)
|
|
||||||
// save(state, packetKey, packet)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func GetIBCPacket(state state.SimpleDB, src, dst string, seq uint64) (Packet, error) {
|
|
||||||
// packetKey := toKey(_IBC, _EGRESS, src, dst, cmn.Fmt("%v", seq))
|
|
||||||
// packetBytes := state.Get(packetKey)
|
|
||||||
|
|
||||||
// var packet Packet
|
|
||||||
// err := wire.ReadBinaryBytes(packetBytes, &packet)
|
|
||||||
// return packet, err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// const (
|
|
||||||
// PayloadTypeBytes = byte(0x01)
|
|
||||||
// PayloadTypeCoins = byte(0x02)
|
|
||||||
// )
|
|
||||||
|
|
||||||
// var _ = wire.RegisterInterface(
|
|
||||||
// struct{ Payload }{},
|
|
||||||
// wire.ConcreteType{DataPayload{}, PayloadTypeBytes},
|
|
||||||
// wire.ConcreteType{CoinsPayload{}, PayloadTypeCoins},
|
|
||||||
// )
|
|
||||||
|
|
||||||
// type Payload interface {
|
|
||||||
// AssertIsPayload()
|
|
||||||
// Type() string
|
|
||||||
// ValidateBasic() abci.Result
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (DataPayload) AssertIsPayload() {}
|
|
||||||
// func (CoinsPayload) AssertIsPayload() {}
|
|
||||||
|
|
||||||
// type DataPayload []byte
|
|
||||||
|
|
||||||
// func (p DataPayload) Type() string {
|
|
||||||
// return "data"
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (p DataPayload) ValidateBasic() abci.Result {
|
|
||||||
// return abci.OK
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type CoinsPayload struct {
|
|
||||||
// Address []byte
|
|
||||||
// Coins coin.Coins
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (p CoinsPayload) Type() string {
|
|
||||||
// return "coin"
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (p CoinsPayload) ValidateBasic() abci.Result {
|
|
||||||
// // TODO: validate
|
|
||||||
// return abci.OK
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// const (
|
|
||||||
// IBCTxTypeRegisterChain = byte(0x01)
|
|
||||||
// IBCTxTypeUpdateChain = byte(0x02)
|
|
||||||
// IBCTxTypePacketCreate = byte(0x03)
|
|
||||||
// IBCTxTypePacketPost = byte(0x04)
|
|
||||||
|
|
||||||
// IBCCodeEncodingError = abci.CodeType(1001)
|
|
||||||
// IBCCodeChainAlreadyExists = abci.CodeType(1002)
|
|
||||||
// IBCCodePacketAlreadyExists = abci.CodeType(1003)
|
|
||||||
// IBCCodeUnknownHeight = abci.CodeType(1004)
|
|
||||||
// IBCCodeInvalidCommit = abci.CodeType(1005)
|
|
||||||
// IBCCodeInvalidProof = abci.CodeType(1006)
|
|
||||||
// )
|
|
||||||
|
|
||||||
// var _ = wire.RegisterInterface(
|
|
||||||
// struct{ IBCTx }{},
|
|
||||||
// wire.ConcreteType{IBCRegisterChainTx{}, IBCTxTypeRegisterChain},
|
|
||||||
// wire.ConcreteType{IBCUpdateChainTx{}, IBCTxTypeUpdateChain},
|
|
||||||
// wire.ConcreteType{IBCPacketCreateTx{}, IBCTxTypePacketCreate},
|
|
||||||
// wire.ConcreteType{IBCPacketPostTx{}, IBCTxTypePacketPost},
|
|
||||||
// )
|
|
||||||
|
|
||||||
// type IBCTx interface {
|
|
||||||
// AssertIsIBCTx()
|
|
||||||
// ValidateBasic() abci.Result
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (IBCRegisterChainTx) AssertIsIBCTx() {}
|
|
||||||
// func (IBCUpdateChainTx) AssertIsIBCTx() {}
|
|
||||||
// func (IBCPacketCreateTx) AssertIsIBCTx() {}
|
|
||||||
// func (IBCPacketPostTx) AssertIsIBCTx() {}
|
|
||||||
|
|
||||||
// type IBCRegisterChainTx struct {
|
|
||||||
// BlockchainGenesis
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (IBCRegisterChainTx) ValidateBasic() (res abci.Result) {
|
|
||||||
// // TODO - validate
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type IBCUpdateChainTx struct {
|
|
||||||
// Header tm.Header
|
|
||||||
// Commit tm.Commit
|
|
||||||
// // TODO: NextValidators
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (IBCUpdateChainTx) ValidateBasic() (res abci.Result) {
|
|
||||||
// // TODO - validate
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type IBCPacketCreateTx struct {
|
|
||||||
// Packet
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (IBCPacketCreateTx) ValidateBasic() (res abci.Result) {
|
|
||||||
// // TODO - validate
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type IBCPacketPostTx struct {
|
|
||||||
// FromChainID string // The immediate source of the packet, not always Packet.SrcChainID
|
|
||||||
// FromChainHeight uint64 // The block height in which Packet was committed, to check Proof
|
|
||||||
// Packet
|
|
||||||
// Proof *merkle.IAVLProof
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (IBCPacketPostTx) ValidateBasic() (res abci.Result) {
|
|
||||||
// // TODO - validate
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// type IBCPlugin struct {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (ibc *IBCPlugin) Name() string {
|
|
||||||
// return "IBC"
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (ibc *IBCPlugin) StateKey() []byte {
|
|
||||||
// return []byte("IBCPlugin.State")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func New() *IBCPlugin {
|
|
||||||
// return &IBCPlugin{}
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (ibc *IBCPlugin) SetOption(store state.SimpleDB, key string, value string) (log string) {
|
|
||||||
// return ""
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (ibc *IBCPlugin) RunTx(store state.SimpleDB, ctx types.CallContext, txBytes []byte) (res abci.Result) {
|
|
||||||
// // Decode tx
|
|
||||||
// var tx IBCTx
|
|
||||||
// err := wire.ReadBinaryBytes(txBytes, &tx)
|
|
||||||
// if err != nil {
|
|
||||||
// return abci.ErrBaseEncodingError.AppendLog("Error decoding tx: " + err.Error())
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Validate tx
|
|
||||||
// res = tx.ValidateBasic()
|
|
||||||
// if res.IsErr() {
|
|
||||||
// return res.PrependLog("ValidateBasic Failed: ")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // TODO - Check whether sufficient funds
|
|
||||||
|
|
||||||
// defer func() {
|
|
||||||
// // TODO - Refund any remaining funds left over
|
|
||||||
// // e.g. !ctx.Coins.Minus(tx.Fee).IsZero()
|
|
||||||
// // ctx.CallerAccount is synced w/ store, so just modify that and store it.
|
|
||||||
// // NOTE: We should use the CallContext to store fund/refund information.
|
|
||||||
// }()
|
|
||||||
|
|
||||||
// sm := &IBCStateMachine{store, ctx, abci.OK}
|
|
||||||
|
|
||||||
// switch tx := tx.(type) {
|
|
||||||
// case IBCRegisterChainTx:
|
|
||||||
// sm.runRegisterChainTx(tx)
|
|
||||||
// case IBCUpdateChainTx:
|
|
||||||
// sm.runUpdateChainTx(tx)
|
|
||||||
// case IBCPacketCreateTx:
|
|
||||||
// sm.runPacketCreateTx(tx)
|
|
||||||
// case IBCPacketPostTx:
|
|
||||||
// sm.runPacketPostTx(tx)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return sm.res
|
|
||||||
// }
|
|
||||||
|
|
||||||
// type IBCStateMachine struct {
|
|
||||||
// store state.SimpleDB
|
|
||||||
// ctx types.CallContext
|
|
||||||
// res abci.Result
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (sm *IBCStateMachine) runRegisterChainTx(tx IBCRegisterChainTx) {
|
|
||||||
// chainGenKey := toKey(_IBC, _BLOCKCHAIN, _GENESIS, tx.ChainID)
|
|
||||||
// chainStateKey := toKey(_IBC, _BLOCKCHAIN, _STATE, tx.ChainID)
|
|
||||||
// chainGen := tx.BlockchainGenesis
|
|
||||||
|
|
||||||
// // Parse genesis
|
|
||||||
// chainGenDoc := new(tm.GenesisDoc)
|
|
||||||
// err := json.Unmarshal([]byte(chainGen.Genesis), chainGenDoc)
|
|
||||||
// if err != nil {
|
|
||||||
// sm.res.Code = IBCCodeEncodingError
|
|
||||||
// sm.res.Log = "Genesis doc couldn't be parsed: " + err.Error()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Make sure chainGen doesn't already exist
|
|
||||||
// if exists(sm.store, chainGenKey) {
|
|
||||||
// sm.res.Code = IBCCodeChainAlreadyExists
|
|
||||||
// sm.res.Log = "Already exists"
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Save new BlockchainGenesis
|
|
||||||
// save(sm.store, chainGenKey, chainGen)
|
|
||||||
|
|
||||||
// // Create new BlockchainState
|
|
||||||
// chainState := BlockchainState{
|
|
||||||
// ChainID: chainGenDoc.ChainID,
|
|
||||||
// Validators: make([]*tm.Validator, len(chainGenDoc.Validators)),
|
|
||||||
// LastBlockHash: nil,
|
|
||||||
// LastBlockHeight: 0,
|
|
||||||
// }
|
|
||||||
// // Make validators slice
|
|
||||||
// for i, val := range chainGenDoc.Validators {
|
|
||||||
// pubKey := val.PubKey
|
|
||||||
// address := pubKey.Address()
|
|
||||||
// chainState.Validators[i] = &tm.Validator{
|
|
||||||
// Address: address,
|
|
||||||
// PubKey: pubKey,
|
|
||||||
// VotingPower: val.Amount,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Save new BlockchainState
|
|
||||||
// save(sm.store, chainStateKey, chainState)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (sm *IBCStateMachine) runUpdateChainTx(tx IBCUpdateChainTx) {
|
|
||||||
// chainID := tx.Header.ChainID
|
|
||||||
// chainStateKey := toKey(_IBC, _BLOCKCHAIN, _STATE, chainID)
|
|
||||||
|
|
||||||
// // Make sure chainState exists
|
|
||||||
// if !exists(sm.store, chainStateKey) {
|
|
||||||
// return // Chain does not exist, do nothing
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Load latest chainState
|
|
||||||
// var chainState BlockchainState
|
|
||||||
// exists, err := load(sm.store, chainStateKey, &chainState)
|
|
||||||
// if err != nil {
|
|
||||||
// sm.res = abci.ErrInternalError.AppendLog(cmn.Fmt("Loading ChainState: %v", err.Error()))
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// if !exists {
|
|
||||||
// sm.res = abci.ErrInternalError.AppendLog(cmn.Fmt("Missing ChainState"))
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Check commit against last known state & validators
|
|
||||||
// err = verifyCommit(chainState, &tx.Header, &tx.Commit)
|
|
||||||
// if err != nil {
|
|
||||||
// sm.res.Code = IBCCodeInvalidCommit
|
|
||||||
// sm.res.Log = cmn.Fmt("Invalid Commit: %v", err.Error())
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Store header
|
|
||||||
// headerKey := toKey(_IBC, _BLOCKCHAIN, _HEADER, chainID, cmn.Fmt("%v", tx.Header.Height))
|
|
||||||
// save(sm.store, headerKey, tx.Header)
|
|
||||||
|
|
||||||
// // Update chainState
|
|
||||||
// chainState.LastBlockHash = tx.Header.Hash()
|
|
||||||
// chainState.LastBlockHeight = uint64(tx.Header.Height)
|
|
||||||
|
|
||||||
// // Store chainState
|
|
||||||
// save(sm.store, chainStateKey, chainState)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (sm *IBCStateMachine) runPacketCreateTx(tx IBCPacketCreateTx) {
|
|
||||||
// packet := tx.Packet
|
|
||||||
// packetKey := toKey(_IBC, _EGRESS,
|
|
||||||
// packet.SrcChainID,
|
|
||||||
// packet.DstChainID,
|
|
||||||
// cmn.Fmt("%v", packet.Sequence),
|
|
||||||
// )
|
|
||||||
// // Make sure packet doesn't already exist
|
|
||||||
// if exists(sm.store, packetKey) {
|
|
||||||
// sm.res.Code = IBCCodePacketAlreadyExists
|
|
||||||
// // TODO: .AppendLog() does not update sm.res
|
|
||||||
// sm.res.Log = "Already exists"
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Execute the payload
|
|
||||||
// switch payload := tx.Packet.Payload.(type) {
|
|
||||||
// case DataPayload:
|
|
||||||
// // do nothing
|
|
||||||
// case CoinsPayload:
|
|
||||||
// // ensure enough coins were sent in tx to cover the payload coins
|
|
||||||
// if !sm.ctx.Coins.IsGTE(payload.Coins) {
|
|
||||||
// sm.res.Code = abci.CodeType_InsufficientFunds
|
|
||||||
// sm.res.Log = fmt.Sprintf("Not enough funds sent in tx (%v) to send %v via IBC", sm.ctx.Coins, payload.Coins)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // deduct coins from context
|
|
||||||
// sm.ctx.Coins = sm.ctx.Coins.Minus(payload.Coins)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Save new Packet
|
|
||||||
// save(sm.store, packetKey, packet)
|
|
||||||
|
|
||||||
// // set the sequence number
|
|
||||||
// SetSequenceNumber(sm.store, packet.SrcChainID, packet.DstChainID, packet.Sequence)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (sm *IBCStateMachine) runPacketPostTx(tx IBCPacketPostTx) {
|
|
||||||
// packet := tx.Packet
|
|
||||||
// packetKeyEgress := toKey(_IBC, _EGRESS,
|
|
||||||
// packet.SrcChainID,
|
|
||||||
// packet.DstChainID,
|
|
||||||
// cmn.Fmt("%v", packet.Sequence),
|
|
||||||
// )
|
|
||||||
// packetKeyIngress := toKey(_IBC, _INGRESS,
|
|
||||||
// packet.DstChainID,
|
|
||||||
// packet.SrcChainID,
|
|
||||||
// cmn.Fmt("%v", packet.Sequence),
|
|
||||||
// )
|
|
||||||
// headerKey := toKey(_IBC, _BLOCKCHAIN, _HEADER,
|
|
||||||
// tx.FromChainID,
|
|
||||||
// cmn.Fmt("%v", tx.FromChainHeight),
|
|
||||||
// )
|
|
||||||
|
|
||||||
// // Make sure packet doesn't already exist
|
|
||||||
// if exists(sm.store, packetKeyIngress) {
|
|
||||||
// sm.res.Code = IBCCodePacketAlreadyExists
|
|
||||||
// sm.res.Log = "Already exists"
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Save new Packet (just for fun)
|
|
||||||
// save(sm.store, packetKeyIngress, packet)
|
|
||||||
|
|
||||||
// // Load Header and make sure it exists
|
|
||||||
// // If it exists, we already checked a valid commit for it in UpdateChainTx
|
|
||||||
// var header tm.Header
|
|
||||||
// exists, err := load(sm.store, headerKey, &header)
|
|
||||||
// if err != nil {
|
|
||||||
// sm.res = abci.ErrInternalError.AppendLog(cmn.Fmt("Loading Header: %v", err.Error()))
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// if !exists {
|
|
||||||
// sm.res.Code = IBCCodeUnknownHeight
|
|
||||||
// sm.res.Log = cmn.Fmt("Loading Header: Unknown height")
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// proof := tx.Proof
|
|
||||||
// if proof == nil {
|
|
||||||
// sm.res.Code = IBCCodeInvalidProof
|
|
||||||
// sm.res.Log = "Proof is nil"
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
// packetBytes := wire.BinaryBytes(packet)
|
|
||||||
|
|
||||||
// // Make sure packet's proof matches given (packet, key, blockhash)
|
|
||||||
// ok := proof.Verify(packetKeyEgress, packetBytes, header.AppHash)
|
|
||||||
// if !ok {
|
|
||||||
// sm.res.Code = IBCCodeInvalidProof
|
|
||||||
// sm.res.Log = fmt.Sprintf("Proof is invalid. key: %s; packetByes %X; header %v; proof %v", packetKeyEgress, packetBytes, header, proof)
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Execute payload
|
|
||||||
// switch payload := packet.Payload.(type) {
|
|
||||||
// case DataPayload:
|
|
||||||
// // do nothing
|
|
||||||
// case CoinsPayload:
|
|
||||||
// // Add coins to destination account
|
|
||||||
// acc := types.GetAccount(sm.store, payload.Address)
|
|
||||||
// if acc == nil {
|
|
||||||
// acc = &types.Account{}
|
|
||||||
// }
|
|
||||||
// acc.Balance = acc.Balance.Plus(payload.Coins)
|
|
||||||
// types.SetAccount(sm.store, payload.Address, acc)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (ibc *IBCPlugin) InitChain(store state.SimpleDB, vals []*abci.Validator) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (cp *IBCPlugin) BeginBlock(store state.SimpleDB, hash []byte, header *abci.Header) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (cp *IBCPlugin) EndBlock(store state.SimpleDB, height uint64) (res abci.ResponseEndBlock) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //--------------------------------------------------------------------------------
|
|
||||||
// // TODO: move to utils
|
|
||||||
|
|
||||||
// // Returns true if exists, false if nil.
|
|
||||||
// func exists(store state.SimpleDB, key []byte) (exists bool) {
|
|
||||||
// value := store.Get(key)
|
|
||||||
// return len(value) > 0
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Load bytes from store by reading value for key and read into ptr.
|
|
||||||
// // Returns true if exists, false if nil.
|
|
||||||
// // Returns err if decoding error.
|
|
||||||
// func load(store state.SimpleDB, key []byte, ptr interface{}) (exists bool, err error) {
|
|
||||||
// value := store.Get(key)
|
|
||||||
// if len(value) > 0 {
|
|
||||||
// err = wire.ReadBinaryBytes(value, ptr)
|
|
||||||
// if err != nil {
|
|
||||||
// return true, errors.New(
|
|
||||||
// cmn.Fmt("Error decoding key 0x%X = 0x%X: %v", key, value, err.Error()),
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// return true, nil
|
|
||||||
// } else {
|
|
||||||
// return false, nil
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Save bytes to store by writing obj's go-wire binary bytes.
|
|
||||||
// func save(store state.SimpleDB, key []byte, obj interface{}) {
|
|
||||||
// store.Set(key, wire.BinaryBytes(obj))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Key parts are URL escaped and joined with ','
|
|
||||||
// func toKey(parts ...string) []byte {
|
|
||||||
// escParts := make([]string, len(parts))
|
|
||||||
// for i, part := range parts {
|
|
||||||
// escParts[i] = url.QueryEscape(part)
|
|
||||||
// }
|
|
||||||
// return []byte(strings.Join(escParts, ","))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // NOTE: Commit's votes include ValidatorAddress, so can be matched up
|
|
||||||
// // against chainState.Validators, even if the validator set had changed.
|
|
||||||
// // For the purpose of the demo, we assume that the validator set hadn't changed,
|
|
||||||
// // though we should check that explicitly.
|
|
||||||
// func verifyCommit(chainState BlockchainState, header *tm.Header, commit *tm.Commit) error {
|
|
||||||
|
|
||||||
// // Ensure that chainState and header ChainID match.
|
|
||||||
// if chainState.ChainID != header.ChainID {
|
|
||||||
// return errors.New(cmn.Fmt("Expected header.ChainID %v, got %v", chainState.ChainID, header.ChainID))
|
|
||||||
// }
|
|
||||||
// // Ensure things aren't empty
|
|
||||||
// if len(chainState.Validators) == 0 {
|
|
||||||
// return errors.New(cmn.Fmt("Blockchain has no validators")) // NOTE: Why would this happen?
|
|
||||||
// }
|
|
||||||
// if len(commit.Precommits) == 0 {
|
|
||||||
// return errors.New(cmn.Fmt("Commit has no signatures"))
|
|
||||||
// }
|
|
||||||
// chainID := chainState.ChainID
|
|
||||||
// vals := chainState.Validators
|
|
||||||
// valSet := tm.NewValidatorSet(vals)
|
|
||||||
|
|
||||||
// var blockID tm.BlockID
|
|
||||||
// for _, pc := range commit.Precommits {
|
|
||||||
// // XXX: incorrect. we want the one for +2/3, not just the first one
|
|
||||||
// if pc != nil {
|
|
||||||
// blockID = pc.BlockID
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if blockID.IsZero() {
|
|
||||||
// return errors.New("All precommits are nil!")
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // NOTE: Currently this only works with the exact same validator set.
|
|
||||||
// // Not this, but perhaps "ValidatorSet.VerifyCommitAny" should expose
|
|
||||||
// // the functionality to verify commits even after validator changes.
|
|
||||||
// err := valSet.VerifyCommit(chainID, blockID, header.Height, commit)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Ensure the committed blockID matches the header
|
|
||||||
// if !bytes.Equal(header.Hash(), blockID.Hash) {
|
|
||||||
// return errors.New(cmn.Fmt("blockID.Hash (%X) does not match header.Hash (%X)", blockID.Hash, header.Hash()))
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // All ok!
|
|
||||||
// return nil
|
|
||||||
// }
|
|
|
@ -1,512 +0,0 @@
|
||||||
package ibc
|
|
||||||
|
|
||||||
// import (
|
|
||||||
// "bytes"
|
|
||||||
// "encoding/json"
|
|
||||||
// "sort"
|
|
||||||
// "strings"
|
|
||||||
// "testing"
|
|
||||||
|
|
||||||
// "github.com/stretchr/testify/assert"
|
|
||||||
// "github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
// abci "github.com/tendermint/abci/types"
|
|
||||||
// crypto "github.com/tendermint/go-crypto"
|
|
||||||
// "github.com/tendermint/go-wire"
|
|
||||||
// eyes "github.com/tendermint/merkleeyes/client"
|
|
||||||
// "github.com/tendermint/merkleeyes/iavl"
|
|
||||||
// cmn "github.com/tendermint/tmlibs/common"
|
|
||||||
|
|
||||||
// "github.com/tendermint/basecoin/types"
|
|
||||||
// tm "github.com/tendermint/tendermint/types"
|
|
||||||
// )
|
|
||||||
|
|
||||||
// // NOTE: PrivAccounts are sorted by Address,
|
|
||||||
// // GenesisDoc, not necessarily.
|
|
||||||
// func genGenesisDoc(chainID string, numVals int) (*tm.GenesisDoc, []types.PrivAccount) {
|
|
||||||
// var privAccs []types.PrivAccount
|
|
||||||
// genDoc := &tm.GenesisDoc{
|
|
||||||
// ChainID: chainID,
|
|
||||||
// Validators: nil,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for i := 0; i < numVals; i++ {
|
|
||||||
// name := cmn.Fmt("%v_val_%v", chainID, i)
|
|
||||||
// privAcc := types.PrivAccountFromSecret(name)
|
|
||||||
// genDoc.Validators = append(genDoc.Validators, tm.GenesisValidator{
|
|
||||||
// PubKey: privAcc.PubKey,
|
|
||||||
// Amount: 1,
|
|
||||||
// Name: name,
|
|
||||||
// })
|
|
||||||
// privAccs = append(privAccs, privAcc)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Sort PrivAccounts
|
|
||||||
// sort.Sort(PrivAccountsByAddress(privAccs))
|
|
||||||
|
|
||||||
// return genDoc, privAccs
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //-------------------------------------
|
|
||||||
// // Implements sort for sorting PrivAccount by address.
|
|
||||||
|
|
||||||
// type PrivAccountsByAddress []types.PrivAccount
|
|
||||||
|
|
||||||
// func (pas PrivAccountsByAddress) Len() int {
|
|
||||||
// return len(pas)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (pas PrivAccountsByAddress) Less(i, j int) bool {
|
|
||||||
// return bytes.Compare(pas[i].Account.PubKey.Address(), pas[j].Account.PubKey.Address()) == -1
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func (pas PrivAccountsByAddress) Swap(i, j int) {
|
|
||||||
// it := pas[i]
|
|
||||||
// pas[i] = pas[j]
|
|
||||||
// pas[j] = it
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// var testGenesisDoc = `{
|
|
||||||
// "app_hash": "",
|
|
||||||
// "chain_id": "test_chain_1",
|
|
||||||
// "genesis_time": "0001-01-01T00:00:00.000Z",
|
|
||||||
// "validators": [
|
|
||||||
// {
|
|
||||||
// "amount": 10,
|
|
||||||
// "name": "",
|
|
||||||
// "pub_key": {
|
|
||||||
// "type": "ed25519",
|
|
||||||
// "data":"D6EBB92440CF375054AA59BCF0C99D596DEEDFFB2543CAE1BA1908B72CF9676A"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// ],
|
|
||||||
// "app_options": {
|
|
||||||
// "accounts": [
|
|
||||||
// {
|
|
||||||
// "pub_key": {
|
|
||||||
// "type": "ed25519",
|
|
||||||
// "data": "B3588BDC92015ED3CDB6F57A86379E8C79A7111063610B7E625487C76496F4DF"
|
|
||||||
// },
|
|
||||||
// "coins": [
|
|
||||||
// {
|
|
||||||
// "denom": "mycoin",
|
|
||||||
// "amount": 9007199254740992
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
// }`
|
|
||||||
|
|
||||||
// func TestIBCGenesisFromString(t *testing.T) {
|
|
||||||
// eyesClient := eyes.NewLocalClient("", 0)
|
|
||||||
// store := types.NewKVCache(eyesClient)
|
|
||||||
// store.SetLogging() // Log all activity
|
|
||||||
|
|
||||||
// ibcPlugin := New()
|
|
||||||
// ctx := types.NewCallContext(nil, nil, coin.Coins{})
|
|
||||||
|
|
||||||
// registerChain(t, ibcPlugin, store, ctx, "test_chain", testGenesisDoc)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //--------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// func TestIBCPluginRegister(t *testing.T) {
|
|
||||||
// require := require.New(t)
|
|
||||||
|
|
||||||
// eyesClient := eyes.NewLocalClient("", 0)
|
|
||||||
// store := types.NewKVCache(eyesClient)
|
|
||||||
// store.SetLogging() // Log all activity
|
|
||||||
|
|
||||||
// ibcPlugin := New()
|
|
||||||
// ctx := types.NewCallContext(nil, nil, coin.Coins{})
|
|
||||||
|
|
||||||
// chainID_1 := "test_chain"
|
|
||||||
// genDoc_1, _ := genGenesisDoc(chainID_1, 4)
|
|
||||||
// genDocJSON_1, err := json.Marshal(genDoc_1)
|
|
||||||
// require.Nil(err)
|
|
||||||
|
|
||||||
// // Register a malformed chain
|
|
||||||
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{
|
|
||||||
// BlockchainGenesis{
|
|
||||||
// ChainID: "test_chain",
|
|
||||||
// Genesis: "<THIS IS NOT JSON>",
|
|
||||||
// },
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, IBCCodeEncodingError)
|
|
||||||
|
|
||||||
// // Successfully register a chain
|
|
||||||
// registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1))
|
|
||||||
|
|
||||||
// // Duplicate request fails
|
|
||||||
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{
|
|
||||||
// BlockchainGenesis{
|
|
||||||
// ChainID: "test_chain",
|
|
||||||
// Genesis: string(genDocJSON_1),
|
|
||||||
// },
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, IBCCodeChainAlreadyExists)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func TestIBCPluginPost(t *testing.T) {
|
|
||||||
// require := require.New(t)
|
|
||||||
|
|
||||||
// eyesClient := eyes.NewLocalClient("", 0)
|
|
||||||
// store := types.NewKVCache(eyesClient)
|
|
||||||
// store.SetLogging() // Log all activity
|
|
||||||
|
|
||||||
// ibcPlugin := New()
|
|
||||||
// ctx := types.NewCallContext(nil, nil, coin.Coins{})
|
|
||||||
|
|
||||||
// chainID_1 := "test_chain"
|
|
||||||
// genDoc_1, _ := genGenesisDoc(chainID_1, 4)
|
|
||||||
// genDocJSON_1, err := json.Marshal(genDoc_1)
|
|
||||||
// require.Nil(err)
|
|
||||||
|
|
||||||
// // Register a chain
|
|
||||||
// registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1))
|
|
||||||
|
|
||||||
// // Create a new packet (for testing)
|
|
||||||
// packet := NewPacket("test_chain", "dst_chain", 0, DataPayload([]byte("hello world")))
|
|
||||||
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
|
|
||||||
// Packet: packet,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_OK)
|
|
||||||
|
|
||||||
// // Post a duplicate packet
|
|
||||||
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
|
|
||||||
// Packet: packet,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, IBCCodePacketAlreadyExists)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func TestIBCPluginPayloadBytes(t *testing.T) {
|
|
||||||
// assert := assert.New(t)
|
|
||||||
// require := require.New(t)
|
|
||||||
|
|
||||||
// eyesClient := eyes.NewLocalClient("", 0)
|
|
||||||
// store := types.NewKVCache(eyesClient)
|
|
||||||
// store.SetLogging() // Log all activity
|
|
||||||
|
|
||||||
// ibcPlugin := New()
|
|
||||||
// ctx := types.NewCallContext(nil, nil, coin.Coins{})
|
|
||||||
|
|
||||||
// chainID_1 := "test_chain"
|
|
||||||
// genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4)
|
|
||||||
// genDocJSON_1, err := json.Marshal(genDoc_1)
|
|
||||||
// require.Nil(err)
|
|
||||||
|
|
||||||
// // Register a chain
|
|
||||||
// registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1))
|
|
||||||
|
|
||||||
// // Create a new packet (for testing)
|
|
||||||
// packet := NewPacket("test_chain", "dst_chain", 0, DataPayload([]byte("hello world")))
|
|
||||||
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
|
|
||||||
// Packet: packet,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_OK)
|
|
||||||
|
|
||||||
// // Construct a Header that includes the above packet.
|
|
||||||
// store.Sync()
|
|
||||||
// resCommit := eyesClient.CommitSync()
|
|
||||||
// appHash := resCommit.Data
|
|
||||||
// header := newHeader("test_chain", 999, appHash, []byte("must_exist"))
|
|
||||||
|
|
||||||
// // Construct a Commit that signs above header
|
|
||||||
// commit := constructCommit(privAccs_1, header)
|
|
||||||
|
|
||||||
// // Update a chain
|
|
||||||
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{
|
|
||||||
// Header: header,
|
|
||||||
// Commit: commit,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_OK)
|
|
||||||
|
|
||||||
// // Get proof for the packet
|
|
||||||
// packetKey := toKey(_IBC, _EGRESS,
|
|
||||||
// packet.SrcChainID,
|
|
||||||
// packet.DstChainID,
|
|
||||||
// cmn.Fmt("%v", packet.Sequence),
|
|
||||||
// )
|
|
||||||
// resQuery, err := eyesClient.QuerySync(abci.RequestQuery{
|
|
||||||
// Path: "/store",
|
|
||||||
// Data: packetKey,
|
|
||||||
// Prove: true,
|
|
||||||
// })
|
|
||||||
// assert.Nil(err)
|
|
||||||
// var proof *iavl.IAVLProof
|
|
||||||
// err = wire.ReadBinaryBytes(resQuery.Proof, &proof)
|
|
||||||
// assert.Nil(err)
|
|
||||||
|
|
||||||
// // Post a packet
|
|
||||||
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketPostTx{
|
|
||||||
// FromChainID: "test_chain",
|
|
||||||
// FromChainHeight: 999,
|
|
||||||
// Packet: packet,
|
|
||||||
// Proof: proof,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_OK)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func TestIBCPluginPayloadCoins(t *testing.T) {
|
|
||||||
// assert := assert.New(t)
|
|
||||||
// require := require.New(t)
|
|
||||||
|
|
||||||
// eyesClient := eyes.NewLocalClient("", 0)
|
|
||||||
// store := types.NewKVCache(eyesClient)
|
|
||||||
// store.SetLogging() // Log all activity
|
|
||||||
|
|
||||||
// ibcPlugin := New()
|
|
||||||
// coins := coin.Coins{
|
|
||||||
// coin.Coin{
|
|
||||||
// Denom: "mycoin",
|
|
||||||
// Amount: 100,
|
|
||||||
// },
|
|
||||||
// }
|
|
||||||
// ctx := types.NewCallContext(nil, nil, coins)
|
|
||||||
|
|
||||||
// chainID_1 := "test_chain"
|
|
||||||
// genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4)
|
|
||||||
// genDocJSON_1, err := json.Marshal(genDoc_1)
|
|
||||||
// require.Nil(err)
|
|
||||||
|
|
||||||
// // Register a chain
|
|
||||||
// registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1))
|
|
||||||
|
|
||||||
// // send coins to this addr on the other chain
|
|
||||||
// destinationAddr := []byte("some address")
|
|
||||||
// coinsBad := coin.Coins{coin.Coin{"mycoin", 200}}
|
|
||||||
// coinsGood := coin.Coins{coin.Coin{"mycoin", 1}}
|
|
||||||
|
|
||||||
// // Try to send too many coins
|
|
||||||
// packet := NewPacket("test_chain", "dst_chain", 0, CoinsPayload{
|
|
||||||
// Address: destinationAddr,
|
|
||||||
// Coins: coinsBad,
|
|
||||||
// })
|
|
||||||
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
|
|
||||||
// Packet: packet,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_InsufficientFunds)
|
|
||||||
|
|
||||||
// // Send a small enough number of coins
|
|
||||||
// packet = NewPacket("test_chain", "dst_chain", 0, CoinsPayload{
|
|
||||||
// Address: destinationAddr,
|
|
||||||
// Coins: coinsGood,
|
|
||||||
// })
|
|
||||||
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
|
|
||||||
// Packet: packet,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_OK)
|
|
||||||
|
|
||||||
// // Construct a Header that includes the above packet.
|
|
||||||
// store.Sync()
|
|
||||||
// resCommit := eyesClient.CommitSync()
|
|
||||||
// appHash := resCommit.Data
|
|
||||||
// header := newHeader("test_chain", 999, appHash, []byte("must_exist"))
|
|
||||||
|
|
||||||
// // Construct a Commit that signs above header
|
|
||||||
// commit := constructCommit(privAccs_1, header)
|
|
||||||
|
|
||||||
// // Update a chain
|
|
||||||
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{
|
|
||||||
// Header: header,
|
|
||||||
// Commit: commit,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_OK)
|
|
||||||
|
|
||||||
// // Get proof for the packet
|
|
||||||
// packetKey := toKey(_IBC, _EGRESS,
|
|
||||||
// packet.SrcChainID,
|
|
||||||
// packet.DstChainID,
|
|
||||||
// cmn.Fmt("%v", packet.Sequence),
|
|
||||||
// )
|
|
||||||
// resQuery, err := eyesClient.QuerySync(abci.RequestQuery{
|
|
||||||
// Path: "/store",
|
|
||||||
// Data: packetKey,
|
|
||||||
// Prove: true,
|
|
||||||
// })
|
|
||||||
// assert.Nil(err)
|
|
||||||
// var proof *iavl.IAVLProof
|
|
||||||
// err = wire.ReadBinaryBytes(resQuery.Proof, &proof)
|
|
||||||
// assert.Nil(err)
|
|
||||||
|
|
||||||
// // Account should be empty before the tx
|
|
||||||
// acc := types.GetAccount(store, destinationAddr)
|
|
||||||
// assert.Nil(acc)
|
|
||||||
|
|
||||||
// // Post a packet
|
|
||||||
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketPostTx{
|
|
||||||
// FromChainID: "test_chain",
|
|
||||||
// FromChainHeight: 999,
|
|
||||||
// Packet: packet,
|
|
||||||
// Proof: proof,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_OK)
|
|
||||||
|
|
||||||
// // Account should now have some coins
|
|
||||||
// acc = types.GetAccount(store, destinationAddr)
|
|
||||||
// assert.Equal(acc.Balance, coinsGood)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func TestIBCPluginBadCommit(t *testing.T) {
|
|
||||||
// require := require.New(t)
|
|
||||||
|
|
||||||
// eyesClient := eyes.NewLocalClient("", 0)
|
|
||||||
// store := types.NewKVCache(eyesClient)
|
|
||||||
// store.SetLogging() // Log all activity
|
|
||||||
|
|
||||||
// ibcPlugin := New()
|
|
||||||
// ctx := types.NewCallContext(nil, nil, coin.Coins{})
|
|
||||||
|
|
||||||
// chainID_1 := "test_chain"
|
|
||||||
// genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4)
|
|
||||||
// genDocJSON_1, err := json.Marshal(genDoc_1)
|
|
||||||
// require.Nil(err)
|
|
||||||
|
|
||||||
// // Successfully register a chain
|
|
||||||
// registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1))
|
|
||||||
|
|
||||||
// // Construct a Header
|
|
||||||
// header := newHeader("test_chain", 999, nil, []byte("must_exist"))
|
|
||||||
|
|
||||||
// // Construct a Commit that signs above header
|
|
||||||
// commit := constructCommit(privAccs_1, header)
|
|
||||||
|
|
||||||
// // Update a chain with a broken commit
|
|
||||||
// // Modify the first byte of the first signature
|
|
||||||
// sig := commit.Precommits[0].Signature.Unwrap().(crypto.SignatureEd25519)
|
|
||||||
// sig[0] += 1
|
|
||||||
// commit.Precommits[0].Signature = sig.Wrap()
|
|
||||||
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{
|
|
||||||
// Header: header,
|
|
||||||
// Commit: commit,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, IBCCodeInvalidCommit)
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func TestIBCPluginBadProof(t *testing.T) {
|
|
||||||
// assert := assert.New(t)
|
|
||||||
// require := require.New(t)
|
|
||||||
|
|
||||||
// eyesClient := eyes.NewLocalClient("", 0)
|
|
||||||
// store := types.NewKVCache(eyesClient)
|
|
||||||
// store.SetLogging() // Log all activity
|
|
||||||
|
|
||||||
// ibcPlugin := New()
|
|
||||||
// ctx := types.NewCallContext(nil, nil, coin.Coins{})
|
|
||||||
|
|
||||||
// chainID_1 := "test_chain"
|
|
||||||
// genDoc_1, privAccs_1 := genGenesisDoc(chainID_1, 4)
|
|
||||||
// genDocJSON_1, err := json.Marshal(genDoc_1)
|
|
||||||
// require.Nil(err)
|
|
||||||
|
|
||||||
// // Successfully register a chain
|
|
||||||
// registerChain(t, ibcPlugin, store, ctx, "test_chain", string(genDocJSON_1))
|
|
||||||
|
|
||||||
// // Create a new packet (for testing)
|
|
||||||
// packet := NewPacket("test_chain", "dst_chain", 0, DataPayload([]byte("hello world")))
|
|
||||||
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketCreateTx{
|
|
||||||
// Packet: packet,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_OK)
|
|
||||||
|
|
||||||
// // Construct a Header that includes the above packet.
|
|
||||||
// store.Sync()
|
|
||||||
// resCommit := eyesClient.CommitSync()
|
|
||||||
// appHash := resCommit.Data
|
|
||||||
// header := newHeader("test_chain", 999, appHash, []byte("must_exist"))
|
|
||||||
|
|
||||||
// // Construct a Commit that signs above header
|
|
||||||
// commit := constructCommit(privAccs_1, header)
|
|
||||||
|
|
||||||
// // Update a chain
|
|
||||||
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCUpdateChainTx{
|
|
||||||
// Header: header,
|
|
||||||
// Commit: commit,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_OK)
|
|
||||||
|
|
||||||
// // Get proof for the packet
|
|
||||||
// packetKey := toKey(_IBC, _EGRESS,
|
|
||||||
// packet.SrcChainID,
|
|
||||||
// packet.DstChainID,
|
|
||||||
// cmn.Fmt("%v", packet.Sequence),
|
|
||||||
// )
|
|
||||||
// resQuery, err := eyesClient.QuerySync(abci.RequestQuery{
|
|
||||||
// Path: "/store",
|
|
||||||
// Data: packetKey,
|
|
||||||
// Prove: true,
|
|
||||||
// })
|
|
||||||
// assert.Nil(err)
|
|
||||||
// var proof *iavl.IAVLProof
|
|
||||||
// err = wire.ReadBinaryBytes(resQuery.Proof, &proof)
|
|
||||||
// assert.Nil(err)
|
|
||||||
|
|
||||||
// // Mutate the proof
|
|
||||||
// proof.InnerNodes[0].Height += 1
|
|
||||||
|
|
||||||
// // Post a packet
|
|
||||||
// res = ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCPacketPostTx{
|
|
||||||
// FromChainID: "test_chain",
|
|
||||||
// FromChainHeight: 999,
|
|
||||||
// Packet: packet,
|
|
||||||
// Proof: proof,
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, IBCCodeInvalidProof)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// //-------------------------------------
|
|
||||||
// // utils
|
|
||||||
|
|
||||||
// func assertAndLog(t *testing.T, store *types.KVCache, res abci.Result, codeExpected abci.CodeType) {
|
|
||||||
// assert := assert.New(t)
|
|
||||||
// assert.Equal(codeExpected, res.Code, res.Log)
|
|
||||||
// t.Log(">>", strings.Join(store.GetLogLines(), "\n"))
|
|
||||||
// store.ClearLogLines()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func newHeader(chainID string, height int, appHash, valHash []byte) tm.Header {
|
|
||||||
// return tm.Header{
|
|
||||||
// ChainID: chainID,
|
|
||||||
// Height: height,
|
|
||||||
// AppHash: appHash,
|
|
||||||
// ValidatorsHash: valHash,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func registerChain(t *testing.T, ibcPlugin *IBCPlugin, store *types.KVCache, ctx types.CallContext, chainID, genDoc string) {
|
|
||||||
// res := ibcPlugin.RunTx(store, ctx, wire.BinaryBytes(struct{ IBCTx }{IBCRegisterChainTx{
|
|
||||||
// BlockchainGenesis{
|
|
||||||
// ChainID: chainID,
|
|
||||||
// Genesis: genDoc,
|
|
||||||
// },
|
|
||||||
// }}))
|
|
||||||
// assertAndLog(t, store, res, abci.CodeType_OK)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// func constructCommit(privAccs []types.PrivAccount, header tm.Header) tm.Commit {
|
|
||||||
// blockHash := header.Hash()
|
|
||||||
// blockID := tm.BlockID{Hash: blockHash}
|
|
||||||
// commit := tm.Commit{
|
|
||||||
// BlockID: blockID,
|
|
||||||
// Precommits: make([]*tm.Vote, len(privAccs)),
|
|
||||||
// }
|
|
||||||
// for i, privAcc := range privAccs {
|
|
||||||
// vote := &tm.Vote{
|
|
||||||
// ValidatorAddress: privAcc.Account.PubKey.Address(),
|
|
||||||
// ValidatorIndex: i,
|
|
||||||
// Height: 999,
|
|
||||||
// Round: 0,
|
|
||||||
// Type: tm.VoteTypePrecommit,
|
|
||||||
// BlockID: tm.BlockID{Hash: blockHash},
|
|
||||||
// }
|
|
||||||
// vote.Signature = privAcc.PrivKey.Sign(
|
|
||||||
// tm.SignBytes("test_chain", vote),
|
|
||||||
// )
|
|
||||||
// commit.Precommits[i] = vote
|
|
||||||
// }
|
|
||||||
// return commit
|
|
||||||
// }
|
|
Loading…
Reference in New Issue