Skip to content

Commit

Permalink
[R4R] refactor cross chain functions (#133)
Browse files Browse the repository at this point in the history
* refactor cross chain functions

* add unbind msg
  • Loading branch information
yutianwu authored Jun 29, 2020
1 parent 24952c3 commit 70b8ec6
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 192 deletions.
81 changes: 19 additions & 62 deletions client/rpc/dex_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package rpc

import (
"encoding/binary"
"encoding/json"
"errors"
"fmt"
"strings"

core_types "github.com/tendermint/tendermint/rpc/core/types"

"github.com/binance-chain/go-sdk/common"
"github.com/binance-chain/go-sdk/common/types"
sdk "github.com/binance-chain/go-sdk/common/types"
"github.com/binance-chain/go-sdk/keys"
gtypes "github.com/binance-chain/go-sdk/types"
"github.com/binance-chain/go-sdk/types/msg"
Expand All @@ -28,6 +27,7 @@ const (
const (
AccountStoreName = "acc"
OracleStoreName = "oracle"
SideChainStoreName = "sc"
BridgeStoreName = "bridge"
ParamABCIPrefix = "param"
TimeLockMsgRoute = "timelock"
Expand Down Expand Up @@ -69,17 +69,13 @@ type DexClient interface {
ClaimHTLT(swapID []byte, randomNumber []byte, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error)
RefundHTLT(swapID []byte, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error)

UpdateBind(sequence int64, symbol string, contractAddress msg.SmartChainAddress, status msg.BindStatus, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error)
TransferOutRefund(sequence int64, refundAddr types.AccAddress, amount types.Coin, refundReason msg.RefundReason, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error)
Bind(symbol string, amount int64, contractAddress msg.SmartChainAddress, contractDecimals int8, expireTime int64, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error)
Unbind(symbol string, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error)
TransferOut(to msg.SmartChainAddress, amount types.Coin, expireTime int64, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error)
TransferIn(sequence int64, contractAddr msg.SmartChainAddress,
refundAddresses []msg.SmartChainAddress, receiverAddresses []types.AccAddress, amounts []int64, symbol string,
relayFee types.Coin, expireTime int64, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error)

Claim(claimType msg.ClaimType, claim string, sequence int64, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error)
GetProphecy(claimType msg.ClaimType, sequence int64) (*msg.Prophecy, error)
GetCurrentSequence(claimType msg.ClaimType) (int64, error)
Claim(chainId sdk.IbcChainID, sequence uint64, payload []byte, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error)
GetProphecy(chainId sdk.IbcChainID, sequence int64) (*msg.Prophecy, error)
GetCurrentOracleSequence(chainId sdk.IbcChainID) (int64, error)
}

func (c *HTTP) TxInfoSearch(query string, prove bool, page, perPage int) ([]Info, error) {
Expand Down Expand Up @@ -662,26 +658,6 @@ func (c *HTTP) CancelOrder(baseAssetSymbol, quoteAssetSymbol, refId string, sync
return c.Broadcast(cancelOrderMsg, syncType, options...)
}

func (c *HTTP) TransferIn(sequence int64, contractAddr msg.SmartChainAddress,
refundAddresses []msg.SmartChainAddress, receiverAddresses []types.AccAddress, amounts []int64, symbol string,
relayFee types.Coin, expireTime int64, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error) {
claim := msg.TransferInClaim{
ContractAddress: contractAddr,
RefundAddresses: refundAddresses,
ReceiverAddresses: receiverAddresses,
Amounts: amounts,
Symbol: symbol,
RelayFee: relayFee,
ExpireTime: expireTime,
}

claimBz, err := json.Marshal(claim)
if err != nil {
return nil, err
}
return c.Claim(msg.ClaimTypeTransferIn, string(claimBz), sequence, syncType, options...)
}

func (c *HTTP) TransferOut(to msg.SmartChainAddress, amount types.Coin, expireTime int64, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error) {
if c.key == nil {
return nil, KeyMissingError
Expand All @@ -706,33 +682,15 @@ func (c *HTTP) Bind(symbol string, amount int64, contractAddress msg.SmartChainA
return c.Broadcast(bindMsg, syncType, options...)
}

func (c *HTTP) TransferOutRefund(sequence int64, refundAddr types.AccAddress, amount types.Coin, refundReason msg.RefundReason, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error) {
claim := msg.TransferOutRefundClaim{
RefundAddress: refundAddr,
Amount: amount,
RefundReason: refundReason,
}

claimBz, err := json.Marshal(claim)
if err != nil {
return nil, err
func (c *HTTP) Unbind(symbol string, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error) {
if c.key == nil {
return nil, KeyMissingError
}

return c.Claim(msg.ClaimTypeTransferOutRefund, string(claimBz), sequence, syncType, options...)
}

func (c *HTTP) UpdateBind(sequence int64, symbol string, contractAddress msg.SmartChainAddress, status msg.BindStatus, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error) {
claim := msg.UpdateBindClaim{
Status: status,
Symbol: strings.ToUpper(symbol),
ContractAddress: contractAddress,
}
fromAddr := c.key.GetAddr()

claimBz, err := json.Marshal(claim)
if err != nil {
return nil, err
}
return c.Claim(msg.ClaimTypeUpdateBind, string(claimBz), sequence, syncType, options...)
unbindMsg := msg.NewUnbindMsg(fromAddr, symbol)
return c.Broadcast(unbindMsg, syncType, options...)
}

func (c *HTTP) Broadcast(m msg.Msg, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error) {
Expand Down Expand Up @@ -769,20 +727,20 @@ func (c *HTTP) Broadcast(m msg.Msg, syncType SyncType, options ...tx.Option) (*c
}
}

func (c *HTTP) Claim(claimType msg.ClaimType, claim string, sequence int64, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error) {
func (c *HTTP) Claim(chainId sdk.IbcChainID, sequence uint64, payload []byte, syncType SyncType, options ...tx.Option) (*core_types.ResultBroadcastTx, error) {
if c.key == nil {
return nil, KeyMissingError
}

fromAddr := c.key.GetAddr()

claimMsg := msg.NewClaimMsg(claimType, sequence, claim, fromAddr)
claimMsg := msg.NewClaimMsg(chainId, sequence, payload, fromAddr)

return c.Broadcast(claimMsg, syncType, options...)
}

func (c *HTTP) GetProphecy(claimType msg.ClaimType, sequence int64) (*msg.Prophecy, error) {
key := []byte(msg.GetClaimId(claimType, sequence))
func (c *HTTP) GetProphecy(chainId sdk.IbcChainID, sequence int64) (*msg.Prophecy, error) {
key := []byte(msg.GetClaimId(chainId, msg.OracleChannelId, sequence))
bz, err := c.QueryStore(key, OracleStoreName)
if err != nil {
return nil, err
Expand All @@ -805,9 +763,9 @@ func (c *HTTP) GetProphecy(claimType msg.ClaimType, sequence int64) (*msg.Prophe
return &prophecy, err
}

func (c *HTTP) GetCurrentSequence(claimType msg.ClaimType) (int64, error) {
key := msg.GetClaimTypeSequence(claimType)
bz, err := c.QueryStore(key, OracleStoreName)
func (c *HTTP) GetCurrentOracleSequence(chainId sdk.IbcChainID) (int64, error) {
key := types.GetReceiveSequenceKey(chainId, msg.OracleChannelId)
bz, err := c.QueryStore(key, SideChainStoreName)
if err != nil {
return 0, err
}
Expand All @@ -816,7 +774,6 @@ func (c *HTTP) GetCurrentSequence(claimType msg.ClaimType) (int64, error) {
}

sequence := binary.BigEndian.Uint64(bz)

return int64(sequence), err
}

Expand Down
34 changes: 34 additions & 0 deletions common/types/oracle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package types

import (
"encoding/binary"
)

type IbcChannelID uint8
type IbcChainID uint16

const (
prefixLength = 1
destIbcChainIDLength = 2
channelIDLength = 1
)

var (
SideChainStorePrefixByIdKey = []byte{0x01} // prefix for each key to a side chain store prefix, by side chain id

PrefixForSendSequenceKey = []byte{0xf0}
PrefixForReceiveSequenceKey = []byte{0xf1}
)

func GetReceiveSequenceKey(destIbcChainID IbcChainID, channelID IbcChannelID) []byte {
return buildChannelSequenceKey(destIbcChainID, channelID, PrefixForReceiveSequenceKey)
}

func buildChannelSequenceKey(destIbcChainID IbcChainID, channelID IbcChannelID, prefix []byte) []byte {
key := make([]byte, prefixLength+destIbcChainIDLength+channelIDLength)

copy(key[:prefixLength], prefix)
binary.BigEndian.PutUint16(key[prefixLength:prefixLength+destIbcChainIDLength], uint16(destIbcChainID))
copy(key[prefixLength+destIbcChainIDLength:], []byte{byte(channelID)})
return key
}
92 changes: 49 additions & 43 deletions types/msg/msg-bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ const (
RouteBridge = "bridge"

BindMsgType = "crossBind"
UnbindMsgType = "crossUnbind"
TransferOutMsgType = "crossTransferOut"
)

const (
MaxSymbolLength = 32
)

// SmartChainAddress defines a standard smart chain address
type SmartChainAddress [20]byte

Expand Down Expand Up @@ -61,51 +66,8 @@ func (addr *SmartChainAddress) UnmarshalJSON(input []byte) error {
return nil
}

type TransferInClaim struct {
ContractAddress SmartChainAddress `json:"contract_address"`
RefundAddresses []SmartChainAddress `json:"refund_addresses"`
ReceiverAddresses []sdk.AccAddress `json:"receiver_addresses"`
Amounts []int64 `json:"amounts"`
Symbol string `json:"symbol"`
RelayFee sdk.Coin `json:"relay_fee"`
ExpireTime int64 `json:"expire_time"`
}

type RefundReason uint16

const (
UnboundToken RefundReason = 1
Timeout RefundReason = 2
InsufficientBalance RefundReason = 3
Unknown RefundReason = 4
)

type TransferOutRefundClaim struct {
RefundAddress sdk.AccAddress `json:"refund_address"`
Amount sdk.Coin `json:"amount"`
RefundReason RefundReason `json:"refund_reason"`
}

type BindStatus int8

const (
BindStatusSuccess BindStatus = 0
BindStatusRejected BindStatus = 1
BindStatusTimeout BindStatus = 2
BindStatusInvalidParameter BindStatus = 3
)

type UpdateBindClaim struct {
Status BindStatus `json:"status"`
Symbol string `json:"symbol"`
ContractAddress SmartChainAddress `json:"contract_address"`
}

type SkipSequenceClaim struct {
ClaimType ClaimType `json:"claim_type"`
Sequence int64 `json:"sequence"`
}

type BindMsg struct {
From sdk.AccAddress `json:"from"`
Symbol string `json:"symbol"`
Expand Down Expand Up @@ -219,3 +181,47 @@ func (msg TransferOutMsg) GetSignBytes() []byte {
}
return b
}

type UnbindMsg struct {
From sdk.AccAddress `json:"from"`
Symbol string `json:"symbol"`
}

func NewUnbindMsg(from sdk.AccAddress, symbol string) UnbindMsg {
return UnbindMsg{
From: from,
Symbol: symbol,
}
}

func (msg UnbindMsg) Route() string { return RouteBridge }
func (msg UnbindMsg) Type() string { return UnbindMsgType }
func (msg UnbindMsg) String() string {
return fmt.Sprintf("Unbind{%v#%s}", msg.From, msg.Symbol)
}
func (msg UnbindMsg) GetInvolvedAddresses() []sdk.AccAddress { return msg.GetSigners() }
func (msg UnbindMsg) GetSigners() []sdk.AccAddress { return []sdk.AccAddress{msg.From} }

func (msg UnbindMsg) ValidateBasic() error {
if len(msg.From) != sdk.AddrLen {
return fmt.Errorf("address length should be %d", sdk.AddrLen)
}

if len(msg.Symbol) == 0 {
return fmt.Errorf("symbol should not be empty")
}

if len(msg.Symbol) > MaxSymbolLength {
return fmt.Errorf("symbol length should not be larger than %d", MaxSymbolLength)
}

return nil
}

func (msg UnbindMsg) GetSignBytes() []byte {
b, err := json.Marshal(msg) // XXX: ensure some canonical form
if err != nil {
panic(err)
}
return b
}
Loading

0 comments on commit 70b8ec6

Please sign in to comment.