Commit 6363dce5 authored by vicotor's avatar vicotor

update code

parent 031f7acd
This diff is collapsed.
......@@ -21,3 +21,24 @@ const (
ValidatorStatusRejection = 2
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
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 {
Event *BridgeContractTransferIn // Event containing the contract specifics and raw log
......@@ -2393,7 +2393,7 @@ func (_BridgeContract *BridgeContractFilterer) ParseTransferInRejection(log type
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 {
Event *BridgeContractTransferOut // Event containing the contract specifics and raw log
......
This diff is collapsed.
......@@ -14,18 +14,24 @@ import (
"gorm.io/gorm/schema"
)
type ChainInfo struct {
conf *config.ChainConfig
cli *ethclient.Client
}
type Dao struct {
c *config.Config
db *gorm.DB
ethClient map[int64]*ethclient.Client
chainGroup map[int64]ChainInfo
quit chan struct{}
wg sync.WaitGroup
handleMux sync.Mutex
}
func New(_c *config.Config) (dao *Dao, err error) {
dao = &Dao{
c: _c,
ethClient: make(map[int64]*ethclient.Client),
chainGroup: make(map[int64]ChainInfo),
quit: make(chan struct{}),
}
......@@ -45,7 +51,10 @@ func New(_c *config.Config) (dao *Dao, err error) {
// Update the chain ID in the config
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)
}
......@@ -90,16 +99,16 @@ func (d *Dao) Stop() {
close(d.quit)
d.wg.Wait()
for _, client := range d.ethClient {
if client != nil {
client.Close()
for _, chain := range d.chainGroup {
if chain.cli != nil {
chain.cli.Close()
}
}
if d.db != nil {
sqlDB, _ := d.db.DB()
sqlDB.Close()
}
d.ethClient = nil
d.chainGroup = nil
d.db = nil
d.c = nil
}
......@@ -58,6 +58,19 @@ func (d *Dao) GetBridgeEventWithInInfoTx(tx *Transaction, chain int64, inId int6
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 {
return tx.tx.Model(event).Where("`id` = ?", event.ID).Updates(map[string]interface{}{
"to_contract": event.ToContract,
......@@ -81,8 +94,9 @@ func (d *Dao) UpdateBridgeResultTx(tx *Transaction, event *dbModel.BridgeEvent,
}).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{
Contract: contract,
ChainId: chain,
Validator: validator,
TxHash: txHash,
......
......@@ -8,6 +8,7 @@ import (
"context"
"errors"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/ethclient"
"golang.org/x/crypto/sha3"
"math/big"
"time"
......@@ -23,10 +24,14 @@ import (
func (d *Dao) GetBlockHeight(chain *config.ChainConfig, behindBlock ...int) (height int64, err error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if _, ok := d.ethClient[chain.ChainId]; !ok {
if _, ok := d.chainGroup[chain.ChainId]; !ok {
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 {
n -= uint64(behindBlock[0])
if n < 0 {
......@@ -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) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if _, ok := d.ethClient[chain.ChainId]; !ok {
chainInfo, ok := d.chainGroup[chain.ChainId]
if !ok {
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 {
return
}
......@@ -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) {
if _, ok := d.ethClient[chain.ChainId]; !ok {
chainInfo, ok := d.chainGroup[chain.ChainId]
if !ok {
return 0, errors.New("chain client not support")
}
for i := 0; i < 2; i++ {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
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 {
return int(block.Time()), nil
}
......@@ -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) {
if _, ok := d.ethClient[chain.ChainId]; !ok {
chainInfo, ok := d.chainGroup[chain.ChainId]
if !ok {
return nil, errors.New("chain client not support")
}
for i := 0; i < 2; i++ {
// 重试2次
logs, err = d.getLogs(chain, beginHeight, endHeight, topics, addresses)
logs, err = d.getLogs(chainInfo.cli, beginHeight, endHeight, topics, addresses)
if err == nil {
return logs, nil
}
......@@ -79,7 +87,7 @@ func (d *Dao) GetLogs(chain *config.ChainConfig, beginHeight, endHeight int64, t
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)
for _, addr := range addresses {
addrs = append(addrs, common.HexToAddress(addr))
......@@ -97,7 +105,7 @@ func (d *Dao) getLogs(chain *config.ChainConfig, beginHeight, endHeight int64, t
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
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) {
......@@ -144,59 +152,49 @@ func (d *Dao) buildParam(event *dbModel.BridgeEvent) (bridge.BridgesubmitParams,
}
func (d *Dao) SubmitInTransfer(event *dbModel.BridgeEvent) error {
if _, ok := d.ethClient[event.ToChain]; !ok {
return errors.New("chain client 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")
chain, ok := d.chainGroup[event.ToChain]
if !ok {
return errors.New("chain not support")
}
// verify the event is valid.
valid := d.CheckEventValid()
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")
}
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 {
return err
}
k := chain.ValidatorPrivateKey
k := chain.conf.ValidatorPrivateKey
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
}
signPrivateKey, err := crypto.HexToECDSA(common.Bytes2Hex(common.FromHex(k)))
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
}
opts, err := bind.NewKeyedTransactorWithChainID(signPrivateKey, big.NewInt(int64(chain.ChainId)))
opts, err := bind.NewKeyedTransactorWithChainID(signPrivateKey, big.NewInt(int64(chain.conf.ChainId)))
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
}
param, err := d.buildParam(event)
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
}
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
} else {
// 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)
}
}
......
......@@ -36,6 +36,7 @@ type BridgeEvent struct {
type ValidatorEvent struct {
ChainId int64 `gorm:"type:int;comment:链ID"`
Contract string `gorm:"type:varchar(255);comment:合约地址"` // 合约地址
Validator string `gorm:"type:varchar(255);index;comment:验证者地址"` // 验证者地址
TxHash string `gorm:"type:varchar(255);index;comment:交易hash"` // 交易hash
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