Commit 4efefa6e authored by QM's avatar QM

add ethinterface.go

parent 4ddc2e22
......@@ -36,12 +36,10 @@ func PrepareTestEnv() (bind.ContractBackend, *ethtxs.DeployPara) {
}
alloc[addr] = account
}
gasLimit := uint64(100000000)
sim := backends.NewSimulatedBackend(alloc, gasLimit)
InitPowers := []*big.Int{big.NewInt(80), big.NewInt(10), big.NewInt(10)}
para := &ethtxs.DeployPara{
DeployPrivateKey: genesiskey,
Deployer: genesisAddr,
......@@ -55,12 +53,6 @@ func PrepareTestEnv() (bind.ContractBackend, *ethtxs.DeployPara) {
}
func PrepareTestEnvironment(deployerPrivateKey string, ethValidatorAddrKeys []string) (bind.ContractBackend, *ethtxs.DeployPara) {
//var deployerPrivateKey = "8656d2bc732a8a816a461ba5e2d8aac7c7f85c26a813df30d5327210465eb230"
//var ethValidatorAddrKeyA = "3fa21584ae2e4fd74db9b58e2386f5481607dfa4d7ba0617aaa7858e5025dc1e"
//var ethValidatorAddrKeyB = "a5f3063552f4483cfc20ac4f40f45b798791379862219de9e915c64722c1d400"
//var ethValidatorAddrKeyC = "bbf5e65539e9af0eb0cfac30bad475111054b09c11d668fc0731d54ea777471e"
//var ethValidatorAddrKeyD = "c9fa31d7984edf81b8ef3b40c761f1847f6fcd5711ab2462da97dc458f1f896b"
genesiskey, _ := crypto.HexToECDSA(deployerPrivateKey)
alloc := make(core.GenesisAlloc)
genesisAddr := crypto.PubkeyToAddress(genesiskey.PublicKey)
......@@ -70,12 +62,6 @@ func PrepareTestEnvironment(deployerPrivateKey string, ethValidatorAddrKeys []st
}
alloc[genesisAddr] = genesisAccount
//ethValidatorAddrKey := make([]string, 0)
//ethValidatorAddrKey = append(ethValidatorAddrKey, ethValidatorAddrKeyA)
//ethValidatorAddrKey = append(ethValidatorAddrKey, ethValidatorAddrKeyB)
//ethValidatorAddrKey = append(ethValidatorAddrKey, ethValidatorAddrKeyC)
//ethValidatorAddrKey = append(ethValidatorAddrKey, ethValidatorAddrKeyD)
var InitValidators []common.Address
var ValidatorPriKey []*ecdsa.PrivateKey
for _, v := range ethValidatorAddrKeys {
......
package ethinterface
import (
"context"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)
type EthClientSpec interface {
bind.ContractBackend
TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)
HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
}
type SimExtend struct {
*backends.SimulatedBackend
}
func (sim *SimExtend) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
return sim.Blockchain().CurrentBlock().Header(), nil
}
......@@ -5,15 +5,13 @@ import (
"errors"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethinterface"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/events"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
)
type NewProphecyClaimPara struct {
......@@ -26,9 +24,9 @@ type NewProphecyClaimPara struct {
Txhash []byte
}
func CreateBridgeToken(symbol string, backend bind.ContractBackend, para *OperatorInfo, x2EthDeployInfo *X2EthDeployInfo, x2EthContracts *X2EthContracts) (string, error) {
func CreateBridgeToken(symbol string, client ethinterface.EthClientSpec, para *OperatorInfo, x2EthDeployInfo *X2EthDeployInfo, x2EthContracts *X2EthContracts) (string, error) {
if nil == para {
return "", errors.New("No operator private key configured")
return "", errors.New("no operator private key configured")
}
//订阅事件
eventName := "LogNewBridgeToken"
......@@ -40,7 +38,6 @@ func CreateBridgeToken(symbol string, backend bind.ContractBackend, para *Operat
// We will check logs for new events
logs := make(chan types.Log)
// Filter by contract and event, write results to logs
client := backend.(*ethclient.Client)
sub, err := client.SubscribeFilterLogs(context.Background(), query, logs)
if nil != err {
txslog.Error("CreateBrigeToken", "failed to SubscribeFilterLogs", err.Error())
......@@ -56,7 +53,7 @@ func CreateBridgeToken(symbol string, backend bind.ContractBackend, para *Operat
}()
//创建token
auth, err := PrepareAuth(backend, para.PrivateKey, para.Address)
auth, err := PrepareAuth(client, para.PrivateKey, para.Address)
if nil != err {
return "", err
}
......@@ -97,9 +94,9 @@ func CreateBridgeToken(symbol string, backend bind.ContractBackend, para *Operat
return logEvent.Token.String(), nil
}
func CreateERC20Token(symbol string, backend bind.ContractBackend, para *OperatorInfo, x2EthDeployInfo *X2EthDeployInfo, x2EthContracts *X2EthContracts) (string, error) {
func CreateERC20Token(symbol string, client ethinterface.EthClientSpec, para *OperatorInfo) (string, error) {
if nil == para {
return "", errors.New("No operator private key configured")
return "", errors.New("no operator private key configured")
}
var prepareDone bool
......@@ -111,19 +108,19 @@ func CreateERC20Token(symbol string, backend bind.ContractBackend, para *Operato
}
}()
auth, err := PrepareAuth(backend, para.PrivateKey, para.Address)
auth, err := PrepareAuth(client, para.PrivateKey, para.Address)
if nil != err {
return "", err
}
prepareDone = true
tokenAddr, tx, _, err := generated.DeployBridgeToken(auth, backend, symbol)
tokenAddr, tx, _, err := generated.DeployBridgeToken(auth, client, symbol)
if nil != err {
return "", err
}
err = waitEthTxFinished(backend.(*ethclient.Client), tx.Hash(), "CreateERC20Token")
err = waitEthTxFinished(client, tx.Hash(), "CreateERC20Token")
if nil != err {
return "", err
}
......@@ -131,9 +128,9 @@ func CreateERC20Token(symbol string, backend bind.ContractBackend, para *Operato
return tokenAddr.String(), nil
}
func MintERC20Token(tokenAddr, ownerAddr string, amount *big.Int, backend bind.ContractBackend, para *OperatorInfo) (string, error) {
func MintERC20Token(tokenAddr, ownerAddr string, amount *big.Int, client ethinterface.EthClientSpec, para *OperatorInfo) (string, error) {
if nil == para {
return "", errors.New("No operator private key configured")
return "", errors.New("no operator private key configured")
}
var prepareDone bool
......@@ -145,14 +142,14 @@ func MintERC20Token(tokenAddr, ownerAddr string, amount *big.Int, backend bind.C
}
}()
operatorAuth, err := PrepareAuth(backend, para.PrivateKey, para.Address)
operatorAuth, err := PrepareAuth(client, para.PrivateKey, para.Address)
if nil != err {
return "", err
}
prepareDone = true
erc20TokenInstance, err := generated.NewBridgeToken(common.HexToAddress(tokenAddr), backend)
erc20TokenInstance, err := generated.NewBridgeToken(common.HexToAddress(tokenAddr), client)
if nil != err {
return "", err
}
......@@ -161,7 +158,7 @@ func MintERC20Token(tokenAddr, ownerAddr string, amount *big.Int, backend bind.C
return "", err
}
err = waitEthTxFinished(backend.(*ethclient.Client), tx.Hash(), "MintERC20Token")
err = waitEthTxFinished(client, tx.Hash(), "MintERC20Token")
if nil != err {
return "", err
}
......@@ -169,7 +166,7 @@ func MintERC20Token(tokenAddr, ownerAddr string, amount *big.Int, backend bind.C
return tx.Hash().String(), nil
}
func ApproveAllowance(ownerPrivateKeyStr, tokenAddr string, bridgeBank common.Address, amount *big.Int, backend bind.ContractBackend) (string, error) {
func ApproveAllowance(ownerPrivateKeyStr, tokenAddr string, bridgeBank common.Address, amount *big.Int, client ethinterface.EthClientSpec) (string, error) {
ownerPrivateKey, err := crypto.ToECDSA(common.FromHex(ownerPrivateKeyStr))
if nil != err {
return "", err
......@@ -184,14 +181,14 @@ func ApproveAllowance(ownerPrivateKeyStr, tokenAddr string, bridgeBank common.Ad
}
}()
auth, err := PrepareAuth(backend, ownerPrivateKey, ownerAddr)
auth, err := PrepareAuth(client, ownerPrivateKey, ownerAddr)
if nil != err {
return "", err
}
prepareDone = true
erc20TokenInstance, err := generated.NewBridgeToken(common.HexToAddress(tokenAddr), backend)
erc20TokenInstance, err := generated.NewBridgeToken(common.HexToAddress(tokenAddr), client)
if nil != err {
return "", err
}
......@@ -201,7 +198,7 @@ func ApproveAllowance(ownerPrivateKeyStr, tokenAddr string, bridgeBank common.Ad
return "", err
}
err = waitEthTxFinished(backend.(*ethclient.Client), tx.Hash(), "ApproveAllowance")
err = waitEthTxFinished(client, tx.Hash(), "ApproveAllowance")
if nil != err {
return "", err
}
......@@ -209,7 +206,7 @@ func ApproveAllowance(ownerPrivateKeyStr, tokenAddr string, bridgeBank common.Ad
return tx.Hash().String(), nil
}
func Burn(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, bridgeBank common.Address, amount *big.Int, bridgeBankIns *generated.BridgeBank, backend bind.ContractBackend) (string, error) {
func Burn(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, bridgeBank common.Address, amount *big.Int, bridgeBankIns *generated.BridgeBank, client ethinterface.EthClientSpec) (string, error) {
ownerPrivateKey, err := crypto.ToECDSA(common.FromHex(ownerPrivateKeyStr))
if nil != err {
return "", err
......@@ -222,7 +219,7 @@ func Burn(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, bridgeBank c
_, _ = revokeNonce(ownerAddr)
}
}()
auth, err := PrepareAuth(backend, ownerPrivateKey, ownerAddr)
auth, err := PrepareAuth(client, ownerPrivateKey, ownerAddr)
if nil != err {
return "", err
}
......@@ -230,7 +227,7 @@ func Burn(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, bridgeBank c
prepareDone = true
tokenAddr := common.HexToAddress(tokenAddrstr)
tokenInstance, err := generated.NewBridgeToken(tokenAddr, backend)
tokenInstance, err := generated.NewBridgeToken(tokenAddr, client)
if nil != err {
return "", err
}
......@@ -239,7 +236,7 @@ func Burn(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, bridgeBank c
if nil != err {
return "", err
}
client := backend.(*ethclient.Client)
err = waitEthTxFinished(client, tx.Hash(), "Approve")
if nil != err {
return "", err
......@@ -248,7 +245,7 @@ func Burn(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, bridgeBank c
prepareDone = false
auth, err = PrepareAuth(backend, ownerPrivateKey, ownerAddr)
auth, err = PrepareAuth(client, ownerPrivateKey, ownerAddr)
if nil != err {
return "", err
}
......@@ -267,7 +264,7 @@ func Burn(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, bridgeBank c
return tx.Hash().String(), nil
}
func BurnAsync(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, bridgeBank common.Address, amount *big.Int, bridgeBankIns *generated.BridgeBank, backend bind.ContractBackend) (string, error) {
func BurnAsync(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, amount *big.Int, bridgeBankIns *generated.BridgeBank, client ethinterface.EthClientSpec) (string, error) {
ownerPrivateKey, err := crypto.ToECDSA(common.FromHex(ownerPrivateKeyStr))
if nil != err {
return "", err
......@@ -281,7 +278,7 @@ func BurnAsync(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, bridgeB
_, _ = revokeNonce(ownerAddr)
}
}()
auth, err := PrepareAuth(backend, ownerPrivateKey, ownerAddr)
auth, err := PrepareAuth(client, ownerPrivateKey, ownerAddr)
if nil != err {
return "", err
}
......@@ -297,8 +294,8 @@ func BurnAsync(ownerPrivateKeyStr, tokenAddrstr, chain33Receiver string, bridgeB
return tx.Hash().String(), nil
}
func TransferToken(tokenAddr, fromPrivateKeyStr, toAddr string, amount *big.Int, backend bind.ContractBackend) (string, error) {
tokenInstance, err := generated.NewBridgeToken(common.HexToAddress(tokenAddr), backend)
func TransferToken(tokenAddr, fromPrivateKeyStr, toAddr string, amount *big.Int, client ethinterface.EthClientSpec) (string, error) {
tokenInstance, err := generated.NewBridgeToken(common.HexToAddress(tokenAddr), client)
if nil != err {
return "", err
}
......@@ -317,7 +314,7 @@ func TransferToken(tokenAddr, fromPrivateKeyStr, toAddr string, amount *big.Int,
}
}()
auth, err := PrepareAuth(backend, fromPrivateKey, fromAddr)
auth, err := PrepareAuth(client, fromPrivateKey, fromAddr)
if nil != err {
return "", err
}
......@@ -329,14 +326,14 @@ func TransferToken(tokenAddr, fromPrivateKeyStr, toAddr string, amount *big.Int,
return "", err
}
err = waitEthTxFinished(backend.(*ethclient.Client), tx.Hash(), "TransferFromToken")
err = waitEthTxFinished(client, tx.Hash(), "TransferFromToken")
if nil != err {
return "", err
}
return tx.Hash().String(), nil
}
func LockEthErc20Asset(ownerPrivateKeyStr, tokenAddrStr, chain33Receiver string, amount *big.Int, backend bind.ContractBackend, bridgeBank *generated.BridgeBank, bridgeBankAddr common.Address) (string, error) {
func LockEthErc20Asset(ownerPrivateKeyStr, tokenAddrStr, chain33Receiver string, amount *big.Int, client ethinterface.EthClientSpec, bridgeBank *generated.BridgeBank, bridgeBankAddr common.Address) (string, error) {
var prepareDone bool
txslog.Info("LockEthErc20Asset", "ownerPrivateKeyStr", ownerPrivateKeyStr, "tokenAddrStr", tokenAddrStr, "chain33Receiver", chain33Receiver, "amount", amount.String())
ownerPrivateKey, err := crypto.ToECDSA(common.FromHex(ownerPrivateKeyStr))
......@@ -356,11 +353,11 @@ func LockEthErc20Asset(ownerPrivateKeyStr, tokenAddrStr, chain33Receiver string,
if "" != tokenAddrStr {
//如果是eth以外的erc20,则需要先进行approve操作
tokenAddr = common.HexToAddress(tokenAddrStr)
tokenInstance, err := generated.NewBridgeToken(tokenAddr, backend)
tokenInstance, err := generated.NewBridgeToken(tokenAddr, client)
if nil != err {
return "", err
}
auth, err := PrepareAuth(backend, ownerPrivateKey, ownerAddr)
auth, err := PrepareAuth(client, ownerPrivateKey, ownerAddr)
if nil != err {
txslog.Error("LockEthErc20Asset", "PrepareAuth err", err.Error())
return "", err
......@@ -373,7 +370,7 @@ func LockEthErc20Asset(ownerPrivateKeyStr, tokenAddrStr, chain33Receiver string,
if nil != err {
return "", err
}
err = waitEthTxFinished(backend.(*ethclient.Client), tx.Hash(), "Approve")
err = waitEthTxFinished(client, tx.Hash(), "Approve")
if nil != err {
return "", err
}
......@@ -382,7 +379,7 @@ func LockEthErc20Asset(ownerPrivateKeyStr, tokenAddrStr, chain33Receiver string,
prepareDone = false
auth, err := PrepareAuth(backend, ownerPrivateKey, ownerAddr)
auth, err := PrepareAuth(client, ownerPrivateKey, ownerAddr)
if nil != err {
txslog.Error("LockEthErc20Asset", "PrepareAuth err", err.Error())
return "", err
......@@ -399,7 +396,7 @@ func LockEthErc20Asset(ownerPrivateKeyStr, tokenAddrStr, chain33Receiver string,
txslog.Error("LockEthErc20Asset", "lock err", err.Error())
return "", err
}
err = waitEthTxFinished(backend.(*ethclient.Client), tx.Hash(), "LockEthErc20Asset")
err = waitEthTxFinished(client, tx.Hash(), "LockEthErc20Asset")
if nil != err {
txslog.Error("LockEthErc20Asset", "waitEthTxFinished err", err.Error())
return "", err
......@@ -408,7 +405,7 @@ func LockEthErc20Asset(ownerPrivateKeyStr, tokenAddrStr, chain33Receiver string,
return tx.Hash().String(), nil
}
func LockEthErc20AssetAsync(ownerPrivateKeyStr, tokenAddrStr, chain33Receiver string, amount *big.Int, backend bind.ContractBackend, bridgeBank *generated.BridgeBank) (string, error) {
func LockEthErc20AssetAsync(ownerPrivateKeyStr, tokenAddrStr, chain33Receiver string, amount *big.Int, client ethinterface.EthClientSpec, bridgeBank *generated.BridgeBank) (string, error) {
txslog.Info("LockEthErc20Asset", "ownerPrivateKeyStr", ownerPrivateKeyStr, "tokenAddrStr", tokenAddrStr, "chain33Receiver", chain33Receiver, "amount", amount.String())
ownerPrivateKey, err := crypto.ToECDSA(common.FromHex(ownerPrivateKeyStr))
if nil != err {
......@@ -416,7 +413,7 @@ func LockEthErc20AssetAsync(ownerPrivateKeyStr, tokenAddrStr, chain33Receiver st
}
ownerAddr := crypto.PubkeyToAddress(ownerPrivateKey.PublicKey)
auth, err := PrepareAuth(backend, ownerPrivateKey, ownerAddr)
auth, err := PrepareAuth(client, ownerPrivateKey, ownerAddr)
if nil != err {
txslog.Error("LockEthErc20Asset", "PrepareAuth err", err.Error())
return "", err
......
......@@ -7,12 +7,10 @@ import (
"math/big"
"time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethinterface"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)
......@@ -57,14 +55,14 @@ type OperatorInfo struct {
}
//DeployValset: 部署Valset
func DeployValset(backend bind.ContractBackend, privateKey *ecdsa.PrivateKey, deployer common.Address, operator common.Address, initValidators []common.Address, initPowers []*big.Int) (*generated.Valset, *DeployResult, error) {
auth, err := PrepareAuth(backend, privateKey, deployer)
func DeployValset(client ethinterface.EthClientSpec, privateKey *ecdsa.PrivateKey, deployer common.Address, operator common.Address, initValidators []common.Address, initPowers []*big.Int) (*generated.Valset, *DeployResult, error) {
auth, err := PrepareAuth(client, privateKey, deployer)
if nil != err {
return nil, nil, err
}
//部署合约
addr, tx, valset, err := generated.DeployValset(auth, backend, operator, initValidators, initPowers)
addr, tx, valset, err := generated.DeployValset(auth, client, operator, initValidators, initPowers)
if err != nil {
return nil, nil, err
}
......@@ -78,14 +76,14 @@ func DeployValset(backend bind.ContractBackend, privateKey *ecdsa.PrivateKey, de
}
//DeployChain33Bridge: 部署Chain33Bridge
func DeployChain33Bridge(backend bind.ContractBackend, privateKey *ecdsa.PrivateKey, deployer common.Address, operator, valset common.Address) (*generated.Chain33Bridge, *DeployResult, error) {
auth, err := PrepareAuth(backend, privateKey, deployer)
func DeployChain33Bridge(client ethinterface.EthClientSpec, privateKey *ecdsa.PrivateKey, deployer common.Address, operator, valset common.Address) (*generated.Chain33Bridge, *DeployResult, error) {
auth, err := PrepareAuth(client, privateKey, deployer)
if nil != err {
return nil, nil, err
}
//部署合约
addr, tx, chain33Bridge, err := generated.DeployChain33Bridge(auth, backend, operator, valset)
addr, tx, chain33Bridge, err := generated.DeployChain33Bridge(auth, client, operator, valset)
if err != nil {
return nil, nil, err
}
......@@ -98,14 +96,14 @@ func DeployChain33Bridge(backend bind.ContractBackend, privateKey *ecdsa.Private
}
//DeployOracle: 部署Oracle
func DeployOracle(backend bind.ContractBackend, privateKey *ecdsa.PrivateKey, deployer, operator, valset, chain33Bridge common.Address) (*generated.Oracle, *DeployResult, error) {
auth, err := PrepareAuth(backend, privateKey, deployer)
func DeployOracle(client ethinterface.EthClientSpec, privateKey *ecdsa.PrivateKey, deployer, operator, valset, chain33Bridge common.Address) (*generated.Oracle, *DeployResult, error) {
auth, err := PrepareAuth(client, privateKey, deployer)
if nil != err {
return nil, nil, err
}
//部署合约
addr, tx, oracle, err := generated.DeployOracle(auth, backend, operator, valset, chain33Bridge)
addr, tx, oracle, err := generated.DeployOracle(auth, client, operator, valset, chain33Bridge)
if err != nil {
return nil, nil, err
}
......@@ -118,14 +116,14 @@ func DeployOracle(backend bind.ContractBackend, privateKey *ecdsa.PrivateKey, de
}
//DeployBridgeBank: 部署BridgeBank
func DeployBridgeBank(backend bind.ContractBackend, privateKey *ecdsa.PrivateKey, deployer, operator, oracle, chain33Bridge common.Address) (*generated.BridgeBank, *DeployResult, error) {
auth, err := PrepareAuth(backend, privateKey, deployer)
func DeployBridgeBank(client ethinterface.EthClientSpec, privateKey *ecdsa.PrivateKey, deployer, operator, oracle, chain33Bridge common.Address) (*generated.BridgeBank, *DeployResult, error) {
auth, err := PrepareAuth(client, privateKey, deployer)
if nil != err {
return nil, nil, err
}
//部署合约
addr, tx, bridgeBank, err := generated.DeployBridgeBank(auth, backend, operator, oracle, chain33Bridge)
addr, tx, bridgeBank, err := generated.DeployBridgeBank(auth, client, operator, oracle, chain33Bridge)
if err != nil {
return nil, nil, err
}
......@@ -138,14 +136,14 @@ func DeployBridgeBank(backend bind.ContractBackend, privateKey *ecdsa.PrivateKey
}
//DeployBridgeRegistry: 部署BridgeRegistry
func DeployBridgeRegistry(backend bind.ContractBackend, privateKey *ecdsa.PrivateKey, deployer, chain33BridgeAddr, bridgeBankAddr, oracleAddr, valsetAddr common.Address) (*generated.BridgeRegistry, *DeployResult, error) {
auth, err := PrepareAuth(backend, privateKey, deployer)
func DeployBridgeRegistry(client ethinterface.EthClientSpec, privateKey *ecdsa.PrivateKey, deployer, chain33BridgeAddr, bridgeBankAddr, oracleAddr, valsetAddr common.Address) (*generated.BridgeRegistry, *DeployResult, error) {
auth, err := PrepareAuth(client, privateKey, deployer)
if nil != err {
return nil, nil, err
}
//部署合约
addr, tx, bridgeRegistry, err := generated.DeployBridgeRegistry(auth, backend, chain33BridgeAddr, bridgeBankAddr, oracleAddr, valsetAddr)
addr, tx, bridgeRegistry, err := generated.DeployBridgeRegistry(auth, client, chain33BridgeAddr, bridgeBankAddr, oracleAddr, valsetAddr)
if err != nil {
return nil, nil, err
}
......@@ -157,20 +155,20 @@ func DeployBridgeRegistry(backend bind.ContractBackend, privateKey *ecdsa.Privat
return bridgeRegistry, deployResult, nil
}
func DeployAndInit(backend bind.ContractBackend, para *DeployPara) (*X2EthContracts, *X2EthDeployInfo, error) {
func DeployAndInit(client ethinterface.EthClientSpec, para *DeployPara) (*X2EthContracts, *X2EthDeployInfo, error) {
x2EthContracts := &X2EthContracts{}
deployInfo := &X2EthDeployInfo{}
var err error
/////////////////////////////////////
sim, isSim := backend.(*backends.SimulatedBackend)
sim, isSim := client.(*ethinterface.SimExtend)
if isSim {
fmt.Println("Use the simulator")
} else {
fmt.Println("Use the actual Ethereum")
}
x2EthContracts.Valset, deployInfo.Valset, err = DeployValset(backend, para.DeployPrivateKey, para.Deployer, para.Operator, para.InitValidators, para.InitPowers)
x2EthContracts.Valset, deployInfo.Valset, err = DeployValset(client, para.DeployPrivateKey, para.Deployer, para.Operator, para.InitValidators, para.InitPowers)
if nil != err {
deployLog.Error("DeployAndInit", "failed to DeployValset due to:", err.Error())
return nil, nil, err
......@@ -178,7 +176,6 @@ func DeployAndInit(backend bind.ContractBackend, para *DeployPara) (*X2EthContra
if isSim {
sim.Commit()
} else {
client := backend.(*ethclient.Client)
fmt.Println("\nDeployValset tx hash:", deployInfo.Valset.TxHash)
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
......@@ -215,7 +212,7 @@ func DeployAndInit(backend bind.ContractBackend, para *DeployPara) (*X2EthContra
}
deployChain33Bridge:
x2EthContracts.Chain33Bridge, deployInfo.Chain33Bridge, err = DeployChain33Bridge(backend, para.DeployPrivateKey, para.Deployer, para.Operator, deployInfo.Valset.Address)
x2EthContracts.Chain33Bridge, deployInfo.Chain33Bridge, err = DeployChain33Bridge(client, para.DeployPrivateKey, para.Deployer, para.Operator, deployInfo.Valset.Address)
if nil != err {
deployLog.Error("DeployAndInit", "failed to DeployChain33Bridge due to:", err.Error())
return nil, nil, err
......@@ -223,7 +220,6 @@ deployChain33Bridge:
if isSim {
sim.Commit()
} else {
client := backend.(*ethclient.Client)
fmt.Printf("\n\nGoing to DeployChain33Bridge with valset address:%s", deployInfo.Valset.Address.String())
fmt.Println("\nDeployChain33Bridge tx hash:", deployInfo.Chain33Bridge.TxHash)
timeout := time.NewTimer(300 * time.Second)
......@@ -261,7 +257,7 @@ deployChain33Bridge:
}
deployOracle:
x2EthContracts.Oracle, deployInfo.Oracle, err = DeployOracle(backend, para.DeployPrivateKey, para.Deployer, para.Operator, deployInfo.Valset.Address, deployInfo.Chain33Bridge.Address)
x2EthContracts.Oracle, deployInfo.Oracle, err = DeployOracle(client, para.DeployPrivateKey, para.Deployer, para.Operator, deployInfo.Valset.Address, deployInfo.Chain33Bridge.Address)
if nil != err {
deployLog.Error("DeployAndInit", "failed to DeployOracle due to:", err.Error())
return nil, nil, err
......@@ -269,7 +265,6 @@ deployOracle:
if isSim {
sim.Commit()
} else {
client := backend.(*ethclient.Client)
fmt.Println("DeployOracle tx hash:", deployInfo.Oracle.TxHash)
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
......@@ -306,7 +301,7 @@ deployOracle:
}
/////////////////////////////////////
deployBridgeBank:
x2EthContracts.BridgeBank, deployInfo.BridgeBank, err = DeployBridgeBank(backend, para.DeployPrivateKey, para.Deployer, para.Operator, deployInfo.Oracle.Address, deployInfo.Chain33Bridge.Address)
x2EthContracts.BridgeBank, deployInfo.BridgeBank, err = DeployBridgeBank(client, para.DeployPrivateKey, para.Deployer, para.Operator, deployInfo.Oracle.Address, deployInfo.Chain33Bridge.Address)
if nil != err {
deployLog.Error("DeployAndInit", "failed to DeployBridgeBank due to:", err.Error())
return nil, nil, err
......@@ -314,7 +309,6 @@ deployBridgeBank:
if isSim {
sim.Commit()
} else {
client := backend.(*ethclient.Client)
fmt.Println("DeployBridgeBank tx hash:", deployInfo.BridgeBank.TxHash)
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
......@@ -352,7 +346,7 @@ deployBridgeBank:
settingBridgeBank:
////////////////////////
auth, err := PrepareAuth(backend, para.DeployPrivateKey, para.Deployer)
auth, err := PrepareAuth(client, para.DeployPrivateKey, para.Deployer)
if nil != err {
return nil, nil, err
}
......@@ -364,7 +358,6 @@ settingBridgeBank:
if isSim {
sim.Commit()
} else {
client := backend.(*ethclient.Client)
fmt.Println("setBridgeBankTx tx hash:", setBridgeBankTx.Hash().String())
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
......@@ -401,7 +394,7 @@ settingBridgeBank:
}
setOracle:
auth, err = PrepareAuth(backend, para.DeployPrivateKey, para.Deployer)
auth, err = PrepareAuth(client, para.DeployPrivateKey, para.Deployer)
if nil != err {
return nil, nil, err
}
......@@ -413,7 +406,6 @@ setOracle:
if isSim {
sim.Commit()
} else {
client := backend.(*ethclient.Client)
fmt.Println("setOracleTx tx hash:", setOracleTx.Hash().String())
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
......@@ -450,7 +442,7 @@ setOracle:
}
deployBridgeRegistry:
x2EthContracts.BridgeRegistry, deployInfo.BridgeRegistry, err = DeployBridgeRegistry(backend, para.DeployPrivateKey, para.Deployer, deployInfo.Chain33Bridge.Address, deployInfo.BridgeBank.Address, deployInfo.Oracle.Address, deployInfo.Valset.Address)
x2EthContracts.BridgeRegistry, deployInfo.BridgeRegistry, err = DeployBridgeRegistry(client, para.DeployPrivateKey, para.Deployer, deployInfo.Chain33Bridge.Address, deployInfo.BridgeBank.Address, deployInfo.Oracle.Address, deployInfo.Valset.Address)
if nil != err {
deployLog.Error("DeployAndInit", "failed to DeployBridgeBank due to:", err.Error())
return nil, nil, err
......@@ -458,7 +450,6 @@ deployBridgeRegistry:
if isSim {
sim.Commit()
} else {
client := backend.(*ethclient.Client)
fmt.Println("DeployBridgeRegistry tx hash:", deployInfo.BridgeRegistry.TxHash)
timeout := time.NewTimer(300 * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
......
......@@ -3,14 +3,13 @@ package ethtxs
import (
"context"
"errors"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethinterface"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)
func GetOperator(client *ethclient.Client, sender, bridgeBank common.Address) (common.Address, error) {
func GetOperator(client ethinterface.EthClientSpec, sender, bridgeBank common.Address) (common.Address, error) {
header, err := client.HeaderByNumber(context.Background(), nil)
if err != nil {
txslog.Error("GetOperator", "Failed to get HeaderByNumber due to:", err.Error())
......@@ -68,7 +67,7 @@ func IsProphecyPending(claimID [32]byte, validator common.Address, chain33Bridge
return active, nil
}
func GetBalance(client *ethclient.Client, tokenAddr, owner string) (string, error) {
func GetBalance(client ethinterface.EthClientSpec, tokenAddr, owner string) (string, error) {
//查询ERC20余额
if tokenAddr != "" {
bridgeToken, err := generated.NewBridgeToken(common.HexToAddress(tokenAddr), client)
......@@ -113,13 +112,13 @@ func GetLockedFunds(bridgeBank *generated.BridgeBank, tokenAddrStr string) (stri
return balance.String(), nil
}
func GetDepositFunds(backend bind.ContractBackend, tokenAddrStr string) (string, error) {
func GetDepositFunds(client ethinterface.EthClientSpec, tokenAddrStr string) (string, error) {
if tokenAddrStr == "" {
return "", errors.New("nil token address")
}
tokenAddr := common.HexToAddress(tokenAddrStr)
bridgeToken, err := generated.NewBridgeToken(tokenAddr, backend)
bridgeToken, err := generated.NewBridgeToken(tokenAddr, client)
if nil != err {
return "", err
}
......
......@@ -4,39 +4,39 @@ import (
"errors"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethinterface"
"github.com/ethereum/go-ethereum/common"
)
func RecoverContractHandler(backend bind.ContractBackend, sender, registry common.Address) (*X2EthContracts, *X2EthDeployInfo, error) {
bridgeBankAddr, err := GetAddressFromBridgeRegistry(backend, sender, registry, BridgeBank)
func RecoverContractHandler(client ethinterface.EthClientSpec, sender, registry common.Address) (*X2EthContracts, *X2EthDeployInfo, error) {
bridgeBankAddr, err := GetAddressFromBridgeRegistry(client, sender, registry, BridgeBank)
if nil != err {
return nil, nil, errors.New("Failed to get addr for bridgeBank from registry")
return nil, nil, errors.New("failed to get addr for bridgeBank from registry")
}
bridgeBank, err := generated.NewBridgeBank(*bridgeBankAddr, backend)
bridgeBank, err := generated.NewBridgeBank(*bridgeBankAddr, client)
if nil != err {
return nil, nil, errors.New("Failed to NewBridgeBank")
return nil, nil, errors.New("failed to NewBridgeBank")
}
chain33BridgeAddr, err := GetAddressFromBridgeRegistry(backend, sender, registry, Chain33Bridge)
chain33BridgeAddr, err := GetAddressFromBridgeRegistry(client, sender, registry, Chain33Bridge)
if nil != err {
return nil, nil, errors.New("Failed to get addr for chain33BridgeAddr from registry")
return nil, nil, errors.New("failed to get addr for chain33BridgeAddr from registry")
}
chain33Bridge, err := generated.NewChain33Bridge(*chain33BridgeAddr, backend)
chain33Bridge, err := generated.NewChain33Bridge(*chain33BridgeAddr, client)
if nil != err {
return nil, nil, errors.New("Failed to NewChain33Bridge")
return nil, nil, errors.New("failed to NewChain33Bridge")
}
oracleAddr, err := GetAddressFromBridgeRegistry(backend, sender, registry, Oracle)
oracleAddr, err := GetAddressFromBridgeRegistry(client, sender, registry, Oracle)
if nil != err {
return nil, nil, errors.New("Failed to get addr for oracleBridgeAddr from registry")
return nil, nil, errors.New("failed to get addr for oracleBridgeAddr from registry")
}
oracle, err := generated.NewOracle(*oracleAddr, backend)
oracle, err := generated.NewOracle(*oracleAddr, client)
if nil != err {
return nil, nil, errors.New("Failed to NewOracle")
return nil, nil, errors.New("failed to NewOracle")
}
registryInstance, _ := generated.NewBridgeRegistry(registry, backend)
registryInstance, _ := generated.NewBridgeRegistry(registry, client)
x2EthContracts := &X2EthContracts{
BridgeRegistry: registryInstance,
BridgeBank: bridgeBank,
......@@ -54,14 +54,14 @@ func RecoverContractHandler(backend bind.ContractBackend, sender, registry commo
return x2EthContracts, x2EthDeployInfo, nil
}
func RecoverOracleInstance(backend bind.ContractBackend, sender, registry common.Address) (*generated.Oracle, error) {
oracleAddr, err := GetAddressFromBridgeRegistry(backend, sender, registry, Oracle)
func RecoverOracleInstance(client ethinterface.EthClientSpec, sender, registry common.Address) (*generated.Oracle, error) {
oracleAddr, err := GetAddressFromBridgeRegistry(client, sender, registry, Oracle)
if nil != err {
return nil, errors.New("Failed to get addr for oracleBridgeAddr from registry")
return nil, errors.New("failed to get addr for oracleBridgeAddr from registry")
}
oracle, err := generated.NewOracle(*oracleAddr, backend)
oracle, err := generated.NewOracle(*oracleAddr, client)
if nil != err {
return nil, errors.New("Failed to NewOracle")
return nil, errors.New("failed to NewOracle")
}
return oracle, nil
......
......@@ -4,12 +4,11 @@ import (
"context"
"log"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
bridgeRegistry "github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethinterface"
ebrelayerTypes "github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
)
// ContractRegistry :
......@@ -32,8 +31,8 @@ func (d ContractRegistry) String() string {
}
// GetAddressFromBridgeRegistry : utility method which queries the requested contract address from the BridgeRegistry
func GetAddressFromBridgeRegistry(backend bind.ContractBackend, sender, registry common.Address, target ContractRegistry) (address *common.Address, err error) {
header, err := backend.(*ethclient.Client).HeaderByNumber(context.Background(), nil)
func GetAddressFromBridgeRegistry(client ethinterface.EthClientSpec, sender, registry common.Address, target ContractRegistry) (address *common.Address, err error) {
header, err := client.HeaderByNumber(context.Background(), nil)
if err != nil {
txslog.Error("GetAddressFromBridgeRegistry", "Failed to get HeaderByNumber due to:", err.Error())
return nil, err
......@@ -48,7 +47,7 @@ func GetAddressFromBridgeRegistry(backend bind.ContractBackend, sender, registry
}
// Initialize BridgeRegistry instance
registryInstance, err := bridgeRegistry.NewBridgeRegistry(registry, backend)
registryInstance, err := bridgeRegistry.NewBridgeRegistry(registry, client)
if err != nil {
txslog.Error("GetAddressFromBridgeRegistry", "Failed to NewBridgeRegistry to:", err.Error())
return nil, err
......@@ -86,7 +85,7 @@ func GetAddressFromBridgeRegistry(backend bind.ContractBackend, sender, registry
}
// GetDeployHeight : 获取合约部署高度
func GetDeployHeight(client *ethclient.Client, sender, registry common.Address) (height int64, err error) {
func GetDeployHeight(client ethinterface.EthClientSpec, sender, registry common.Address) (height int64, err error) {
header, err := client.HeaderByNumber(context.Background(), nil)
if err != nil {
txslog.Error("GetAddressFromBridgeRegistry", "Failed to get HeaderByNumber due to:", err.Error())
......
......@@ -2,8 +2,8 @@ package ethtxs
import (
"crypto/ecdsa"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethinterface"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/33cn/chain33/common/log/log15"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
......@@ -23,10 +23,10 @@ const (
)
// RelayOracleClaimToEthereum : relays the provided burn or lock to Chain33Bridge contract on the Ethereum network
func RelayOracleClaimToEthereum(oracleInstance *generated.Oracle, backend bind.ContractBackend, sender common.Address, event events.Event, claim ProphecyClaim, privateKey *ecdsa.PrivateKey, chain33TxHash []byte) (txhash string, err error) {
txslog.Info("RelayProphecyClaimToEthereum", "sender", sender.String(), "event", event, "chain33Sender", common.ToHex(claim.Chain33Sender), "ethereumReceiver", claim.EthereumReceiver.String(), "TokenAddress", claim.TokenContractAddress.String(), "symbol", claim.Symbol, "Amount", claim.Amount.String(), "claimType", claim.ClaimType.String())
func RelayOracleClaimToEthereum(oracleInstance *generated.Oracle, client ethinterface.EthClientSpec, sender common.Address, event events.Event, claim ProphecyClaim, privateKey *ecdsa.PrivateKey, chain33TxHash []byte) (txhash string, err error) {
txslog.Info("RelayProphecyClaimToEthereum", "sender", sender.String(), "event", event, "chain33Sender", hexutil.Encode(claim.Chain33Sender), "ethereumReceiver", claim.EthereumReceiver.String(), "TokenAddress", claim.TokenContractAddress.String(), "symbol", claim.Symbol, "Amount", claim.Amount.String(), "claimType", claim.ClaimType.String())
auth, err := PrepareAuth(backend, privateKey, sender)
auth, err := PrepareAuth(client, privateKey, sender)
if nil != err {
txslog.Error("RelayProphecyClaimToEthereum", "PrepareAuth err", err.Error())
return "", err
......
......@@ -8,6 +8,7 @@ import (
"sync"
"time"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethinterface"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
......@@ -15,7 +16,6 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/ethclient"
solsha3 "github.com/miguelmota/go-solidity-sha3"
)
......@@ -34,8 +34,6 @@ func (ethTxStatus EthTxStatus) String() string {
const (
PendingDuration4TxExeuction = 300
EthTxFail = EthTxStatus(0)
EthTxSuccess = EthTxStatus(1)
EthTxPending = EthTxStatus(2)
)
......@@ -64,7 +62,7 @@ func prefixMessage(message common.Hash, key *ecdsa.PrivateKey) ([]byte, []byte)
return sig, prefixed
}
func getNonce(sender common.Address, backend bind.ContractBackend) (*big.Int, error) {
func getNonce(sender common.Address, client ethinterface.EthClientSpec) (*big.Int, error) {
if nonceMutex, exist := addr2Nonce[sender]; exist {
nonceMutex.rw.Lock()
defer nonceMutex.rw.Unlock()
......@@ -74,7 +72,7 @@ func getNonce(sender common.Address, backend bind.ContractBackend) (*big.Int, er
return big.NewInt(nonceMutex.nonce), nil
}
nonce, err := backend.PendingNonceAt(context.Background(), sender)
nonce, err := client.PendingNonceAt(context.Background(), sender)
if nil != err {
return nil, err
}
......@@ -95,43 +93,41 @@ func revokeNonce(sender common.Address) (*big.Int, error) {
txslog.Debug("revokeNonce", "address", sender.String(), "nonce", nonceMutex.nonce)
return big.NewInt(nonceMutex.nonce), nil
}
return nil, errors.New("Address doesn't exist tx")
return nil, errors.New("address doesn't exist tx")
}
func PrepareAuth(backend bind.ContractBackend, privateKey *ecdsa.PrivateKey, transactor common.Address) (*bind.TransactOpts, error) {
//var backend bind.ContractBackend = client
//client *ethclient.Client
if nil == privateKey || nil == backend {
txslog.Error("PrepareAuth", "nil input parameter", "backend", backend, "privateKey", privateKey)
func PrepareAuth(client ethinterface.EthClientSpec, privateKey *ecdsa.PrivateKey, transactor common.Address) (*bind.TransactOpts, error) {
if nil == privateKey || nil == client {
txslog.Error("PrepareAuth", "nil input parameter", "client", client, "privateKey", privateKey)
return nil, errors.New("nil input parameter")
}
ctx := context.Background()
gasPrice, err := backend.SuggestGasPrice(ctx)
gasPrice, err := client.SuggestGasPrice(ctx)
if err != nil {
txslog.Error("PrepareAuth", "Failed to SuggestGasPrice due to:", err.Error())
return nil, errors.New("Failed to get suggest gas price")
return nil, errors.New("failed to get suggest gas price")
}
auth := bind.NewKeyedTransactor(privateKey)
auth.Value = big.NewInt(0) // in wei
auth.GasLimit = GasLimit4Deploy
auth.GasPrice = gasPrice
if auth.Nonce, err = getNonce(transactor, backend); err != nil {
if auth.Nonce, err = getNonce(transactor, client); err != nil {
return nil, err
}
return auth, nil
}
func waitEthTxFinished(client *ethclient.Client, txhash common.Hash, txName string) error {
func waitEthTxFinished(client ethinterface.EthClientSpec, txhash common.Hash, txName string) error {
txslog.Info(txName, "Wait for tx to be finished executing with hash", txhash.String())
timeout := time.NewTimer(PendingDuration4TxExeuction * time.Second)
oneSecondtimeout := time.NewTicker(5 * time.Second)
for {
select {
case <-timeout.C:
return errors.New("Eth tx timeout")
return errors.New("eth tx timeout")
case <-oneSecondtimeout.C:
_, err := client.TransactionReceipt(context.Background(), txhash)
if err == ethereum.NotFound {
......@@ -145,7 +141,7 @@ func waitEthTxFinished(client *ethclient.Client, txhash common.Hash, txName stri
}
}
func GetEthTxStatus(client *ethclient.Client, txhash common.Hash) string {
func GetEthTxStatus(client ethinterface.EthClientSpec, txhash common.Hash) string {
receipt, err := client.TransactionReceipt(context.Background(), txhash)
if nil != err {
return EthTxPending.String()
......
......@@ -11,15 +11,13 @@ import (
"sync/atomic"
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/ethclient"
dbm "github.com/33cn/chain33/common/db"
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/chain33/rpc/jsonclient"
rpctypes "github.com/33cn/chain33/rpc/types"
chain33Types "github.com/33cn/chain33/types"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethinterface"
relayerTx "github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethtxs"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/events"
syncTx "github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/relayer/chain33/transceiver/sync"
......@@ -33,7 +31,7 @@ var relayerLog = log.New("module", "chain33_relayer")
type Relayer4Chain33 struct {
syncTxReceipts *syncTx.TxReceipts
ethBackend bind.ContractBackend
ethClient ethinterface.EthClientSpec
rpcLaddr string //用户向指定的blockchain节点进行rpc调用
fetchHeightPeriodMs int64
db dbm.DB
......@@ -53,7 +51,7 @@ type Relayer4Chain33 struct {
// StartChain33Relayer : initializes a relayer which witnesses events on the chain33 network and relays them to Ethereum
func StartChain33Relayer(ctx context.Context, syncTxConfig *ebTypes.SyncTxConfig, registryAddr, provider string, db dbm.DB) *Relayer4Chain33 {
relayer := &Relayer4Chain33{
chian33Relayer := &Relayer4Chain33{
rpcLaddr: syncTxConfig.Chain33Host,
fetchHeightPeriodMs: syncTxConfig.FetchHeightPeriodMs,
unlock: make(chan int),
......@@ -76,12 +74,12 @@ func StartChain33Relayer(ctx context.Context, syncTxConfig *ebTypes.SyncTxConfig
if err != nil {
panic(err)
}
relayer.ethBackend = client
relayer.totalTx4Chain33ToEth = relayer.getTotalTxAmount2Eth()
relayer.statusCheckedIndex = relayer.getStatusCheckedIndex()
chian33Relayer.ethClient = client
chian33Relayer.totalTx4Chain33ToEth = chian33Relayer.getTotalTxAmount2Eth()
chian33Relayer.statusCheckedIndex = chian33Relayer.getStatusCheckedIndex()
go relayer.syncProc(syncCfg)
return relayer
go chian33Relayer.syncProc(syncCfg)
return chian33Relayer
}
func (chain33Relayer *Relayer4Chain33) QueryTxhashRelay2Eth() ebTypes.Txhashes {
......@@ -97,7 +95,7 @@ func (chain33Relayer *Relayer4Chain33) syncProc(syncCfg *ebTypes.SyncTxReceiptCo
chain33Relayer.syncTxReceipts = syncTx.StartSyncTxReceipt(syncCfg, chain33Relayer.db)
chain33Relayer.lastHeight4Tx = chain33Relayer.loadLastSyncHeight()
oracleInstance, err := relayerTx.RecoverOracleInstance(chain33Relayer.ethBackend, chain33Relayer.bridgeRegistryAddr, chain33Relayer.bridgeRegistryAddr)
oracleInstance, err := relayerTx.RecoverOracleInstance(chain33Relayer.ethClient, chain33Relayer.bridgeRegistryAddr, chain33Relayer.bridgeRegistryAddr)
if err != nil {
panic(err.Error())
}
......@@ -137,7 +135,7 @@ func (chain33Relayer *Relayer4Chain33) onNewHeightProc(currentHeight int64) {
relayerLog.Error("onNewHeightProc", "getEthTxhash for index ", index, "error", err.Error())
break
}
status := relayerTx.GetEthTxStatus(chain33Relayer.ethBackend.(*ethclient.Client), txhash)
status := relayerTx.GetEthTxStatus(chain33Relayer.ethClient, txhash)
//按照提交交易的先后顺序检查交易,只要出现当前交易还在pending状态,就不再检查后续交易,等到下个区块再从该交易进行检查
//TODO:可能会由于网络和打包挖矿的原因,使得交易执行顺序和提交顺序有差别,后续完善该检查逻辑
if status == relayerTx.EthTxPending.String() {
......@@ -221,7 +219,7 @@ func (chain33Relayer *Relayer4Chain33) handleBurnLockMsg(claimEvent events.Event
prophecyClaim := relayerTx.Chain33MsgToProphecyClaim(*chain33Msg)
// Relay the Chain33Msg to the Ethereum network
txhash, err := relayerTx.RelayOracleClaimToEthereum(chain33Relayer.oracleInstance, chain33Relayer.ethBackend, chain33Relayer.ethSender, claimEvent, prophecyClaim, chain33Relayer.privateKey4Ethereum, chain33TxHash)
txhash, err := relayerTx.RelayOracleClaimToEthereum(chain33Relayer.oracleInstance, chain33Relayer.ethClient, chain33Relayer.ethSender, claimEvent, prophecyClaim, chain33Relayer.privateKey4Ethereum, chain33TxHash)
if nil != err {
return err
}
......
......@@ -20,23 +20,21 @@ import (
"sync/atomic"
"time"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
x2ethTypes "github.com/33cn/plugin/plugin/dapp/x2ethereum/types"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
chain33Crypto "github.com/33cn/chain33/common/crypto"
dbm "github.com/33cn/chain33/common/db"
log "github.com/33cn/chain33/common/log/log15"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethinterface"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethtxs"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/events"
ebTypes "github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/types"
x2ethTypes "github.com/33cn/plugin/plugin/dapp/x2ethereum/types"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
)
type Relayer4Ethereum struct {
......@@ -54,7 +52,7 @@ type Relayer4Ethereum struct {
maturityDegree int32
fetchHeightPeriodMs int32
eventLogIndex ebTypes.EventLogIndex
backend bind.ContractBackend
clientSpec ethinterface.EthClientSpec
bridgeBankAddr common.Address
bridgeBankSub ethereum.Subscription
bridgeBankLog chan types.Log
......@@ -80,7 +78,7 @@ func StartEthereumRelayer(rpcURL2Chain33 string, db dbm.DB, provider, registryAd
if 0 == blockInterval {
blockInterval = DefaultBlockPeriod
}
relayer := &Relayer4Ethereum{
ethRelayer := &Relayer4Ethereum{
provider: provider,
db: db,
unlockchan: make(chan int, 2),
......@@ -91,21 +89,37 @@ func StartEthereumRelayer(rpcURL2Chain33 string, db dbm.DB, provider, registryAd
fetchHeightPeriodMs: blockInterval,
}
registrAddrInDB, err := relayer.getBridgeRegistryAddr()
registrAddrInDB, err := ethRelayer.getBridgeRegistryAddr()
//如果输入的registry地址非空,且和数据库保存地址不一致,则直接使用输入注册地址
if registryAddress != "" && nil == err && registrAddrInDB != registryAddress {
relayerLog.Error("StartEthereumRelayer", "BridgeRegistry is setted already with value", registrAddrInDB,
"but now setting to", registryAddress)
_ = relayer.setBridgeRegistryAddr(registryAddress)
_ = ethRelayer.setBridgeRegistryAddr(registryAddress)
} else if registryAddress == "" && registrAddrInDB != "" {
//输入地址为空,且数据库中保存地址不为空,则直接使用数据库中的地址
relayer.bridgeRegistryAddr = common.HexToAddress(registrAddrInDB)
ethRelayer.bridgeRegistryAddr = common.HexToAddress(registrAddrInDB)
}
ethRelayer.eventLogIndex = ethRelayer.getLastBridgeBankProcessedHeight()
ethRelayer.initBridgeBankTx()
// Start clientSpec with infura ropsten provider
relayerLog.Info("Relayer4Ethereum proc", "Started Ethereum websocket with provider:", ethRelayer.provider, "rpcURL2Chain33:", ethRelayer.rpcURL2Chain33)
client, err := ethtxs.SetupWebsocketEthClient(ethRelayer.provider)
if err != nil {
panic(err)
}
relayer.eventLogIndex = relayer.getLastBridgeBankProcessedHeight()
relayer.initBridgeBankTx()
ethRelayer.clientSpec = client
go relayer.proc()
return relayer
ctx := context.Background()
clientChainID, err := client.NetworkID(ctx)
if err != nil {
errinfo := fmt.Sprintf("Failed to get NetworkID due to:%s", err.Error())
panic(errinfo)
}
ethRelayer.clientChainID = clientChainID
go ethRelayer.proc()
return ethRelayer
}
func (ethRelayer *Relayer4Ethereum) recoverDeployPara() (err error) {
......@@ -172,7 +186,7 @@ func (ethRelayer *Relayer4Ethereum) DeployContrcts() (bridgeRegistry string, err
"power", power.String())
}
x2EthContracts, x2EthDeployInfo, err := ethtxs.DeployAndInit(ethRelayer.backend, para)
x2EthContracts, x2EthDeployInfo, err := ethtxs.DeployAndInit(ethRelayer.clientSpec, para)
if err != nil {
return bridgeRegistry, err
}
......@@ -195,7 +209,7 @@ func (ethRelayer *Relayer4Ethereum) DeployContrcts() (bridgeRegistry string, err
//GetBalance:获取某一个币种的余额
func (ethRelayer *Relayer4Ethereum) GetBalance(tokenAddr, owner string) (string, error) {
return ethtxs.GetBalance(ethRelayer.backend.(*ethclient.Client), tokenAddr, owner)
return ethtxs.GetBalance(ethRelayer.clientSpec, tokenAddr, owner)
}
func (ethRelayer *Relayer4Ethereum) ShowBridgeBankAddr() (string, error) {
......@@ -219,7 +233,7 @@ func (ethRelayer *Relayer4Ethereum) ShowLockStatics(tokenAddr string) (string, e
}
func (ethRelayer *Relayer4Ethereum) ShowDepositStatics(tokenAddr string) (string, error) {
return ethtxs.GetDepositFunds(ethRelayer.backend, tokenAddr)
return ethtxs.GetDepositFunds(ethRelayer.clientSpec, tokenAddr)
}
func (ethRelayer *Relayer4Ethereum) ShowTokenAddrBySymbol(tokenSymbol string) (string, error) {
......@@ -231,41 +245,41 @@ func (ethRelayer *Relayer4Ethereum) IsProphecyPending(claimID [32]byte) (bool, e
}
func (ethRelayer *Relayer4Ethereum) CreateBridgeToken(symbol string) (string, error) {
return ethtxs.CreateBridgeToken(symbol, ethRelayer.backend, ethRelayer.operatorInfo, ethRelayer.x2EthDeployInfo, ethRelayer.x2EthContracts)
return ethtxs.CreateBridgeToken(symbol, ethRelayer.clientSpec, ethRelayer.operatorInfo, ethRelayer.x2EthDeployInfo, ethRelayer.x2EthContracts)
}
func (ethRelayer *Relayer4Ethereum) CreateERC20Token(symbol string) (string, error) {
return ethtxs.CreateERC20Token(symbol, ethRelayer.backend, ethRelayer.operatorInfo, ethRelayer.x2EthDeployInfo, ethRelayer.x2EthContracts)
return ethtxs.CreateERC20Token(symbol, ethRelayer.clientSpec, ethRelayer.operatorInfo)
}
func (ethRelayer *Relayer4Ethereum) MintERC20Token(tokenAddr, ownerAddr, amount string) (string, error) {
bn := big.NewInt(1)
bn, _ = bn.SetString(x2ethTypes.TrimZeroAndDot(amount), 10)
return ethtxs.MintERC20Token(tokenAddr, ownerAddr, bn, ethRelayer.backend, ethRelayer.operatorInfo)
return ethtxs.MintERC20Token(tokenAddr, ownerAddr, bn, ethRelayer.clientSpec, ethRelayer.operatorInfo)
}
func (ethRelayer *Relayer4Ethereum) ApproveAllowance(ownerPrivateKey, tokenAddr, amount string) (string, error) {
bn := big.NewInt(1)
bn, _ = bn.SetString(x2ethTypes.TrimZeroAndDot(amount), 10)
return ethtxs.ApproveAllowance(ownerPrivateKey, tokenAddr, ethRelayer.x2EthDeployInfo.BridgeBank.Address, bn, ethRelayer.backend)
return ethtxs.ApproveAllowance(ownerPrivateKey, tokenAddr, ethRelayer.x2EthDeployInfo.BridgeBank.Address, bn, ethRelayer.clientSpec)
}
func (ethRelayer *Relayer4Ethereum) Burn(ownerPrivateKey, tokenAddr, chain33Receiver, amount string) (string, error) {
bn := big.NewInt(1)
bn, _ = bn.SetString(x2ethTypes.TrimZeroAndDot(amount), 10)
return ethtxs.Burn(ownerPrivateKey, tokenAddr, chain33Receiver, ethRelayer.x2EthDeployInfo.BridgeBank.Address, bn, ethRelayer.x2EthContracts.BridgeBank, ethRelayer.backend)
return ethtxs.Burn(ownerPrivateKey, tokenAddr, chain33Receiver, ethRelayer.x2EthDeployInfo.BridgeBank.Address, bn, ethRelayer.x2EthContracts.BridgeBank, ethRelayer.clientSpec)
}
func (ethRelayer *Relayer4Ethereum) BurnAsync(ownerPrivateKey, tokenAddr, chain33Receiver, amount string) (string, error) {
bn := big.NewInt(1)
bn, _ = bn.SetString(x2ethTypes.TrimZeroAndDot(amount), 10)
return ethtxs.BurnAsync(ownerPrivateKey, tokenAddr, chain33Receiver, ethRelayer.x2EthDeployInfo.BridgeBank.Address, bn, ethRelayer.x2EthContracts.BridgeBank, ethRelayer.backend)
return ethtxs.BurnAsync(ownerPrivateKey, tokenAddr, chain33Receiver, bn, ethRelayer.x2EthContracts.BridgeBank, ethRelayer.clientSpec)
}
func (ethRelayer *Relayer4Ethereum) TransferToken(tokenAddr, fromKey, toAddr, amount string) (string, error) {
bn := big.NewInt(1)
bn, _ = bn.SetString(x2ethTypes.TrimZeroAndDot(amount), 10)
return ethtxs.TransferToken(tokenAddr, fromKey, toAddr, bn, ethRelayer.backend)
return ethtxs.TransferToken(tokenAddr, fromKey, toAddr, bn, ethRelayer.clientSpec)
}
func (ethRelayer *Relayer4Ethereum) GetDecimals(tokenAddr string) (uint8, error) {
......@@ -274,52 +288,35 @@ func (ethRelayer *Relayer4Ethereum) GetDecimals(tokenAddr string) (uint8, error)
From: common.HexToAddress(tokenAddr),
Context: context.Background(),
}
bridgeToken, _ := generated.NewBridgeToken(common.HexToAddress(tokenAddr), ethRelayer.backend)
bridgeToken, _ := generated.NewBridgeToken(common.HexToAddress(tokenAddr), ethRelayer.clientSpec)
return bridgeToken.Decimals(opts)
}
func (ethRelayer *Relayer4Ethereum) LockEthErc20Asset(ownerPrivateKey, tokenAddr, amount string, chain33Receiver string) (string, error) {
bn := big.NewInt(1)
bn, _ = bn.SetString(x2ethTypes.TrimZeroAndDot(amount), 10)
return ethtxs.LockEthErc20Asset(ownerPrivateKey, tokenAddr, chain33Receiver, bn, ethRelayer.backend, ethRelayer.x2EthContracts.BridgeBank, ethRelayer.x2EthDeployInfo.BridgeBank.Address)
return ethtxs.LockEthErc20Asset(ownerPrivateKey, tokenAddr, chain33Receiver, bn, ethRelayer.clientSpec, ethRelayer.x2EthContracts.BridgeBank, ethRelayer.x2EthDeployInfo.BridgeBank.Address)
}
func (ethRelayer *Relayer4Ethereum) LockEthErc20AssetAsync(ownerPrivateKey, tokenAddr, amount string, chain33Receiver string) (string, error) {
bn := big.NewInt(1)
bn, _ = bn.SetString(x2ethTypes.TrimZeroAndDot(amount), 10)
return ethtxs.LockEthErc20AssetAsync(ownerPrivateKey, tokenAddr, chain33Receiver, bn, ethRelayer.backend, ethRelayer.x2EthContracts.BridgeBank)
return ethtxs.LockEthErc20AssetAsync(ownerPrivateKey, tokenAddr, chain33Receiver, bn, ethRelayer.clientSpec, ethRelayer.x2EthContracts.BridgeBank)
}
func (ethRelayer *Relayer4Ethereum) ShowTxReceipt(hash string) (*types.Receipt, error) {
txhash := common.HexToHash(hash)
client := ethRelayer.backend.(*ethclient.Client)
return client.TransactionReceipt(context.Background(), txhash)
return ethRelayer.clientSpec.TransactionReceipt(context.Background(), txhash)
}
func (ethRelayer *Relayer4Ethereum) proc() {
// Start backend with infura ropsten provider
relayerLog.Info("Relayer4Ethereum proc", "Started Ethereum websocket with provider:", ethRelayer.provider,
"rpcURL2Chain33:", ethRelayer.rpcURL2Chain33)
client, err := ethtxs.SetupWebsocketEthClient(ethRelayer.provider)
if err != nil {
panic(err)
}
ethRelayer.backend = client
ctx := context.Background()
clientChainID, err := client.NetworkID(ctx)
if err != nil {
errinfo := fmt.Sprintf("Failed to get NetworkID due to:%s", err.Error())
panic(errinfo)
}
ethRelayer.clientChainID = clientChainID
//等待用户导入
relayerLog.Info("Please unlock or import private key for Ethereum relayer")
nilAddr := common.Address{}
if nilAddr != ethRelayer.bridgeRegistryAddr {
relayerLog.Info("proc", "Going to recover corresponding solidity contract handler with bridgeRegistryAddr", ethRelayer.bridgeRegistryAddr.String())
ethRelayer.x2EthContracts, ethRelayer.x2EthDeployInfo, err = ethtxs.RecoverContractHandler(client, ethRelayer.bridgeRegistryAddr, ethRelayer.bridgeRegistryAddr)
var err error
ethRelayer.x2EthContracts, ethRelayer.x2EthDeployInfo, err = ethtxs.RecoverContractHandler(ethRelayer.clientSpec, ethRelayer.bridgeRegistryAddr, ethRelayer.bridgeRegistryAddr)
if nil != err {
panic("Failed to recover corresponding solidity contract handler due to:" + err.Error())
}
......@@ -331,6 +328,7 @@ func (ethRelayer *Relayer4Ethereum) proc() {
}
var timer *time.Ticker
ctx := context.Background()
continueFailCount := int32(0)
for range ethRelayer.unlockchan {
relayerLog.Info("Received ethRelayer.unlockchan")
......@@ -360,7 +358,7 @@ latter:
}
func (ethRelayer *Relayer4Ethereum) procNewHeight(ctx context.Context, continueFailCount *int32) {
head, err := ethRelayer.backend.(*ethclient.Client).HeaderByNumber(ctx, nil)
head, err := ethRelayer.clientSpec.HeaderByNumber(ctx, nil)
if nil != err {
*continueFailCount++
if *continueFailCount >= (12 * 5) {
......@@ -449,7 +447,7 @@ func (ethRelayer *Relayer4Ethereum) procBridgeBankLogs(vLog types.Log) {
}()
//检查当前交易是否因为区块回退而导致交易丢失
receipt, err := ethRelayer.backend.(*ethclient.Client).TransactionReceipt(context.Background(), vLog.TxHash)
receipt, err := ethRelayer.clientSpec.TransactionReceipt(context.Background(), vLog.TxHash)
if nil != err {
relayerLog.Error("procBridgeBankLogs", "Failed to get tx receipt with hash", vLog.TxHash.String())
return
......@@ -487,14 +485,14 @@ func (ethRelayer *Relayer4Ethereum) procBridgeBankLogs(vLog types.Log) {
}
func (ethRelayer *Relayer4Ethereum) filterLogEvents() {
deployHeight, _ := ethtxs.GetDeployHeight(ethRelayer.backend.(*ethclient.Client), ethRelayer.x2EthDeployInfo.BridgeRegistry.Address, ethRelayer.x2EthDeployInfo.BridgeRegistry.Address)
deployHeight, _ := ethtxs.GetDeployHeight(ethRelayer.clientSpec, ethRelayer.x2EthDeployInfo.BridgeRegistry.Address, ethRelayer.x2EthDeployInfo.BridgeRegistry.Address)
height4BridgeBankLogAt := int64(ethRelayer.getHeight4BridgeBankLogAt())
if height4BridgeBankLogAt < deployHeight {
height4BridgeBankLogAt = deployHeight
}
header, err := ethRelayer.backend.(*ethclient.Client).HeaderByNumber(context.Background(), nil)
header, err := ethRelayer.clientSpec.HeaderByNumber(context.Background(), nil)
if err != nil {
errinfo := fmt.Sprintf("Failed to get HeaderByNumbers due to:%s", err.Error())
panic(errinfo)
......@@ -543,7 +541,7 @@ func (ethRelayer *Relayer4Ethereum) filterLogEventsProc(logchan chan<- types.Log
}
// Filter by contract and event, write results to logs
logs, err := ethRelayer.backend.FilterLogs(context.Background(), query)
logs, err := ethRelayer.clientSpec.FilterLogs(context.Background(), query)
if err != nil {
errinfo := fmt.Sprintf("Failed to filterLogEvents due to:%s", err.Error())
panic(errinfo)
......@@ -593,7 +591,7 @@ func (ethRelayer *Relayer4Ethereum) subscribeEvent() {
// We will check logs for new events
logs := make(chan types.Log, 10)
// Filter by contract and event, write results to logs
sub, err := ethRelayer.backend.SubscribeFilterLogs(context.Background(), query, logs)
sub, err := ethRelayer.clientSpec.SubscribeFilterLogs(context.Background(), query, logs)
if err != nil {
errinfo := fmt.Sprintf("Failed to SubscribeFilterLogs due to:%s", err.Error())
panic(errinfo)
......@@ -613,7 +611,7 @@ func (ethRelayer *Relayer4Ethereum) IsValidatorActive(addr string) (bool, error)
}
func (ethRelayer *Relayer4Ethereum) ShowOperator() (string, error) {
operator, err := ethtxs.GetOperator(ethRelayer.backend.(*ethclient.Client), ethRelayer.ethValidator, ethRelayer.bridgeBankAddr)
operator, err := ethtxs.GetOperator(ethRelayer.clientSpec, ethRelayer.ethValidator, ethRelayer.bridgeBankAddr)
if nil != err {
return "", err
}
......@@ -651,7 +649,7 @@ func (ethRelayer *Relayer4Ethereum) handleLogLockEvent(clientChainID *big.Int, c
From: common.HexToAddress(event.Token.String()),
Context: context.Background(),
}
bridgeToken, _ := generated.NewBridgeToken(common.HexToAddress(event.Token.String()), ethRelayer.backend)
bridgeToken, _ := generated.NewBridgeToken(common.HexToAddress(event.Token.String()), ethRelayer.clientSpec)
decimal, err = bridgeToken.Decimals(opts)
if err != nil {
......@@ -706,7 +704,7 @@ func (ethRelayer *Relayer4Ethereum) handleLogBurnEvent(clientChainID *big.Int, c
From: common.HexToAddress(event.Token.String()),
Context: context.Background(),
}
bridgeToken, _ := generated.NewBridgeToken(common.HexToAddress(event.Token.String()), ethRelayer.backend)
bridgeToken, _ := generated.NewBridgeToken(common.HexToAddress(event.Token.String()), ethRelayer.clientSpec)
decimal, err = bridgeToken.Decimals(opts)
if err != nil {
......
......@@ -2,21 +2,24 @@ package ethereum
import (
"context"
"encoding/hex"
"flag"
"fmt"
"github.com/33cn/chain33/client/mocks"
"github.com/33cn/chain33/util/testnode"
"github.com/stretchr/testify/mock"
"math/big"
"os"
"testing"
"time"
"github.com/33cn/chain33/client/mocks"
dbm "github.com/33cn/chain33/common/db"
_ "github.com/33cn/chain33/system"
chain33Types "github.com/33cn/chain33/types"
"github.com/33cn/chain33/util/testnode"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/test/setup"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethinterface"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethtxs"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/events"
ebTypes "github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/types"
relayerTypes "github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/types"
tml "github.com/BurntSushi/toml"
......@@ -24,17 +27,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
)
......@@ -43,16 +36,13 @@ var (
chain33PrivateKeyStr = "0xd627968e445f2a41c92173225791bae1ba42126ae96c32f28f97ff8f226e5c68"
chain33AccountAddr = "1GTxrmuWiXavhcvsaH5w9whgVxUrWsUMdV"
passphrase = "123456hzj"
testEthKey, _ = crypto.HexToECDSA("8656d2bc732a8a816a461ba5e2d8aac7c7f85c26a813df30d5327210465eb230")
testEthAddr = crypto.PubkeyToAddress(testEthKey.PublicKey)
testBalance = big.NewInt(2e18)
chainTestCfg = chain33Types.NewChain33Config(chain33Types.GetDefaultCfgstring())
)
type suiteEthRelayer struct {
suite.Suite
ethRelayer *Relayer4Ethereum
sim *backends.SimulatedBackend
sim *ethinterface.SimExtend
x2EthContracts *ethtxs.X2EthContracts
x2EthDeployInfo *ethtxs.X2EthDeployInfo
para *ethtxs.DeployPara
......@@ -60,6 +50,25 @@ type suiteEthRelayer struct {
}
func TestRunSuiteX2Ethereum(t *testing.T) {
var tx chain33Types.Transaction
var ret chain33Types.Reply
ret.IsOk = true
mockapi := &mocks.QueueProtocolAPI{}
// 这里对需要mock的方法打桩,Close是必须的,其它方法根据需要
mockapi.On("Close").Return()
mockapi.On("CreateTransaction", mock.Anything).Return(&tx, nil)
mockapi.On("SendTx", mock.Anything).Return(&ret, nil)
mockapi.On("SendTransaction", mock.Anything).Return(&ret, nil)
mockapi.On("GetConfig", mock.Anything).Return(chainTestCfg, nil)
mock33 := testnode.New("", mockapi)
defer mock33.Close()
rpcCfg := mock33.GetCfg().RPC
// 这里必须设置监听端口,默认的是无效值
rpcCfg.JrpcBindAddr = "127.0.0.1:8801"
mock33.GetRPC().Listen()
log := new(suiteEthRelayer)
suite.Run(t, log)
}
......@@ -94,13 +103,29 @@ func (r *suiteEthRelayer) Test_1_ImportPrivateKey() {
r.Equal(validators.Chain33Validator, chain33AccountAddr)
}
func (r *suiteEthRelayer) Test_2_IsValidatorActive() {
r.ethRelayer.x2EthContracts = r.x2EthContracts
r.ethRelayer.x2EthDeployInfo = r.x2EthDeployInfo
is, err := r.ethRelayer.IsValidatorActive("0x92c8b16afd6d423652559c6e266cbe1c29bfd84f")
r.Equal(is, true)
r.NoError(err)
is, err = r.ethRelayer.IsValidatorActive("0x0C05bA5c230fDaA503b53702aF1962e08D0C60BF")
r.Equal(is, false)
r.NoError(err)
is, err = r.ethRelayer.IsValidatorActive("123")
r.Error(err)
}
func (r *suiteEthRelayer) Test_2_LockEth() {
ctx := context.Background()
bridgeBankBalance, err := r.sim.BalanceAt(ctx, r.x2EthDeployInfo.BridgeBank.Address, nil)
r.NoError(err)
r.Equal(bridgeBankBalance.Int64(), int64(0))
userOneAuth, err := ethtxs.PrepareAuth(r.backend, r.para.ValidatorPriKey[0], r.para.InitValidators[0])
userOneAuth, err := ethtxs.PrepareAuth(r.sim, r.para.ValidatorPriKey[0], r.para.InitValidators[0])
r.NoError(err)
//lock 50 eth
......@@ -117,64 +142,57 @@ func (r *suiteEthRelayer) Test_2_LockEth() {
time.Sleep(time.Duration(r.ethRelayer.fetchHeightPeriodMs) * time.Millisecond)
query := ethereum.FilterQuery{
Addresses: []common.Address{r.ethRelayer.bridgeBankAddr},
}
logs, err := r.sim.FilterLogs(context.Background(), query)
r.NoError(err)
for _, logv := range logs {
r.ethRelayer.storeBridgeBankLogs(logv, true)
for i := 0; i < 11; i++ {
r.sim.Commit()
}
time.Sleep(time.Duration(r.ethRelayer.fetchHeightPeriodMs) * time.Millisecond)
}
func (r *suiteEthRelayer) Test_3_RestorePrivateKeys() {
// 错误的密码 也不报错
err := r.ethRelayer.RestorePrivateKeys(passphrase)
go func() {
for range r.ethRelayer.unlockchan {
}
}()
temp := r.ethRelayer.privateKey4Chain33
err := r.ethRelayer.RestorePrivateKeys("123")
r.NotEqual(hex.EncodeToString(temp.Bytes()), hex.EncodeToString(r.ethRelayer.privateKey4Chain33.Bytes()))
r.NoError(err)
err = r.ethRelayer.StoreAccountWithNewPassphase(passphrase, passphrase)
err = r.ethRelayer.RestorePrivateKeys(passphrase)
r.Equal(hex.EncodeToString(temp.Bytes()), hex.EncodeToString(r.ethRelayer.privateKey4Chain33.Bytes()))
r.NoError(err)
time.Sleep(1 * time.Second)
err = r.ethRelayer.StoreAccountWithNewPassphase("new123", passphrase)
r.NoError(err)
err = r.ethRelayer.RestorePrivateKeys("new123")
r.Equal(hex.EncodeToString(temp.Bytes()), hex.EncodeToString(r.ethRelayer.privateKey4Chain33.Bytes()))
r.NoError(err)
time.Sleep(10 * time.Second)
}
func (r *suiteEthRelayer) Test_4_handleLogLockEvent() {
var tx chain33Types.Transaction
var ret chain33Types.Reply
ret.IsOk = true
func (r *suiteEthRelayer) Test_2_1_Show() {
{
time.Sleep(1 * time.Second)
mockapi := &mocks.QueueProtocolAPI{}
// 这里对需要mock的方法打桩,Close是必须的,其它方法根据需要
mockapi.On("Close").Return()
mockapi.On("CreateTransaction", mock.Anything).Return(&tx, nil)
mockapi.On("SendTx", mock.Anything).Return(&ret, nil)
mockapi.On("SendTransaction", mock.Anything).Return(&ret, nil)
mockapi.On("GetConfig", mock.Anything).Return(chainTestCfg, nil)
addr, err := r.ethRelayer.CreateBridgeToken("bty")
r.NoError(err)
fmt.Println("++++++", addr, err)
r.sim.Commit()
mock33 := testnode.New("", mockapi)
defer mock33.Close()
rpcCfg := mock33.GetCfg().RPC
// 这里必须设置监听端口,默认的是无效值
rpcCfg.JrpcBindAddr = "127.0.0.1:8801"
mock33.GetRPC().Listen()
tokenAddr, err := r.ethRelayer.CreateERC20Token("testc")
fmt.Println("++++++", tokenAddr, err)
//r.Error(err)
query := ethereum.FilterQuery{
Addresses: []common.Address{r.ethRelayer.bridgeBankAddr},
}
logs, err := r.sim.FilterLogs(context.Background(), query)
r.NoError(err)
addr, err = r.ethRelayer.MintERC20Token(tokenAddr, r.ethRelayer.ethValidator.String(), "20000000000000")
fmt.Println("++++++", addr, err)
//r.Error(err)
for _, logv := range logs {
eventName := events.LogLock.String()
err := r.ethRelayer.handleLogLockEvent(r.ethRelayer.clientChainID, r.ethRelayer.bridgeBankAbi, eventName, logv)
r.NoError(err)
return
}
}
func (r *suiteEthRelayer) Test_5_Show() {
_, err := r.ethRelayer.DeployContrcts()
r.Error(err)
addr, err := r.ethRelayer.ShowBridgeBankAddr()
r.NoError(err)
......@@ -184,16 +202,16 @@ func (r *suiteEthRelayer) Test_5_Show() {
r.NoError(err)
r.Equal(addr, r.x2EthDeployInfo.BridgeRegistry.Address.String())
balance, err := r.ethRelayer.GetBalance("", testEthAddr.String())
r.NoError(err)
r.Equal(balance, "2000000000000000000")
_, err = r.ethRelayer.GetBalance("0x0000000000000000000000000000000000000000", testEthAddr.String())
r.Error(err)
//balance, err := r.ethRelayer.GetBalance("", testEthAddr.String())
//r.NoError(err)
//r.Equal(balance, "2000000000000000000")
//
//_, err = r.ethRelayer.GetBalance("0x0000000000000000000000000000000000000000", testEthAddr.String())
//r.Error(err)
balance, err = r.ethRelayer.ShowLockStatics("")
r.NoError(err)
r.Equal(balance, "50")
//balance, err := r.ethRelayer.ShowLockStatics("")
//r.NoError(err)
//r.Equal(balance, "50")
_, err = r.ethRelayer.ShowDepositStatics("")
r.Error(err)
......@@ -206,23 +224,14 @@ func (r *suiteEthRelayer) Test_5_Show() {
r.NoError(err)
r.Equal(ret, false)
//addr, err = r.ethRelayer.CreateBridgeToken("bty")
//r.NoError(err)
//tokenAddr, err := r.ethRelayer.CreateERC20Token("testc")
//r.Error(err)
//addr, err = r.ethRelayer.MintERC20Token(tokenAddr, r.ethRelayer.ethValidator.String(), "20000000000000")
//_, err = r.ethRelayer.ShowOperator()
//r.Error(err)
_, err = r.ethRelayer.ShowOperator()
r.Error(err)
tx1 := r.ethRelayer.QueryTxhashRelay2Eth()
r.Empty(tx1)
tx2 := r.ethRelayer.QueryTxhashRelay2Chain33()
r.Empty(tx2)
//
//tx1 := r.ethRelayer.QueryTxhashRelay2Eth()
//r.Empty(tx1)
//
//tx2 := r.ethRelayer.QueryTxhashRelay2Chain33()
//r.Empty(tx2)
}
func (r *suiteEthRelayer) newEthRelayer() *Relayer4Ethereum {
......@@ -256,81 +265,38 @@ func (r *suiteEthRelayer) newEthRelayer() *Relayer4Ethereum {
relayer.deployInfo.InitPowers = append(relayer.deployInfo.InitPowers, v.Int64())
}
_ = relayer.setBridgeRegistryAddr(cfg.BridgeRegistry)
registrAddrInDB, err := relayer.getBridgeRegistryAddr()
//如果输入的registry地址非空,且和数据库保存地址不一致,则直接使用输入注册地址
if cfg.BridgeRegistry != "" && nil == err && registrAddrInDB != cfg.BridgeRegistry {
relayerLog.Error("StartEthereumRelayer", "BridgeRegistry is setted already with value", registrAddrInDB,
"but now setting to", cfg.BridgeRegistry)
_ = relayer.setBridgeRegistryAddr(cfg.BridgeRegistry)
} else if cfg.BridgeRegistry == "" && registrAddrInDB != "" {
//输入地址为空,且数据库中保存地址不为空,则直接使用数据库中的地址
relayer.bridgeRegistryAddr = common.HexToAddress(registrAddrInDB)
}
r.NoError(err)
r.Equal(registrAddrInDB, cfg.BridgeRegistry)
relayer.eventLogIndex = relayer.getLastBridgeBankProcessedHeight()
relayer.initBridgeBankTx()
go r.proc()
return relayer
}
relayer.clientSpec = r.sim
relayer.clientChainID = big.NewInt(1)
func (r *suiteEthRelayer) proc() {
backend, _ := r.newTestBackend()
client, _ := backend.Attach()
defer backend.Stop()
defer client.Close()
r.ethRelayer.clientChainID = new(big.Int)
r.ethRelayer.backend = ethclient.NewClient(client)
//等待用户导入
relayerLog.Info("Please unlock or import private key for Ethereum relayer")
nilAddr := common.Address{}
if nilAddr != r.ethRelayer.bridgeRegistryAddr {
r.ethRelayer.x2EthContracts = r.x2EthContracts
r.ethRelayer.x2EthDeployInfo = r.x2EthDeployInfo
relayerLog.Info("^-^ ^-^ Succeed to recover corresponding solidity contract handler")
if nil != r.ethRelayer.recoverDeployPara() {
panic("Failed to recoverDeployPara")
}
r.ethRelayer.unlockchan <- start
}
ctx := context.Background()
var timer *time.Ticker
//var err error
continueFailCount := int32(0)
for range r.ethRelayer.unlockchan {
relayerLog.Info("Received ethRelayer.unlockchan")
if nil != r.ethRelayer.privateKey4Chain33 && nilAddr != r.ethRelayer.bridgeRegistryAddr {
relayerLog.Info("Ethereum relayer starts to run...")
r.ethRelayer.prePareSubscribeEvent()
//向bridgeBank订阅事件
r.ethRelayer.subscribeEvent()
r.ethRelayer.filterLogEvents()
relayerLog.Info("Ethereum relayer starts to process online log event...")
timer = time.NewTicker(time.Duration(r.ethRelayer.fetchHeightPeriodMs) * time.Millisecond)
goto latter
}
}
latter:
for {
select {
case <-timer.C:
r.ethRelayer.procNewHeight(ctx, &continueFailCount)
case err := <-r.ethRelayer.bridgeBankSub.Err():
panic("bridgeBankSub" + err.Error())
case vLog := <-r.ethRelayer.bridgeBankLog:
r.ethRelayer.storeBridgeBankLogs(vLog, true)
}
}
go relayer.proc()
return relayer
}
func (r *suiteEthRelayer) deployContracts() {
// 0x8AFDADFC88a1087c9A1D6c0F5Dd04634b87F303a
var deployerPrivateKey = "8656d2bc732a8a816a461ba5e2d8aac7c7f85c26a813df30d5327210465eb230"
// 0x92C8b16aFD6d423652559C6E266cBE1c29Bfd84f
var ethValidatorAddrKeyA = "3fa21584ae2e4fd74db9b58e2386f5481607dfa4d7ba0617aaa7858e5025dc1e"
var ethValidatorAddrKeyB = "a5f3063552f4483cfc20ac4f40f45b798791379862219de9e915c64722c1d400"
var ethValidatorAddrKeyC = "bbf5e65539e9af0eb0cfac30bad475111054b09c11d668fc0731d54ea777471e"
var ethValidatorAddrKeyD = "c9fa31d7984edf81b8ef3b40c761f1847f6fcd5711ab2462da97dc458f1f896b"
ethValidatorAddrKeys := make([]string, 0)
ethValidatorAddrKeys = append(ethValidatorAddrKeys, ethValidatorAddrKeyA)
ethValidatorAddrKeys = append(ethValidatorAddrKeys, ethValidatorAddrKeyB)
ethValidatorAddrKeys = append(ethValidatorAddrKeys, ethValidatorAddrKeyC)
ethValidatorAddrKeys = append(ethValidatorAddrKeys, ethValidatorAddrKeyD)
ctx := context.Background()
r.backend, r.para = setup.PrepareTestEnv()
r.sim = r.backend.(*backends.SimulatedBackend)
r.backend, r.para = setup.PrepareTestEnvironment(deployerPrivateKey, ethValidatorAddrKeys)
r.sim = new(ethinterface.SimExtend)
r.sim.SimulatedBackend = r.backend.(*backends.SimulatedBackend)
balance, _ := r.sim.BalanceAt(ctx, r.para.Deployer, nil)
r.Equal(balance.Int64(), int64(10000000000*10000))
......@@ -343,7 +309,7 @@ func (r *suiteEthRelayer) deployContracts() {
_, err := r.sim.EstimateGas(ctx, callMsg)
r.NoError(err)
r.x2EthContracts, r.x2EthDeployInfo, err = ethtxs.DeployAndInit(r.backend, r.para)
r.x2EthContracts, r.x2EthDeployInfo, err = ethtxs.DeployAndInit(r.sim, r.para)
r.NoError(err)
r.sim.Commit()
}
......@@ -356,55 +322,3 @@ func initCfg(path string) *relayerTypes.RelayerConfig {
}
return &cfg
}
func (r *suiteEthRelayer) newTestBackend() (*node.Node, []*types.Block) {
// Generate test chain.
genesis, blocks := r.generateTestChain()
// Start Ethereum service.
var ethservice *eth.Ethereum
n, err := node.New(&node.Config{})
err = n.Register(func(ctx *node.ServiceContext) (node.Service, error) {
config := &eth.Config{Genesis: genesis}
config.Ethash.PowMode = ethash.ModeFake
ethservice, err = eth.New(ctx, config)
return ethservice, err
})
assert.NoError(r.T(), err)
// Import the test chain.
if err := n.Start(); err != nil {
r.T().Fatalf("can't start test node: %v", err)
}
if _, err := ethservice.BlockChain().InsertChain(blocks[1:]); err != nil {
r.T().Fatalf("can't import test blocks: %v", err)
}
return n, blocks
}
func (r *suiteEthRelayer) generateTestChain() (*core.Genesis, []*types.Block) {
db := rawdb.NewMemoryDatabase()
config := params.AllEthashProtocolChanges
alloc := make(core.GenesisAlloc)
alloc[testEthAddr] = core.GenesisAccount{Balance: testBalance}
alloc[r.para.Operator] = core.GenesisAccount{Balance: testBalance}
for _, v := range r.para.InitValidators {
alloc[v] = core.GenesisAccount{Balance: testBalance}
}
genesis := &core.Genesis{
Config: config,
//Alloc: core.GenesisAlloc{testEthAddr: {Balance: testBalance}},
Alloc: alloc,
ExtraData: []byte("test genesis"),
Timestamp: 9000,
}
generate := func(i int, g *core.BlockGen) {
g.OffsetTime(1)
g.SetExtra([]byte("test"))
}
gblock := genesis.ToBlock(db)
engine := ethash.NewFaker()
blocks, _ := core.GenerateChain(config, gblock, engine, db, 20, generate)
blocks = append([]*types.Block{gblock}, blocks...)
return genesis, blocks
}
package ethereum
import (
"context"
"encoding/hex"
"fmt"
"math/big"
"testing"
"time"
dbm "github.com/33cn/chain33/common/db"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/generated"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethcontract/test/setup"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/ethtxs"
"github.com/33cn/plugin/plugin/dapp/x2ethereum/ebrelayer/events"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/stretchr/testify/suite"
)
type suiteEthRelayerSim struct {
suite.Suite
ethRelayer *Relayer4Ethereum
sim *backends.SimulatedBackend
x2EthContracts *ethtxs.X2EthContracts
x2EthDeployInfo *ethtxs.X2EthDeployInfo
para *ethtxs.DeployPara
backend bind.ContractBackend
}
func TestRunSuiteX2EthereumSim(t *testing.T) {
log := new(suiteEthRelayerSim)
suite.Run(t, log)
}
func (r *suiteEthRelayerSim) SetupSuite() {
r.deploySimContracts()
r.ethRelayer = r.newSimEthRelayer()
}
func (r *suiteEthRelayerSim) TestSim_1_ImportPrivateKey() {
validators, err := r.ethRelayer.GetValidatorAddr()
r.Error(err)
r.Empty(validators)
_, _, err = r.ethRelayer.NewAccount("123")
r.NoError(err)
err = r.ethRelayer.ImportChain33PrivateKey(passphrase, chain33PrivateKeyStr)
r.NoError(err)
privateKey, addr, err := r.ethRelayer.GetAccount("123")
r.NoError(err)
r.NotEqual(privateKey, chain33PrivateKeyStr)
privateKey, addr, err = r.ethRelayer.GetAccount(passphrase)
r.NoError(err)
r.Equal(privateKey, chain33PrivateKeyStr)
r.Equal(addr, chain33AccountAddr)
validators, err = r.ethRelayer.GetValidatorAddr()
r.NoError(err)
r.Equal(validators.Chain33Validator, chain33AccountAddr)
}
func (r *suiteEthRelayerSim) TestSim_2_RestorePrivateKeys() {
go func() {
for range r.ethRelayer.unlockchan {
}
}()
temp := r.ethRelayer.privateKey4Chain33
err := r.ethRelayer.RestorePrivateKeys("123")
r.NotEqual(hex.EncodeToString(temp.Bytes()), hex.EncodeToString(r.ethRelayer.privateKey4Chain33.Bytes()))
r.NoError(err)
err = r.ethRelayer.RestorePrivateKeys(passphrase)
r.Equal(hex.EncodeToString(temp.Bytes()), hex.EncodeToString(r.ethRelayer.privateKey4Chain33.Bytes()))
r.NoError(err)
err = r.ethRelayer.StoreAccountWithNewPassphase("new123", passphrase)
r.NoError(err)
err = r.ethRelayer.RestorePrivateKeys("new123")
r.Equal(hex.EncodeToString(temp.Bytes()), hex.EncodeToString(r.ethRelayer.privateKey4Chain33.Bytes()))
r.NoError(err)
}
func (r *suiteEthRelayerSim) TestSim_3_IsValidatorActive() {
// 有时候会不通过
is, err := r.ethRelayer.IsValidatorActive("0x92c8b16afd6d423652559c6e266cbe1c29bfd84f")
r.Equal(is, true)
r.NoError(err)
is, err = r.ethRelayer.IsValidatorActive("0x0C05bA5c230fDaA503b53702aF1962e08D0C60BF")
r.Equal(is, false)
r.NoError(err)
is, err = r.ethRelayer.IsValidatorActive("123")
r.Error(err)
}
func (r *suiteEthRelayerSim) Test_4_DeployContrcts() {
_, err := r.ethRelayer.DeployContrcts()
r.Error(err)
}
func (r *suiteEthRelayerSim) newSimEthRelayer() *Relayer4Ethereum {
cfg := initCfg(*configPath)
cfg.SyncTxConfig.Chain33Host = "http://127.0.0.1:8801"
cfg.BridgeRegistry = r.x2EthDeployInfo.BridgeRegistry.Address.String()
cfg.SyncTxConfig.PushBind = "127.0.0.1:60000"
cfg.SyncTxConfig.FetchHeightPeriodMs = 50
cfg.SyncTxConfig.Dbdriver = "memdb"
cfg.SyncTxConfig.DbPath = "datadirSim"
db := dbm.NewDB("relayer_db_service_sim", cfg.SyncTxConfig.Dbdriver, cfg.SyncTxConfig.DbPath, cfg.SyncTxConfig.DbCache)
relayer := &Relayer4Ethereum{
provider: cfg.EthProvider,
db: db,
unlockchan: make(chan int, 2),
rpcURL2Chain33: cfg.SyncTxConfig.Chain33Host,
bridgeRegistryAddr: r.x2EthDeployInfo.BridgeRegistry.Address,
deployInfo: cfg.Deploy,
maturityDegree: cfg.EthMaturityDegree,
fetchHeightPeriodMs: cfg.EthBlockFetchPeriod,
}
registrAddrInDB, err := relayer.getBridgeRegistryAddr()
//如果输入的registry地址非空,且和数据库保存地址不一致,则直接使用输入注册地址
if cfg.BridgeRegistry != "" && nil == err && registrAddrInDB != cfg.BridgeRegistry {
relayerLog.Error("StartEthereumRelayer", "BridgeRegistry is setted already with value", registrAddrInDB, "but now setting to", cfg.BridgeRegistry)
_ = relayer.setBridgeRegistryAddr(cfg.BridgeRegistry)
} else if cfg.BridgeRegistry == "" && registrAddrInDB != "" {
//输入地址为空,且数据库中保存地址不为空,则直接使用数据库中的地址
relayer.bridgeRegistryAddr = common.HexToAddress(registrAddrInDB)
}
relayer.eventLogIndex = relayer.getLastBridgeBankProcessedHeight()
relayer.initBridgeBankTx()
relayer.x2EthContracts = r.x2EthContracts
relayer.x2EthDeployInfo = r.x2EthDeployInfo
go r.procSim()
return relayer
}
func (r *suiteEthRelayerSim) procSim() {
r.ethRelayer.backend = r.sim
r.ethRelayer.clientChainID = new(big.Int)
//等待用户导入
relayerLog.Info("Please unlock or import private key for Ethereum relayer")
nilAddr := common.Address{}
if nilAddr != r.ethRelayer.bridgeRegistryAddr {
relayerLog.Info("^-^ ^-^ Succeed to recover corresponding solidity contract handler")
if nil != r.ethRelayer.recoverDeployPara() {
panic("Failed to recoverDeployPara")
}
r.ethRelayer.unlockchan <- start
}
ctx := context.Background()
var timer *time.Ticker
//var err error
continueFailCount := int32(0)
for range r.ethRelayer.unlockchan {
relayerLog.Info("Received ethRelayer.unlockchan")
if nil != r.ethRelayer.privateKey4Chain33 && nilAddr != r.ethRelayer.bridgeRegistryAddr {
relayerLog.Info("Ethereum relayer starts to run...")
r.ethRelayer.prePareSubscribeEvent()
//向bridgeBank订阅事件
r.ethRelayer.subscribeEvent()
r.filterLogEvents()
relayerLog.Info("Ethereum relayer starts to process online log event...")
timer = time.NewTicker(time.Duration(r.ethRelayer.fetchHeightPeriodMs) * time.Millisecond)
goto latter
}
}
latter:
for {
select {
case <-timer.C:
r.procNewHeight(ctx, &continueFailCount)
case err := <-r.ethRelayer.bridgeBankSub.Err():
panic("bridgeBankSub" + err.Error())
case vLog := <-r.ethRelayer.bridgeBankLog:
r.ethRelayer.storeBridgeBankLogs(vLog, true)
}
}
}
func (r *suiteEthRelayerSim) deploySimContracts() {
// 0x8AFDADFC88a1087c9A1D6c0F5Dd04634b87F303a
var deployerPrivateKey = "8656d2bc732a8a816a461ba5e2d8aac7c7f85c26a813df30d5327210465eb230"
// 0x92C8b16aFD6d423652559C6E266cBE1c29Bfd84f
var ethValidatorAddrKeyA = "3fa21584ae2e4fd74db9b58e2386f5481607dfa4d7ba0617aaa7858e5025dc1e"
var ethValidatorAddrKeyB = "a5f3063552f4483cfc20ac4f40f45b798791379862219de9e915c64722c1d400"
var ethValidatorAddrKeyC = "bbf5e65539e9af0eb0cfac30bad475111054b09c11d668fc0731d54ea777471e"
var ethValidatorAddrKeyD = "c9fa31d7984edf81b8ef3b40c761f1847f6fcd5711ab2462da97dc458f1f896b"
ethValidatorAddrKeys := make([]string, 0)
ethValidatorAddrKeys = append(ethValidatorAddrKeys, ethValidatorAddrKeyA)
ethValidatorAddrKeys = append(ethValidatorAddrKeys, ethValidatorAddrKeyB)
ethValidatorAddrKeys = append(ethValidatorAddrKeys, ethValidatorAddrKeyC)
ethValidatorAddrKeys = append(ethValidatorAddrKeys, ethValidatorAddrKeyD)
ctx := context.Background()
r.backend, r.para = setup.PrepareTestEnvironment(deployerPrivateKey, ethValidatorAddrKeys)
r.sim = r.backend.(*backends.SimulatedBackend)
balance, _ := r.sim.BalanceAt(ctx, r.para.Deployer, nil)
r.Equal(balance.Int64(), int64(10000000000*10000))
callMsg := ethereum.CallMsg{
From: r.para.Deployer,
Data: common.FromHex(generated.BridgeBankBin),
}
_, err := r.sim.EstimateGas(ctx, callMsg)
r.NoError(err)
r.x2EthContracts, r.x2EthDeployInfo, err = ethtxs.DeployAndInit(r.backend, r.para)
r.NoError(err)
r.sim.Commit()
}
func (r *suiteEthRelayerSim) filterLogEvents() {
deployHeight := int64(0)
height4BridgeBankLogAt := int64(r.ethRelayer.getHeight4BridgeBankLogAt())
if height4BridgeBankLogAt < deployHeight {
height4BridgeBankLogAt = deployHeight
}
curHeight := int64(0)
relayerLog.Info("filterLogEvents", "curHeight:", curHeight)
bridgeBankSig := make(map[string]bool)
bridgeBankSig[r.ethRelayer.bridgeBankEventLockSig] = true
bridgeBankSig[r.ethRelayer.bridgeBankEventBurnSig] = true
bridgeBankLog := make(chan types.Log)
done := make(chan int)
go r.ethRelayer.filterLogEventsProc(bridgeBankLog, done, "bridgeBank", curHeight, height4BridgeBankLogAt, r.ethRelayer.bridgeBankAddr, bridgeBankSig)
for {
select {
case vLog := <-bridgeBankLog:
r.ethRelayer.storeBridgeBankLogs(vLog, true)
case vLog := <-r.ethRelayer.bridgeBankLog:
//因为此处是同步保存信息,防止未同步完成出现panic时,直接将其设置为最新高度,中间出现部分信息不同步的情况
r.ethRelayer.storeBridgeBankLogs(vLog, false)
case <-done:
relayerLog.Info("Finshed offline logs processed")
return
}
}
}
func (r *suiteEthRelayerSim) procNewHeight(ctx context.Context, continueFailCount *int32) {
*continueFailCount = 0
currentHeight := uint64(20)
relayerLog.Info("procNewHeight", "currentHeight", currentHeight)
//一次最大只获取10个logEvent进行处理
fetchCnt := int32(10)
for r.ethRelayer.eventLogIndex.Height+uint64(r.ethRelayer.maturityDegree)+1 <= currentHeight {
logs, err := r.ethRelayer.getNextValidEthTxEventLogs(r.ethRelayer.eventLogIndex.Height, r.ethRelayer.eventLogIndex.Index, fetchCnt)
if nil != err {
relayerLog.Error("Failed to get ethereum height", "getNextValidEthTxEventLogs err", err.Error())
return
}
for i, vLog := range logs {
if vLog.BlockNumber+uint64(r.ethRelayer.maturityDegree)+1 > currentHeight {
logs = logs[:i]
break
}
//r.ethRelayer.procBridgeBankLogs(*vLog)
if r.ethRelayer.checkTxProcessed(vLog.TxHash.Bytes()) {
relayerLog.Info("procBridgeBankLogs", "Tx has been already Processed with hash:", vLog.TxHash.Hex(),
"height", vLog.BlockNumber, "index", vLog.Index)
return
}
defer func() {
if err := r.ethRelayer.setTxProcessed(vLog.TxHash.Bytes()); nil != err {
panic(err.Error())
}
}()
//lock,用于捕捉 (ETH/ERC20----->chain33) 跨链转移
if vLog.Topics[0].Hex() == r.ethRelayer.bridgeBankEventLockSig {
eventName := events.LogLock.String()
relayerLog.Info("Relayer4Ethereum proc", "Going to process", eventName,
"Block number:", vLog.BlockNumber, "Tx hash:", vLog.TxHash.Hex())
err := r.ethRelayer.handleLogLockEvent(r.ethRelayer.clientChainID, r.ethRelayer.bridgeBankAbi, eventName, *vLog)
if err != nil {
errinfo := fmt.Sprintf("Failed to handleLogLockEvent due to:%s", err.Error())
relayerLog.Info("Relayer4Ethereum procBridgeBankLogs", "errinfo", errinfo)
panic(errinfo)
}
} else if vLog.Topics[0].Hex() == r.ethRelayer.bridgeBankEventBurnSig {
//burn,用于捕捉 (chain33 token----->chain33) 实现chain33资产withdraw操作,之后在chain33上实现unlock操作
eventName := events.LogChain33TokenBurn.String()
relayerLog.Info("Relayer4Ethereum proc", "Going to process", eventName,
"Block number:", vLog.BlockNumber, "Tx hash:", vLog.TxHash.Hex())
err := r.ethRelayer.handleLogBurnEvent(r.ethRelayer.clientChainID, r.ethRelayer.bridgeBankAbi, eventName, *vLog)
if err != nil {
errinfo := fmt.Sprintf("Failed to handleLogBurnEvent due to:%s", err.Error())
relayerLog.Info("Relayer4Ethereum procBridgeBankLogs", "errinfo", errinfo)
panic(errinfo)
}
}
}
cnt := int32(len(logs))
if len(logs) > 0 {
//firstHeight := logs[0].BlockNumber
lastHeight := logs[cnt-1].BlockNumber
index := logs[cnt-1].TxIndex
//获取的数量小于批量获取数量,则认为直接
r.ethRelayer.setBridgeBankProcessedHeight(lastHeight, uint32(index))
r.ethRelayer.eventLogIndex.Height = lastHeight
r.ethRelayer.eventLogIndex.Index = uint32(index)
}
//当前需要处理的event数量已经少于10个,直接返回
if cnt < fetchCnt {
return
}
}
}
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