Commit 6363dce5 authored by vicotor's avatar vicotor

update code

parent 031f7acd
This diff is collapsed.
...@@ -21,3 +21,24 @@ const ( ...@@ -21,3 +21,24 @@ const (
ValidatorStatusRejection = 2 ValidatorStatusRejection = 2
ValidatorStatusFailure = 3 ValidatorStatusFailure = 3
) )
const (
EVENT_TRANSFER_OUT = "TransferOut"
EVENT_TRANSFER_IN = "TransferIn"
EVENT_TRANSFER_IN_CONFIRMATION = "TransferInConfirmation"
EVENT_TRANSFER_IN_REJECTION = "TransferInRejection"
EVENT_TRANSFER_IN_EXECUTION = "TransferInExecution"
)
type ValidatorOp int
func (op ValidatorOp) String() string {
switch op {
case ValidatorStatusConfirmation:
return "TransferInConfirmation"
case ValidatorStatusRejection:
return "TransferInRejection"
default:
return "Unknown"
}
}
...@@ -1847,7 +1847,7 @@ func (_BridgeContract *BridgeContractFilterer) ParseTokenConfigChanged(log types ...@@ -1847,7 +1847,7 @@ func (_BridgeContract *BridgeContractFilterer) ParseTokenConfigChanged(log types
return event, nil return event, nil
} }
// BridgeContractTransferInIterator is returned from FilterTransferIn and is used to iterate over the raw logs and unpacked data for TransferIn events raised by the BridgeContract contract. // BridgeContractTransferInIterator is returned from filterTransferIn and is used to iterate over the raw logs and unpacked data for TransferIn events raised by the BridgeContract contract.
type BridgeContractTransferInIterator struct { type BridgeContractTransferInIterator struct {
Event *BridgeContractTransferIn // Event containing the contract specifics and raw log Event *BridgeContractTransferIn // Event containing the contract specifics and raw log
...@@ -2393,7 +2393,7 @@ func (_BridgeContract *BridgeContractFilterer) ParseTransferInRejection(log type ...@@ -2393,7 +2393,7 @@ func (_BridgeContract *BridgeContractFilterer) ParseTransferInRejection(log type
return event, nil return event, nil
} }
// BridgeContractTransferOutIterator is returned from FilterTransferOut and is used to iterate over the raw logs and unpacked data for TransferOut events raised by the BridgeContract contract. // BridgeContractTransferOutIterator is returned from filterTransferOut and is used to iterate over the raw logs and unpacked data for TransferOut events raised by the BridgeContract contract.
type BridgeContractTransferOutIterator struct { type BridgeContractTransferOutIterator struct {
Event *BridgeContractTransferOut // Event containing the contract specifics and raw log Event *BridgeContractTransferOut // Event containing the contract specifics and raw log
......
This diff is collapsed.
...@@ -14,19 +14,25 @@ import ( ...@@ -14,19 +14,25 @@ import (
"gorm.io/gorm/schema" "gorm.io/gorm/schema"
) )
type ChainInfo struct {
conf *config.ChainConfig
cli *ethclient.Client
}
type Dao struct { type Dao struct {
c *config.Config c *config.Config
db *gorm.DB db *gorm.DB
ethClient map[int64]*ethclient.Client chainGroup map[int64]ChainInfo
quit chan struct{} quit chan struct{}
wg sync.WaitGroup wg sync.WaitGroup
handleMux sync.Mutex
} }
func New(_c *config.Config) (dao *Dao, err error) { func New(_c *config.Config) (dao *Dao, err error) {
dao = &Dao{ dao = &Dao{
c: _c, c: _c,
ethClient: make(map[int64]*ethclient.Client), chainGroup: make(map[int64]ChainInfo),
quit: make(chan struct{}), quit: make(chan struct{}),
} }
// Connect to all configured chains // Connect to all configured chains
...@@ -45,7 +51,10 @@ func New(_c *config.Config) (dao *Dao, err error) { ...@@ -45,7 +51,10 @@ func New(_c *config.Config) (dao *Dao, err error) {
// Update the chain ID in the config // Update the chain ID in the config
chainConfig.ChainId = chainId.Int64() chainConfig.ChainId = chainId.Int64()
dao.ethClient[chainId.Int64()] = client dao.chainGroup[chainId.Int64()] = ChainInfo{
conf: chainConfig,
cli: client,
}
fmt.Printf("Connected to %s chain with ID %d\n", name, chainConfig.ChainId) fmt.Printf("Connected to %s chain with ID %d\n", name, chainConfig.ChainId)
} }
...@@ -90,16 +99,16 @@ func (d *Dao) Stop() { ...@@ -90,16 +99,16 @@ func (d *Dao) Stop() {
close(d.quit) close(d.quit)
d.wg.Wait() d.wg.Wait()
for _, client := range d.ethClient { for _, chain := range d.chainGroup {
if client != nil { if chain.cli != nil {
client.Close() chain.cli.Close()
} }
} }
if d.db != nil { if d.db != nil {
sqlDB, _ := d.db.DB() sqlDB, _ := d.db.DB()
sqlDB.Close() sqlDB.Close()
} }
d.ethClient = nil d.chainGroup = nil
d.db = nil d.db = nil
d.c = nil d.c = nil
} }
...@@ -58,6 +58,19 @@ func (d *Dao) GetBridgeEventWithInInfoTx(tx *Transaction, chain int64, inId int6 ...@@ -58,6 +58,19 @@ func (d *Dao) GetBridgeEventWithInInfoTx(tx *Transaction, chain int64, inId int6
return event, err return event, err
} }
func (d *Dao) UpdateFullBridgeTx(tx *Transaction, event *dbModel.BridgeEvent) error {
return tx.tx.Model(event).Where("`id` = ?", event.ID).Updates(event).Error
}
func (d *Dao) GetBridgeEventByHashTx(tx *Transaction, hash string) (event *dbModel.BridgeEvent, err error) {
event = new(dbModel.BridgeEvent)
err = tx.tx.Model(event).Where("`hash` = ?", hash).First(event).Error
if err == gorm.ErrRecordNotFound {
return nil, ErrRecordNotFound
}
return event, err
}
func (d *Dao) UpdateBridgeWithTransferInTx(tx *Transaction, event *dbModel.BridgeEvent) error { func (d *Dao) UpdateBridgeWithTransferInTx(tx *Transaction, event *dbModel.BridgeEvent) error {
return tx.tx.Model(event).Where("`id` = ?", event.ID).Updates(map[string]interface{}{ return tx.tx.Model(event).Where("`id` = ?", event.ID).Updates(map[string]interface{}{
"to_contract": event.ToContract, "to_contract": event.ToContract,
...@@ -81,8 +94,9 @@ func (d *Dao) UpdateBridgeResultTx(tx *Transaction, event *dbModel.BridgeEvent, ...@@ -81,8 +94,9 @@ func (d *Dao) UpdateBridgeResultTx(tx *Transaction, event *dbModel.BridgeEvent,
}).Error }).Error
} }
func (d *Dao) CreateValidatorEventTx(tx *Transaction, hash string, chain int64, validator string, txHash string, eventType string, transferInId int64) error { func (d *Dao) CreateValidatorEventTx(tx *Transaction, contract string, hash string, chain int64, validator string, txHash string, eventType string, transferInId int64) error {
event := &dbModel.ValidatorEvent{ event := &dbModel.ValidatorEvent{
Contract: contract,
ChainId: chain, ChainId: chain,
Validator: validator, Validator: validator,
TxHash: txHash, TxHash: txHash,
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"context" "context"
"errors" "errors"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/ethclient"
"golang.org/x/crypto/sha3" "golang.org/x/crypto/sha3"
"math/big" "math/big"
"time" "time"
...@@ -23,10 +24,14 @@ import ( ...@@ -23,10 +24,14 @@ import (
func (d *Dao) GetBlockHeight(chain *config.ChainConfig, behindBlock ...int) (height int64, err error) { func (d *Dao) GetBlockHeight(chain *config.ChainConfig, behindBlock ...int) (height int64, err error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() defer cancel()
if _, ok := d.ethClient[chain.ChainId]; !ok { if _, ok := d.chainGroup[chain.ChainId]; !ok {
return 0, errors.New("chain client not support") return 0, errors.New("chain client not support")
} }
n, err := d.ethClient[chain.ChainId].BlockNumber(ctx) chaininfo, ok := d.chainGroup[chain.ChainId]
if !ok {
return 0, errors.New("chain client not support")
}
n, err := chaininfo.cli.BlockNumber(ctx)
if len(behindBlock) > 0 { if len(behindBlock) > 0 {
n -= uint64(behindBlock[0]) n -= uint64(behindBlock[0])
if n < 0 { if n < 0 {
...@@ -39,10 +44,11 @@ func (d *Dao) GetBlockHeight(chain *config.ChainConfig, behindBlock ...int) (hei ...@@ -39,10 +44,11 @@ func (d *Dao) GetBlockHeight(chain *config.ChainConfig, behindBlock ...int) (hei
func (d *Dao) GetLatestBockHash(chain *config.ChainConfig) (hash string, err error) { func (d *Dao) GetLatestBockHash(chain *config.ChainConfig) (hash string, err error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() defer cancel()
if _, ok := d.ethClient[chain.ChainId]; !ok { chainInfo, ok := d.chainGroup[chain.ChainId]
if !ok {
return "", errors.New("chain client not support") return "", errors.New("chain client not support")
} }
block, err := d.ethClient[chain.ChainId].BlockByNumber(ctx, nil) block, err := chainInfo.cli.BlockByNumber(ctx, nil)
if err != nil { if err != nil {
return return
} }
...@@ -50,14 +56,15 @@ func (d *Dao) GetLatestBockHash(chain *config.ChainConfig) (hash string, err err ...@@ -50,14 +56,15 @@ func (d *Dao) GetLatestBockHash(chain *config.ChainConfig) (hash string, err err
} }
func (d *Dao) GetBlockTime(chain *config.ChainConfig, height int) (timestamp int, err error) { func (d *Dao) GetBlockTime(chain *config.ChainConfig, height int) (timestamp int, err error) {
if _, ok := d.ethClient[chain.ChainId]; !ok { chainInfo, ok := d.chainGroup[chain.ChainId]
if !ok {
return 0, errors.New("chain client not support") return 0, errors.New("chain client not support")
} }
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel() defer cancel()
block, err := d.ethClient[chain.ChainId].BlockByNumber(ctx, big.NewInt(int64(height))) block, err := chainInfo.cli.BlockByNumber(ctx, big.NewInt(int64(height)))
if err == nil { if err == nil {
return int(block.Time()), nil return int(block.Time()), nil
} }
...@@ -66,12 +73,13 @@ func (d *Dao) GetBlockTime(chain *config.ChainConfig, height int) (timestamp int ...@@ -66,12 +73,13 @@ func (d *Dao) GetBlockTime(chain *config.ChainConfig, height int) (timestamp int
} }
func (d *Dao) GetLogs(chain *config.ChainConfig, beginHeight, endHeight int64, topics, addresses []string) (logs []types.Log, err error) { func (d *Dao) GetLogs(chain *config.ChainConfig, beginHeight, endHeight int64, topics, addresses []string) (logs []types.Log, err error) {
if _, ok := d.ethClient[chain.ChainId]; !ok { chainInfo, ok := d.chainGroup[chain.ChainId]
if !ok {
return nil, errors.New("chain client not support") return nil, errors.New("chain client not support")
} }
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
// 重试2次 // 重试2次
logs, err = d.getLogs(chain, beginHeight, endHeight, topics, addresses) logs, err = d.getLogs(chainInfo.cli, beginHeight, endHeight, topics, addresses)
if err == nil { if err == nil {
return logs, nil return logs, nil
} }
...@@ -79,7 +87,7 @@ func (d *Dao) GetLogs(chain *config.ChainConfig, beginHeight, endHeight int64, t ...@@ -79,7 +87,7 @@ func (d *Dao) GetLogs(chain *config.ChainConfig, beginHeight, endHeight int64, t
return return
} }
func (d *Dao) getLogs(chain *config.ChainConfig, beginHeight, endHeight int64, topics []string, addresses []string) (logs []types.Log, err error) { func (d *Dao) getLogs(client *ethclient.Client, beginHeight, endHeight int64, topics []string, addresses []string) (logs []types.Log, err error) {
addrs := make([]common.Address, 0) addrs := make([]common.Address, 0)
for _, addr := range addresses { for _, addr := range addresses {
addrs = append(addrs, common.HexToAddress(addr)) addrs = append(addrs, common.HexToAddress(addr))
...@@ -97,7 +105,7 @@ func (d *Dao) getLogs(chain *config.ChainConfig, beginHeight, endHeight int64, t ...@@ -97,7 +105,7 @@ func (d *Dao) getLogs(chain *config.ChainConfig, beginHeight, endHeight int64, t
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel() defer cancel()
return d.ethClient[chain.ChainId].FilterLogs(ctx, q) return client.FilterLogs(ctx, q)
} }
func (d *Dao) buildParam(event *dbModel.BridgeEvent) (bridge.BridgesubmitParams, error) { func (d *Dao) buildParam(event *dbModel.BridgeEvent) (bridge.BridgesubmitParams, error) {
...@@ -144,59 +152,49 @@ func (d *Dao) buildParam(event *dbModel.BridgeEvent) (bridge.BridgesubmitParams, ...@@ -144,59 +152,49 @@ func (d *Dao) buildParam(event *dbModel.BridgeEvent) (bridge.BridgesubmitParams,
} }
func (d *Dao) SubmitInTransfer(event *dbModel.BridgeEvent) error { func (d *Dao) SubmitInTransfer(event *dbModel.BridgeEvent) error {
chain, ok := d.chainGroup[event.ToChain]
if _, ok := d.ethClient[event.ToChain]; !ok { if !ok {
return errors.New("chain client not support") return errors.New("chain not support")
}
var chain *config.ChainConfig
for _, c := range d.c.Chains {
if c.ChainId == event.ToChain {
chain = c
break
}
}
if chain == nil {
return errors.New("chain not found in config")
} }
// verify the event is valid. // verify the event is valid.
valid := d.CheckEventValid() valid := d.CheckEventValid()
if !valid { if !valid {
log.WithField("chainId", chain.ChainId).Error("event is not valid") log.WithField("chainId", chain.conf.ChainId).Error("event is not valid")
return errors.New("event is not valid") return errors.New("event is not valid")
} }
ca, err := bridge.NewBridgeContract(common.HexToAddress(chain.BridgeContract), d.ethClient[chain.ChainId]) ca, err := bridge.NewBridgeContract(common.HexToAddress(chain.conf.BridgeContract), chain.cli)
if err != nil { if err != nil {
return err return err
} }
k := chain.ValidatorPrivateKey k := chain.conf.ValidatorPrivateKey
if k == "" { if k == "" {
log.WithField("chain", chain.Name).Warn("validator private key is empty, skip submit in transfer") log.WithField("chain", chain.conf.Name).Warn("validator private key is empty, skip submit in transfer")
return nil return nil
} }
signPrivateKey, err := crypto.HexToECDSA(common.Bytes2Hex(common.FromHex(k))) signPrivateKey, err := crypto.HexToECDSA(common.Bytes2Hex(common.FromHex(k)))
if err != nil { if err != nil {
log.WithField("chainId", chain.ChainId).WithError(err).Error("failed to parse private key") log.WithField("chainId", chain.conf.ChainId).WithError(err).Error("failed to parse private key")
return err return err
} }
opts, err := bind.NewKeyedTransactorWithChainID(signPrivateKey, big.NewInt(int64(chain.ChainId))) opts, err := bind.NewKeyedTransactorWithChainID(signPrivateKey, big.NewInt(int64(chain.conf.ChainId)))
if err != nil { if err != nil {
log.WithField("chainId", chain.ChainId).WithError(err).Error("new keyed transfer failed") log.WithField("chainId", chain.conf.ChainId).WithError(err).Error("new keyed transfer failed")
return err return err
} }
param, err := d.buildParam(event) param, err := d.buildParam(event)
if err != nil { if err != nil {
log.WithField("chainId", chain.ChainId).WithError(err).Error("build param failed") log.WithField("chainId", chain.conf.ChainId).WithError(err).Error("build param failed")
return err return err
} }
if tx, err := ca.SubmitInTransfer(opts, param); err != nil { if tx, err := ca.SubmitInTransfer(opts, param); err != nil {
log.WithField("chainId", chain.ChainId).WithError(err).Error("failed to submit in transfer") log.WithField("chainId", chain.conf.ChainId).WithError(err).Error("failed to submit in transfer")
return err return err
} else { } else {
// update validator status. // update validator status.
log.WithField("chainId", chain.ChainId).Infof("submit in transfer tx hash: %s", tx.Hash().Hex()) log.WithField("chainId", chain.conf.ChainId).Infof("submit in transfer tx hash: %s", tx.Hash().Hex())
return d.UpdateBridgeValidatorOperation(event, constant.ValidatorStatusConfirmation) return d.UpdateBridgeValidatorOperation(event, constant.ValidatorStatusConfirmation)
} }
} }
......
...@@ -36,6 +36,7 @@ type BridgeEvent struct { ...@@ -36,6 +36,7 @@ type BridgeEvent struct {
type ValidatorEvent struct { type ValidatorEvent struct {
ChainId int64 `gorm:"type:int;comment:链ID"` ChainId int64 `gorm:"type:int;comment:链ID"`
Contract string `gorm:"type:varchar(255);comment:合约地址"` // 合约地址
Validator string `gorm:"type:varchar(255);index;comment:验证者地址"` // 验证者地址 Validator string `gorm:"type:varchar(255);index;comment:验证者地址"` // 验证者地址
TxHash string `gorm:"type:varchar(255);index;comment:交易hash"` // 交易hash TxHash string `gorm:"type:varchar(255);index;comment:交易hash"` // 交易hash
Event string `gorm:"type:varchar(255);index;comment:事件类型"` // 事件类型 Event string `gorm:"type:varchar(255);index;comment:事件类型"` // 事件类型
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment