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 }