github.com/elastos/Elastos.ELA.SideChain.ETH@v0.2.2/chainbridge-core/chains/evm/chain.go (about)

     1  // Copyright 2021 ChainSafe Systems
     2  // SPDX-License-Identifier: LGPL-3.0-only
     3  
     4  package evm
     5  
     6  import (
     7  	"bytes"
     8  	"errors"
     9  	"fmt"
    10  	"math/big"
    11  
    12  	"github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/blockstore"
    13  	"github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/bridgelog"
    14  	"github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/chains/evm/aribiters"
    15  	"github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/chains/evm/voter"
    16  	"github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/config"
    17  	"github.com/elastos/Elastos.ELA.SideChain.ESC/chainbridge-core/relayer"
    18  	"github.com/elastos/Elastos.ELA.SideChain.ESC/common"
    19  	"github.com/elastos/Elastos.ELA.SideChain.ESC/crypto"
    20  	"github.com/elastos/Elastos.ELA.SideChain.ESC/log"
    21  )
    22  
    23  type EventListener interface {
    24  	ListenToEvents(startBlock *big.Int, chainID uint64, kvrw blockstore.KeyValueWriter, errChn chan<- error) <-chan *relayer.SetArbiterListMsg
    25  }
    26  
    27  type ProposalVoter interface {
    28  	GetClient() voter.ChainClient
    29  	GetPublicKey() ([]byte, error)
    30  	GetSignerAddress() (common.Address, error)
    31  	SetArbiterList(arbiters []common.Address, totalCount int, signature [][]byte, bridgeAddress string) error
    32  	GetArbiterList(bridgeAddress string) ([]common.Address, error)
    33  	GetSignatures(bridgeAddress string) ([][crypto.SignatureLength]byte, error)
    34  	GetTotalCount(bridgeAddress string) (uint64, error)
    35  	GetESCState(bridgeAddress string) (uint8, error)
    36  	GetHashSalt(bridgeAddress string) (*big.Int, error)
    37  	IsDeployedBridgeContract(bridgeAddress string) bool
    38  	SetESCState(bridgeAddress string, state uint8) error
    39  	SetManualArbiter(bridgeAddress string, arbiter []common.Address, totalSigner int) error
    40  }
    41  
    42  // EVMChain is struct that aggregates all data required for
    43  type EVMChain struct {
    44  	listener              EventListener // Rename
    45  	writer                ProposalVoter
    46  	chainID               uint64
    47  	kvdb                  blockstore.KeyValueReaderWriter
    48  	bridgeContractAddress string
    49  	config                *config.GeneralChainConfig
    50  	arbiterManager        *aribiters.ArbiterManager
    51  }
    52  
    53  func NewEVMChain(dr EventListener, writer ProposalVoter, chainID uint64, kvdb blockstore.KeyValueReaderWriter,
    54  	config *config.GeneralChainConfig, arbiterManager *aribiters.ArbiterManager) *EVMChain {
    55  	chain := &EVMChain{listener: dr, writer: writer, chainID: chainID, config: config}
    56  	chain.bridgeContractAddress = config.Opts.Bridge
    57  	chain.arbiterManager = arbiterManager
    58  	chain.kvdb = kvdb
    59  
    60  	return chain
    61  }
    62  
    63  func (c *EVMChain) getMaxArbitersSign() int {
    64  	total := c.writer.GetClient().Engine().GetTotalArbitersCount()
    65  	return total*2/3 + 1
    66  }
    67  
    68  func (c *EVMChain) WriteArbiters(arbiters []common.Address, signatures [][]byte, totalCount int) error {
    69  	if c.writer.IsDeployedBridgeContract(c.bridgeContractAddress) == false {
    70  		return errors.New(fmt.Sprintf("%d is not deploy chainbridge contract", c.chainID))
    71  	}
    72  
    73  	isSame := false
    74  	nowArbiters := c.GetArbiters()
    75  	if len(arbiters) == len(nowArbiters) {
    76  		isSame = true
    77  		for i, arbiter := range nowArbiters {
    78  			if !bytes.Equal(arbiter.Bytes(), arbiters[i].Bytes()) {
    79  				isSame = false
    80  				break
    81  			}
    82  		}
    83  	}
    84  	if !isSame {
    85  		return c.writer.SetArbiterList(arbiters, totalCount, signatures, c.bridgeContractAddress)
    86  	}
    87  	return errors.New("is same arbiters on contract")
    88  }
    89  
    90  func (c *EVMChain) GetArbiters() []common.Address {
    91  	list, err := c.writer.GetArbiterList(c.bridgeContractAddress)
    92  	if err != nil {
    93  		log.Error("GetArbiterList error", "error", err)
    94  		return []common.Address{}
    95  	}
    96  	return list
    97  }
    98  
    99  func (c *EVMChain) GetSignatures() ([][crypto.SignatureLength]byte, error) {
   100  	sigs, err := c.writer.GetSignatures(c.bridgeContractAddress)
   101  	if err != nil {
   102  		log.Error("GetSignatures error", "error", err)
   103  		return [][crypto.SignatureLength]byte{}, err
   104  	}
   105  	return sigs, nil
   106  }
   107  func (c *EVMChain) GetTotalCount() (uint64, error) {
   108  	count, err := c.writer.GetTotalCount(c.bridgeContractAddress)
   109  	if err != nil {
   110  		log.Error("GetTotalCount error", "error", err)
   111  		return 0, err
   112  	}
   113  	return count, nil
   114  }
   115  
   116  func (c *EVMChain) GetESCState() (uint8, error) {
   117  	state, err := c.writer.GetESCState(c.bridgeContractAddress)
   118  	if err != nil {
   119  		log.Error("GetTotalCount error", "error", err)
   120  		return 0, err
   121  	}
   122  	return state, nil
   123  }
   124  
   125  func (c *EVMChain) GetHashSalt() (*big.Int, error) {
   126  	return c.writer.GetHashSalt(c.bridgeContractAddress)
   127  }
   128  
   129  func (c *EVMChain) SetESCState(state uint8) error {
   130  	err := c.writer.SetESCState(c.bridgeContractAddress, state)
   131  	if err != nil {
   132  		return err
   133  	}
   134  	return nil
   135  }
   136  
   137  func (c *EVMChain) SetManualArbiters(arbiters []common.Address, totalSigner int) error {
   138  	err := c.writer.SetManualArbiter(c.bridgeContractAddress, arbiters, totalSigner)
   139  	if err != nil {
   140  		log.Error("SetManualArbiters error", "error", err)
   141  		return err
   142  	}
   143  	return nil
   144  }
   145  
   146  func (c *EVMChain) GetBridgeContract() string {
   147  	return c.config.Opts.Bridge
   148  }
   149  
   150  func (c *EVMChain) ChainID() uint64 {
   151  	return c.chainID
   152  }
   153  
   154  // PollEvents is the goroutine that polling blocks and searching Deposit Events in them. Event then sent to eventsChan
   155  func (c *EVMChain) PollEvents(sysErr chan<- error, stop <-chan struct{}, eventsChan chan *relayer.SetArbiterListMsg) {
   156  	log.Info("Polling Blocks...", "startBlock", c.config.Opts.StartBlock)
   157  	// Handler chain specific configs and flags
   158  	block, err := blockstore.SetupBlockstore(c.config, c.kvdb, big.NewInt(0).SetUint64(c.config.Opts.StartBlock))
   159  	if err != nil {
   160  		sysErr <- fmt.Errorf("error %w on getting last stored block", err)
   161  		return
   162  	}
   163  	ech := c.listener.ListenToEvents(block, c.chainID, c.kvdb, sysErr)
   164  	for {
   165  		select {
   166  		case newEvent := <-ech:
   167  			// Here we can place middlewares for custom logic?
   168  			eventsChan <- newEvent
   169  			continue
   170  		case <-stop:
   171  			bridgelog.Info("PollEvents stopped")
   172  			return
   173  		}
   174  	}
   175  }