diff --git a/cmd/iconbridge/chain/bsc/receiver.go b/cmd/iconbridge/chain/bsc/receiver.go index 2ef7a4b58..439b5cbcd 100644 --- a/cmd/iconbridge/chain/bsc/receiver.go +++ b/cmd/iconbridge/chain/bsc/receiver.go @@ -13,12 +13,12 @@ import ( "sync" "time" - ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" ethCommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" ethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/bsc/types" "github.com/icon-project/icon-bridge/common/log" "github.com/pkg/errors" ) @@ -141,7 +141,7 @@ func (r *receiver) syncVerifier(ctx context.Context, vr IVerifier, height int64) type res struct { Height int64 - Header *types.Header + Header *ethTypes.Header } type req struct { @@ -153,7 +153,7 @@ func (r *receiver) syncVerifier(ctx context.Context, vr IVerifier, height int64) r.log.WithFields(log.Fields{"height": vr.Next().String(), "target": height}).Info("syncVerifier: start") - var prevHeader *types.Header + var prevHeader *ethTypes.Header cursor := vr.Next().Int64() for cursor <= height { rqch := make(chan *req, r.opts.SyncConcurrency) @@ -238,7 +238,7 @@ func (r *receiver) syncVerifier(ctx context.Context, vr IVerifier, height int64) return nil } -func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *BlockNotification) error) (err error) { +func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error) { if opts == nil { return errors.New("receiveLoop: invalid options: ") @@ -259,7 +259,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu // block notification channel // (buffered: to avoid deadlock) // increase concurrency parameter for faster sync - bnch := make(chan *BlockNotification, r.opts.SyncConcurrency) + bnch := make(chan *types.BlockNotification, r.opts.SyncConcurrency) heightTicker := time.NewTicker(BlockInterval) defer heightTicker.Stop() @@ -278,7 +278,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu next, latest := opts.StartHeight, latestHeight() // last unverified block notification - var lbn *BlockNotification + var lbn *types.BlockNotification // start monitor loop for { @@ -342,7 +342,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu type bnq struct { h uint64 - v *BlockNotification + v *types.BlockNotification err error retry int } @@ -355,7 +355,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu r.log.Error("Fatal: Zero length of query channel. Avoiding deadlock") continue } - bns := make([]*BlockNotification, 0, len(qch)) + bns := make([]*types.BlockNotification, 0, len(qch)) for q := range qch { switch { case q.err != nil: @@ -384,7 +384,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu }() if q.v == nil { - q.v = &BlockNotification{} + q.v = &types.BlockNotification{} } q.v.Height = (&big.Int{}).SetUint64(q.h) @@ -475,7 +475,7 @@ func (r *receiver) Subscribe( StartHeight: opts.Height, Concurrency: r.opts.SyncConcurrency, }, - func(v *BlockNotification) error { + func(v *types.BlockNotification) error { r.log.WithFields(log.Fields{"height": v.Height}).Debug("block notification") if v.Height.Uint64() != lastHeight+1 { @@ -516,7 +516,7 @@ func (r *receiver) Subscribe( return _errCh, nil } -func (r *receiver) getRelayReceipts(v *BlockNotification) []*chain.Receipt { +func (r *receiver) getRelayReceipts(v *types.BlockNotification) []*chain.Receipt { sc := common.HexToAddress(r.src.ContractAddress()) var receipts []*chain.Receipt var events []*chain.Event diff --git a/cmd/iconbridge/chain/bsc/receiver_test.go b/cmd/iconbridge/chain/bsc/receiver_test.go index a5eb42ef9..72dc78cdd 100644 --- a/cmd/iconbridge/chain/bsc/receiver_test.go +++ b/cmd/iconbridge/chain/bsc/receiver_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum" ethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -19,7 +19,7 @@ import ( "github.com/icon-project/icon-bridge/cmd/e2etest/chain/bsc/abi/bmcperiphery" "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/bsc/mocks" - bscTypes "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/bsc/types" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/bsc/types" "github.com/icon-project/icon-bridge/common/intconv" "github.com/icon-project/icon-bridge/common/log" "github.com/icon-project/icon-bridge/common/wallet" @@ -29,9 +29,7 @@ import ( ) const ( - ICON_BMC = "btp://0x7.icon/cx8a6606d526b96a16e6764aee5d9abecf926689df" BSC_BMC_PERIPHERY = "btp://0x61.bsc/0xB4fC4b3b4e3157448B7D279f06BC8e340d63e2a9" - BlockHeight = 21447824 ) func newTestReceiver(t *testing.T, src, dst chain.BTPAddress) chain.Receiver { @@ -503,7 +501,7 @@ func Test_MockReceiveLoop(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second) defer cancel() err := rx.receiveLoop(ctx, &BnOptions{StartHeight: 23033451, Concurrency: 1}, - func(v *BlockNotification) error { + func(v *types.BlockNotification) error { if v.HasBTPMessage != nil && *v.HasBTPMessage { if !blockHasBTPMessage[int(v.Height.Int64())] { return fmt.Errorf("Expected hasBTPMessage %v Got %v", blockHasBTPMessage[int(v.Height.Int64())], *v.HasBTPMessage) @@ -721,7 +719,7 @@ func TestClient_MockMedianGasPrice(t *testing.T) { func TestClient_MockBlockReceipts(t *testing.T) { blkHash := ethCommon.HexToHash("0x941bf8efb2664191d52fdc4745ea07129aa6032097c0a434ac0e652f592ad00f") //blkNumber := 23033400 - blk := &bscTypes.Block{ + blk := &types.Block{ Transactions: []string{"0x4d2c7826773b5e9a74eebff4fa6cba796faf6e318c4710a45b4afba7830de5da", "0x33f061ca51140df25c48d52e867df338b3771b431035d7b8bd2045346fec0372"}, GasUsed: "0x203c27", } diff --git a/cmd/iconbridge/chain/bsc/sender.go b/cmd/iconbridge/chain/bsc/sender.go index 13e3aa1ef..9bb17754e 100644 --- a/cmd/iconbridge/chain/bsc/sender.go +++ b/cmd/iconbridge/chain/bsc/sender.go @@ -47,31 +47,6 @@ const ( DefaultGasLimit = 25000000 ) -/* - type sender struct { - c *Client - src module.BtpAddress - dst module.BtpAddress - w Wallet - l log.Logger - opt struct { - } - - bmc *binding.BMC - - evtLogRawFilter struct { - addr []byte - signature []byte - next []byte - seq []byte - } - evtReq *BlockRequest - isFoundOffsetBySeq bool - cb module.ReceiveCallback - - mutex sync.Mutex - } -*/ type senderOptions struct { GasLimit uint64 `json:"gas_limit"` @@ -360,135 +335,3 @@ func revertReason(data []byte) string { length := binary.BigEndian.Uint64(data[24:32]) return string(data[32 : 32+length]) } - -/* - func (s *sender) newTransactionParam(prev string, rm *RelayMessage) (*TransactionParam, error) { - b, err := codec.RLP.MarshalToBytes(rm) - if err != nil { - return nil, err - } - rmp := BMCRelayMethodParams{ - Prev: prev, - //Messages: base64.URLEncoding.EncodeToString(b[:]), - Messages: string(b[:]), - } - s.l.Debugf("HandleRelayMessage msg: %s", base64.URLEncoding.EncodeToString(b)) - p := &TransactionParam{ - Params: rmp, - } - return p, nil - } - - func (s *sender) Relay(segment *module.Segment) (module.GetResultParam, error) { - s.mutex.Lock() - defer s.mutex.Unlock() - p, ok := segment.TransactionParam.(*TransactionParam) - if !ok { - return nil, fmt.Errorf("casting failure") - } - t, err := s.c.newTransactOpts(s.w) - if err != nil { - return nil, err - } - rmp := p.Params.(BMCRelayMethodParams) - var tx *types.Transaction - tx, err = s.bmc.HandleRelayMessage(t, rmp.Prev, rmp.Messages) - if err != nil { - s.l.Errorf("handleRelayMessage: ", err.Error()) - return nil, err - } - thp := &TransactionHashParam{} - thp.Hash = tx.Hash() - s.l.Debugf("HandleRelayMessage tx hash:%s, prev %s, msg: %s", thp.Hash, rmp.Prev, base64.URLEncoding.EncodeToString([]byte(rmp.Messages))) - return thp, nil - } - - func (s *sender) GetResult(p module.GetResultParam) (module.TransactionResult, error) { - if txh, ok := p.(*TransactionHashParam); ok { - for { - _, pending, err := s.c.GetTransaction(txh.Hash) - if err != nil { - return nil, err - } - if pending { - <-time.After(DefaultGetRelayResultInterval) - continue - } - tx, err := s.c.GetTransactionReceipt(txh.Hash) - if err != nil { - return nil, err - } - return tx, nil //mapErrorWithTransactionResult(&types.Receipt{}, err) // TODO: map transaction.js result error - } - } else { - return nil, fmt.Errorf("fail to casting TransactionHashParam %T", p) - } - } - - func (s *sender) GetStatus() (*module.BMCLinkStatus, error) { - var status binding.TypesLinkStats - status, err := s.bmc.GetStatus(nil, s.src.String()) - - if err != nil { - s.l.Errorf("Error retrieving relay status from BMC") - return nil, err - } - - ls := &module.BMCLinkStatus{} - ls.TxSeq = status.TxSeq.Int64() - ls.RxSeq = status.RxSeq.Int64() - ls.BMRIndex = int(status.RelayIdx.Int64()) - ls.RotateHeight = status.RotateHeight.Int64() - ls.RotateTerm = int(status.RotateTerm.Int64()) - ls.DelayLimit = int(status.DelayLimit.Int64()) - ls.MaxAggregation = int(status.MaxAggregation.Int64()) - ls.CurrentHeight = status.CurrentHeight.Int64() - ls.RxHeight = status.RxHeight.Int64() - ls.RxHeightSrc = status.RxHeightSrc.Int64() - return ls, nil - } - - func (s *sender) isOverLimit(size int) bool { - return txSizeLimit < float64(size) - } - - func (s *sender) MonitorLoop(height int64, cb module.MonitorCallback, scb func()) error { - s.l.Debugf("MonitorLoop (sender) connected") - br := &BlockRequest{ - Height: big.NewInt(height), - } - return s.c.MonitorBlock(br, - func(v *BlockNotification) error { - return cb(v.Height.Int64()) - }) - } - - func (s *sender) StopMonitorLoop() { - s.c.CloseAllMonitor() - } - func (s *sender) FinalizeLatency() int { - //on-the-next - return 1 - } - - func NewSender(src, dst module.BtpAddress, w Wallet, endpoints []string, opt map[string]interface{}, l log.Logger) module.Sender { - s := &sender{ - src: src, - dst: dst, - w: w, - l: l, - } - b, err := json.Marshal(opt) - if err != nil { - l.Panicf("fail to marshal opt:%#v err:%+v", opt, err) - } - if err = json.Unmarshal(b, &s.opt); err != nil { - l.Panicf("fail to unmarshal opt:%#v err:%+v", opt, err) - } - s.c = NewClient(endpoints, l) - - s.bmc, _ = binding.NewBMC(HexToAddress(s.dst.ContractAddress()), s.c.ethcl) - - return s - } -*/ diff --git a/cmd/iconbridge/chain/bsc/type.go b/cmd/iconbridge/chain/bsc/type.go deleted file mode 100644 index 988cb33ef..000000000 --- a/cmd/iconbridge/chain/bsc/type.go +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package bsc - -import ( - "encoding/hex" - "fmt" - "math/big" - "strconv" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/icon-project/icon-bridge/common/jsonrpc" -) - -const ( - JsonrpcApiVersion = 3 - JsonrpcErrorCodeSystem jsonrpc.ErrorCode = -31000 - JsonrpcErrorCodeTxPoolOverflow jsonrpc.ErrorCode = -31001 - JsonrpcErrorCodePending jsonrpc.ErrorCode = -31002 - JsonrpcErrorCodeExecuting jsonrpc.ErrorCode = -31003 - JsonrpcErrorCodeNotFound jsonrpc.ErrorCode = -31004 - JsonrpcErrorLackOfResource jsonrpc.ErrorCode = -31005 - JsonrpcErrorCodeTimeout jsonrpc.ErrorCode = -31006 - JsonrpcErrorCodeSystemTimeout jsonrpc.ErrorCode = -31007 - JsonrpcErrorCodeScore jsonrpc.ErrorCode = -30000 -) - -const ( - DuplicateTransactionError = iota + 2000 - TransactionPoolOverflowError - ExpiredTransactionError - FutureTransactionError - TransitionInterruptedError - InvalidTransactionError - InvalidQueryError - InvalidResultError - NoActiveContractError - NotContractAddressError - InvalidPatchDataError - CommittedTransactionError -) - -const ( - ResultStatusSuccess = "0x1" - ResultStatusFailureCodeRevert = 32 - ResultStatusFailureCodeEnd = 99 -) - -type EventLog struct { - Addr []byte - Indexed [][]byte - Data [][]byte -} - -type TransactionResult struct { - To Address `json:"to"` - CumulativeStepUsed HexInt `json:"cumulativeStepUsed"` - StepUsed HexInt `json:"stepUsed"` - StepPrice HexInt `json:"stepPrice"` - EventLogs []struct { - Addr Address `json:"scoreAddress"` - Indexed []string `json:"indexed"` - Data []string `json:"data"` - } `json:"eventLogs"` - LogsBloom HexBytes `json:"logsBloom"` - Status HexInt `json:"status"` - Failure *struct { - CodeValue HexInt `json:"code"` - MessageValue string `json:"message"` - } `json:"failure,omitempty"` - SCOREAddress Address `json:"scoreAddress,omitempty"` - BlockHash HexBytes `json:"blockHash" validate:"required,t_hash"` - BlockHeight HexInt `json:"blockHeight" validate:"required,t_int"` - TxIndex HexInt `json:"txIndex" validate:"required,t_int"` - TxHash HexBytes `json:"txHash" validate:"required,t_int"` -} - -type TransactionParam struct { - FromAddress string `json:"from" validate:"required,t_addr_eoa"` - ToAddress string `json:"to" validate:"required,t_addr"` - NetworkID HexInt `json:"nid" validate:"required,t_int"` - Params interface{} `json:"params,omitempty"` - TransactOpt *bind.TransactOpts -} - -type BMCRelayMethodParams struct { - Prev string `json:"_prev"` - Messages string `json:"_msg"` -} - -type BMCStatus struct { - TxSeq HexInt `json:"tx_seq"` - RxSeq HexInt `json:"rx_seq"` - BMRIndex HexInt `json:"relay_idx"` - RotateHeight HexInt `json:"rotate_height"` - RotateTerm HexInt `json:"rotate_term"` - DelayLimit HexInt `json:"delay_limit"` - MaxAggregation HexInt `json:"max_agg"` - CurrentHeight HexInt `json:"cur_height"` - RxHeight HexInt `json:"rx_height"` - RxHeightSrc HexInt `json:"rx_height_src"` - BlockIntervalSrc HexInt `json:"block_interval_src"` - BlockIntervalDst HexInt `json:"block_interval_dst"` -} - -type TransactionHashParam struct { - Hash common.Hash -} - -type BlockRequest struct { - Height *big.Int `json:"height"` - EventFilters []*EventFilter `json:"eventFilters,omitempty"` - SrcContractAddress common.Address `json:"srcContractAddress,omitempty"` -} - -type EventFilter struct { - Addr Address `json:"addr,omitempty"` - Signature string `json:"event"` - Indexed []*string `json:"indexed,omitempty"` - Data []*string `json:"data,omitempty"` -} - -type BlockNotification struct { - Hash common.Hash - Height *big.Int - Header *types.Header - Receipts types.Receipts - HasBTPMessage *bool -} - -type RelayMessage struct { - ReceiptProofs [][]byte - // - height int64 - eventSequence int64 - numberOfEvent int -} - -type ReceiptProof struct { - Index int - Events []byte - Height int64 -} - -type EVMLog struct { - Address string - Topics [][]byte - Data []byte - BlockNumber uint64 - TxHash []byte - TxIndex uint - BlockHash []byte - Index uint - Removed bool -} - -func MakeLog(log *types.Log) *EVMLog { - topics := make([][]byte, 0) - - for _, topic := range log.Topics { - topics = append(topics, topic.Bytes()) - } - - return &EVMLog{ - Address: log.Address.String(), - Topics: topics, - Data: log.Data, - BlockNumber: log.BlockNumber, - TxHash: log.TxHash.Bytes(), - TxIndex: log.TxIndex, - BlockHash: log.BlockHash.Bytes(), - Index: log.Index, - Removed: log.Removed, - } -} - -type Receipt struct { - // Consensus fields: These fields are defined by the Yellow Paper - Type uint8 - PostState []byte - Status uint64 - CumulativeGasUsed uint64 - Bloom []byte - Logs []*EVMLog - - TxHash common.Hash - ContractAddress common.Address - GasUsed uint64 - - BlockHash common.Hash - BlockNumber uint64 - TransactionIndex uint -} - -func MakeReceipt(receipt *types.Receipt) *Receipt { - logs := make([]*EVMLog, len(receipt.Logs)) - - for _, log := range receipt.Logs { - logs = append(logs, MakeLog(log)) - } - - return &Receipt{ - Type: receipt.Type, - PostState: receipt.PostState, - Status: receipt.Status, - CumulativeGasUsed: receipt.CumulativeGasUsed, - Bloom: receipt.Bloom.Bytes(), - Logs: logs, - TxHash: receipt.TxHash, - ContractAddress: receipt.ContractAddress, - GasUsed: receipt.GasUsed, - BlockHash: receipt.BlockHash, - BlockNumber: receipt.BlockNumber.Uint64(), - TransactionIndex: receipt.TransactionIndex, - } -} - -func HexToAddress(s string) common.Address { - return common.HexToAddress(s) -} - -// HexBytes T_BIN_DATA, T_HASH -type HexBytes string - -func (hs HexBytes) Value() ([]byte, error) { - if hs == "" { - return nil, nil - } - return hex.DecodeString(string(hs[2:])) -} - -// HexInt T_INT -type HexInt string - -func (i HexInt) Value() (int64, error) { - s := string(i) - if strings.HasPrefix(s, "0x") { - s = s[2:] - } - return strconv.ParseInt(s, 16, 64) -} - -func (i HexInt) Int() (int, error) { - s := string(i) - if strings.HasPrefix(s, "0x") { - s = s[2:] - } - v, err := strconv.ParseInt(s, 16, 32) - return int(v), err -} - -// Address T_ADDR_EOA, T_ADDR_SCORE -type Address string - -func (a Address) Value() ([]byte, error) { - var b [21]byte - switch a[:2] { - case "cx": - b[0] = 1 - case "hx": - default: - return nil, fmt.Errorf("invalid prefix %s", a[:2]) - } - n, err := hex.Decode(b[1:], []byte(a[2:])) - if err != nil { - return nil, err - } - if n != 20 { - return nil, fmt.Errorf("invalid length %d", n) - } - return b[:], nil -} - -// Signature T_SIG -type Signature string diff --git a/cmd/iconbridge/chain/bsc/types/types.go b/cmd/iconbridge/chain/bsc/types/types.go index daa2c197b..4feb3cddb 100644 --- a/cmd/iconbridge/chain/bsc/types/types.go +++ b/cmd/iconbridge/chain/bsc/types/types.go @@ -1,5 +1,11 @@ package types +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "math/big" +) + type Block struct { Transactions []string `json:"transactions"` GasUsed string `json:"gasUsed"` @@ -9,3 +15,11 @@ type Wallet interface { Sign(data []byte) ([]byte, error) Address() string } + +type BlockNotification struct { + Hash common.Hash + Height *big.Int + Header *types.Header + Receipts types.Receipts + HasBTPMessage *bool +} \ No newline at end of file diff --git a/cmd/iconbridge/chain/icon/client.go b/cmd/iconbridge/chain/icon/client.go index 924b1e997..cec67f795 100644 --- a/cmd/iconbridge/chain/icon/client.go +++ b/cmd/iconbridge/chain/icon/client.go @@ -150,62 +150,6 @@ func (c *Client) Call(p *types.CallParam, r interface{}) error { return err } -func (c *Client) SendTransactionAndGetResult(p *types.TransactionParam) (*types.HexBytes, *types.TransactionResult, error) { - thp := &types.TransactionHashParam{} -txLoop: - for { - txh, err := c.SendTransaction(p) - if err != nil { - switch err { - case ErrSendFailByOverflow: - //TODO Retry max - time.Sleep(DefaultSendTransactionRetryInterval) - c.log.Debugf("Retry SendTransaction") - continue txLoop - default: - switch re := err.(type) { - case *jsonrpc.Error: - switch re.Code { - case types.JsonrpcErrorCodeSystem: - if subEc, err := strconv.ParseInt(re.Message[1:5], 0, 32); err == nil { - switch subEc { - case 2000: //DuplicateTransactionError - //Ignore - c.log.Debugf("DuplicateTransactionError txh:%v", txh) - thp.Hash = *txh - break txLoop - } - } - } - } - } - c.log.Debugf("fail to SendTransaction hash:%v, err:%+v", txh, err) - return &thp.Hash, nil, err - } - thp.Hash = *txh - break txLoop - } - -txrLoop: - for { - time.Sleep(DefaultGetTransactionResultPollingInterval) - txr, err := c.GetTransactionResult(thp) - if err != nil { - switch re := err.(type) { - case *jsonrpc.Error: - switch re.Code { - case types.JsonrpcErrorCodePending, types.JsonrpcErrorCodeExecuting: - //TODO Retry max - c.log.Debugln("Retry GetTransactionResult", thp) - continue txrLoop - } - } - } - c.log.Debugf("GetTransactionResult hash:%v, txr:%+v, err:%+v", thp.Hash, txr, err) - return &thp.Hash, txr, err - } -} - func (c *Client) WaitForResults(ctx context.Context, thp *types.TransactionHashParam) (txh *types.HexBytes, txr *types.TransactionResult, err error) { ticker := time.NewTicker(time.Duration(DefaultGetTransactionResultPollingInterval) * time.Nanosecond) retryLimit := 10 diff --git a/cmd/iconbridge/chain/substrate-eth/bmc_abigen.go b/cmd/iconbridge/chain/substrate-eth/abi/bmc_abigen.go similarity index 99% rename from cmd/iconbridge/chain/substrate-eth/bmc_abigen.go rename to cmd/iconbridge/chain/substrate-eth/abi/bmc_abigen.go index 7acb0d1a8..edf6b9c0f 100644 --- a/cmd/iconbridge/chain/substrate-eth/bmc_abigen.go +++ b/cmd/iconbridge/chain/substrate-eth/abi/bmc_abigen.go @@ -1,7 +1,7 @@ // Code generated - DO NOT EDIT. // This file is a generated binding and any manual changes will be lost. -package substrate_eth +package abi import ( "math/big" diff --git a/cmd/iconbridge/chain/substrate-eth/client.go b/cmd/iconbridge/chain/substrate-eth/client.go index 17254295b..b57d9553f 100644 --- a/cmd/iconbridge/chain/substrate-eth/client.go +++ b/cmd/iconbridge/chain/substrate-eth/client.go @@ -3,6 +3,7 @@ package substrate_eth import ( "context" "fmt" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/substrate-eth/abi" "math" "math/big" @@ -19,7 +20,7 @@ import ( "github.com/icon-project/icon-bridge/common/log" ) -func newClients(urls []string, bmc string, l log.Logger) (cls []IClient, bmcs []*BMC, err error) { +func newClients(urls []string, bmc string, l log.Logger) (cls []IClient, bmcs []*abi.BMC, err error) { for _, url := range urls { clrpc, err := rpc.Dial(url) if err != nil { @@ -27,7 +28,7 @@ func newClients(urls []string, bmc string, l log.Logger) (cls []IClient, bmcs [] return nil, nil, err } cleth := ethclient.NewClient(clrpc) - clbmc, err := NewBMC(common.HexToAddress(bmc), cleth) + clbmc, err := abi.NewBMC(common.HexToAddress(bmc), cleth) if err != nil { l.Errorf("failed to create bmc binding to snow ethclient: url=%v, %v", url, err) return nil, nil, err diff --git a/cmd/iconbridge/chain/substrate-eth/receiver.go b/cmd/iconbridge/chain/substrate-eth/receiver.go index b07918c93..11c726644 100644 --- a/cmd/iconbridge/chain/substrate-eth/receiver.go +++ b/cmd/iconbridge/chain/substrate-eth/receiver.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/substrate-eth/abi" "math/big" "math/rand" "sort" @@ -13,12 +14,13 @@ import ( subEthTypes "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/substrate-eth/types" - ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" ethCommon "github.com/ethereum/go-ethereum/common" ethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/trie" "github.com/icon-project/icon-bridge/cmd/iconbridge/chain" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/substrate-eth/types" "github.com/icon-project/icon-bridge/common/log" "github.com/pkg/errors" ) @@ -78,7 +80,7 @@ type receiver struct { dst chain.BTPAddress opts ReceiverOptions cls []IClient - bmcs []*BMC + bmcs []*abi.BMC } func (r *receiver) client() IClient { @@ -86,7 +88,7 @@ func (r *receiver) client() IClient { return r.cls[randInt] } -func (r *receiver) bmcClient() *BMC { +func (r *receiver) bmcClient() *abi.BMC { randInt := rand.Intn(len(r.cls)) return r.bmcs[randInt] } @@ -217,7 +219,7 @@ func (r *receiver) syncVerifier(vr *Verifier, height int64) error { return nil } -func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *BlockNotification) error) (err error) { +func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback func(v *types.BlockNotification) error) (err error) { if opts == nil { return errors.New("receiveLoop: invalid options: ") @@ -238,7 +240,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu // block notification channel // (buffered: to avoid deadlock) // increase concurrency parameter for faster sync - bnch := make(chan *BlockNotification, r.opts.SyncConcurrency) + bnch := make(chan *types.BlockNotification, r.opts.SyncConcurrency) heightTicker := time.NewTicker(BlockInterval) defer heightTicker.Stop() @@ -257,7 +259,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu next, latest := opts.StartHeight, latestHeight() // last unverified block notification - var lbn *BlockNotification + var lbn *types.BlockNotification // start monitor loop for { select { @@ -317,7 +319,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu type bnq struct { h uint64 - v *BlockNotification + v *types.BlockNotification err error retry int } @@ -331,7 +333,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu r.log.Error("Fatal: Zero length of query channel. Avoiding deadlock") continue } - bns := make([]*BlockNotification, 0, len(qch)) + bns := make([]*types.BlockNotification, 0, len(qch)) for q := range qch { switch { case q.err != nil: @@ -360,7 +362,7 @@ func (r *receiver) receiveLoop(ctx context.Context, opts *BnOptions, callback fu }() if q.v == nil { - q.v = &BlockNotification{} + q.v = &types.BlockNotification{} } q.v.Height = (&big.Int{}).SetUint64(q.h) @@ -461,7 +463,7 @@ func (r *receiver) Subscribe( StartHeight: opts.Height, Concurrency: r.opts.SyncConcurrency, }, - func(v *BlockNotification) error { + func(v *types.BlockNotification) error { r.log.WithFields(log.Fields{"height": v.Height}).Debug("block notification") if v.Height.Uint64() != lastHeight+1 { @@ -502,7 +504,7 @@ func (r *receiver) Subscribe( return _errCh, nil } -func (r *receiver) getRelayReceipts(v *BlockNotification) []*chain.Receipt { +func (r *receiver) getRelayReceipts(v *types.BlockNotification) []*chain.Receipt { sc := common.HexToAddress(r.src.ContractAddress()) var receipts []*chain.Receipt var events []*chain.Event diff --git a/cmd/iconbridge/chain/substrate-eth/sender.go b/cmd/iconbridge/chain/substrate-eth/sender.go index 81508ed34..1f3f396fe 100644 --- a/cmd/iconbridge/chain/substrate-eth/sender.go +++ b/cmd/iconbridge/chain/substrate-eth/sender.go @@ -21,6 +21,7 @@ import ( "encoding/binary" "encoding/json" "fmt" + "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/substrate-eth/abi" "math/big" "math/rand" "time" @@ -61,11 +62,11 @@ type sender struct { dst chain.BTPAddress opts senderOptions cls []IClient - bmcs []*BMC + bmcs []*abi.BMC prevGasPrice *big.Int } -func (s *sender) jointClient() (IClient, *BMC) { +func (s *sender) jointClient() (IClient, *abi.BMC) { randInt := rand.Intn(len(s.cls)) return s.cls[randInt], s.bmcs[randInt] } @@ -243,7 +244,7 @@ type relayTx struct { opts *bind.TransactOpts pendingTx *ethtypes.Transaction cl IClient - bmcCl *BMC + bmcCl *abi.BMC } func (tx *relayTx) ID() interface{} { diff --git a/cmd/iconbridge/chain/substrate-eth/type.go b/cmd/iconbridge/chain/substrate-eth/type.go deleted file mode 100644 index a67409f27..000000000 --- a/cmd/iconbridge/chain/substrate-eth/type.go +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2021 ICON Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package substrate_eth - -import ( - "encoding/hex" - "fmt" - subEthTypes "github.com/icon-project/icon-bridge/cmd/iconbridge/chain/substrate-eth/types" - "math/big" - "strconv" - "strings" - - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - -type EventLog struct { - Addr []byte - Indexed [][]byte - Data [][]byte -} - -type TransactionResult struct { - To Address `json:"to"` - CumulativeStepUsed HexInt `json:"cumulativeStepUsed"` - StepUsed HexInt `json:"stepUsed"` - StepPrice HexInt `json:"stepPrice"` - EventLogs []struct { - Addr Address `json:"scoreAddress"` - Indexed []string `json:"indexed"` - Data []string `json:"data"` - } `json:"eventLogs"` - LogsBloom HexBytes `json:"logsBloom"` - Status HexInt `json:"status"` - Failure *struct { - CodeValue HexInt `json:"code"` - MessageValue string `json:"message"` - } `json:"failure,omitempty"` - SCOREAddress Address `json:"scoreAddress,omitempty"` - BlockHash HexBytes `json:"blockHash" validate:"required,t_hash"` - BlockHeight HexInt `json:"blockHeight" validate:"required,t_int"` - TxIndex HexInt `json:"txIndex" validate:"required,t_int"` - TxHash HexBytes `json:"txHash" validate:"required,t_int"` -} - -type TransactionParam struct { - FromAddress string `json:"from" validate:"required,t_addr_eoa"` - ToAddress string `json:"to" validate:"required,t_addr"` - NetworkID HexInt `json:"nid" validate:"required,t_int"` - Params interface{} `json:"params,omitempty"` - TransactOpt *bind.TransactOpts -} - -type BMCRelayMethodParams struct { - Prev string `json:"_prev"` - Messages string `json:"_msg"` -} - -type BMCStatus struct { - TxSeq HexInt `json:"tx_seq"` - RxSeq HexInt `json:"rx_seq"` - BMRIndex HexInt `json:"relay_idx"` - RotateHeight HexInt `json:"rotate_height"` - RotateTerm HexInt `json:"rotate_term"` - DelayLimit HexInt `json:"delay_limit"` - MaxAggregation HexInt `json:"max_agg"` - CurrentHeight HexInt `json:"cur_height"` - RxHeight HexInt `json:"rx_height"` - RxHeightSrc HexInt `json:"rx_height_src"` - BlockIntervalSrc HexInt `json:"block_interval_src"` - BlockIntervalDst HexInt `json:"block_interval_dst"` -} - -type TransactionHashParam struct { - Hash common.Hash -} - -type BlockRequest struct { - Height *big.Int `json:"height"` - EventFilters []*EventFilter `json:"eventFilters,omitempty"` - SrcContractAddress common.Address `json:"srcContractAddress,omitempty"` -} - -type EventFilter struct { - Addr Address `json:"addr,omitempty"` - Signature string `json:"event"` - Indexed []*string `json:"indexed,omitempty"` - Data []*string `json:"data,omitempty"` -} - -type BlockNotification struct { - Hash common.Hash - Height *big.Int - Header *subEthTypes.Header - Receipts types.Receipts - HasBTPMessage *bool -} - -type RelayMessage struct { - ReceiptProofs [][]byte - // - height int64 - eventSequence int64 - numberOfEvent int -} - -type ReceiptProof struct { - Index int - Events []byte - Height int64 -} - -type EVMLog struct { - Address string - Topics [][]byte - Data []byte - BlockNumber uint64 - TxHash []byte - TxIndex uint - BlockHash []byte - Index uint - Removed bool -} - -func MakeLog(log *types.Log) *EVMLog { - topics := make([][]byte, 0) - - for _, topic := range log.Topics { - topics = append(topics, topic.Bytes()) - } - - return &EVMLog{ - Address: log.Address.String(), - Topics: topics, - Data: log.Data, - BlockNumber: log.BlockNumber, - TxHash: log.TxHash.Bytes(), - TxIndex: log.TxIndex, - BlockHash: log.BlockHash.Bytes(), - Index: log.Index, - Removed: log.Removed, - } -} - -type Receipt struct { - // Consensus fields: These fields are defined by the Yellow Paper - Type uint8 - PostState []byte - Status uint64 - CumulativeGasUsed uint64 - Bloom []byte - Logs []*EVMLog - - TxHash common.Hash - ContractAddress common.Address - GasUsed uint64 - - BlockHash common.Hash - BlockNumber uint64 - TransactionIndex uint -} - -func MakeReceipt(receipt *types.Receipt) *Receipt { - logs := make([]*EVMLog, len(receipt.Logs)) - - for _, log := range receipt.Logs { - logs = append(logs, MakeLog(log)) - } - - return &Receipt{ - Type: receipt.Type, - PostState: receipt.PostState, - Status: receipt.Status, - CumulativeGasUsed: receipt.CumulativeGasUsed, - Bloom: receipt.Bloom.Bytes(), - Logs: logs, - TxHash: receipt.TxHash, - ContractAddress: receipt.ContractAddress, - GasUsed: receipt.GasUsed, - BlockHash: receipt.BlockHash, - BlockNumber: receipt.BlockNumber.Uint64(), - TransactionIndex: receipt.TransactionIndex, - } -} - -func HexToAddress(s string) common.Address { - return common.HexToAddress(s) -} - -// HexBytes T_BIN_DATA, T_HASH -type HexBytes string - -func (hs HexBytes) Value() ([]byte, error) { - if hs == "" { - return nil, nil - } - return hex.DecodeString(string(hs[2:])) -} - -// HexInt T_INT -type HexInt string - -func (i HexInt) Value() (int64, error) { - s := string(i) - if strings.HasPrefix(s, "0x") { - s = s[2:] - } - return strconv.ParseInt(s, 16, 64) -} - -func (i HexInt) Int() (int, error) { - s := string(i) - if strings.HasPrefix(s, "0x") { - s = s[2:] - } - v, err := strconv.ParseInt(s, 16, 32) - return int(v), err -} - -// Address T_ADDR_EOA, T_ADDR_SCORE -type Address string - -func (a Address) Value() ([]byte, error) { - var b [21]byte - switch a[:2] { - case "cx": - b[0] = 1 - case "hx": - default: - return nil, fmt.Errorf("invalid prefix %s", a[:2]) - } - n, err := hex.Decode(b[1:], []byte(a[2:])) - if err != nil { - return nil, err - } - if n != 20 { - return nil, fmt.Errorf("invalid length %d", n) - } - return b[:], nil -} - -// Signature T_SIG -type Signature string diff --git a/cmd/iconbridge/chain/substrate-eth/types/types.go b/cmd/iconbridge/chain/substrate-eth/types/types.go index 90e6d9733..95cab18df 100644 --- a/cmd/iconbridge/chain/substrate-eth/types/types.go +++ b/cmd/iconbridge/chain/substrate-eth/types/types.go @@ -1,6 +1,25 @@ package types +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "math/big" +) + +type Block struct { + Transactions []string `json:"transactions"` + GasUsed string `json:"gasUsed"` +} + type Wallet interface { Sign(data []byte) ([]byte, error) Address() string } + +type BlockNotification struct { + Hash common.Hash + Height *big.Int + Header *Header + Receipts types.Receipts + HasBTPMessage *bool +} \ No newline at end of file