Try to reconnect ethereum RPC
This commit is contained in:
parent
5c2b9f763e
commit
c409a350c9
@ -72,11 +72,8 @@ func NewEthereumRPC(config json.RawMessage, pushHandler func(bchain.Notification
|
|||||||
if c.BlockAddressesToKeep < 100 {
|
if c.BlockAddressesToKeep < 100 {
|
||||||
c.BlockAddressesToKeep = 100
|
c.BlockAddressesToKeep = 100
|
||||||
}
|
}
|
||||||
rc, err := rpc.Dial(c.RPCURL)
|
|
||||||
if err != nil {
|
rc, ec, err := openRPC(c.RPCURL)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ec := ethclient.NewClient(rc)
|
|
||||||
|
|
||||||
s := &EthereumRPC{
|
s := &EthereumRPC{
|
||||||
BaseChain: &bchain.BaseChain{},
|
BaseChain: &bchain.BaseChain{},
|
||||||
@ -133,6 +130,15 @@ func NewEthereumRPC(config json.RawMessage, pushHandler func(bchain.Notification
|
|||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func openRPC(url string) (*rpc.Client, *ethclient.Client, error) {
|
||||||
|
rc, err := rpc.Dial(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
ec := ethclient.NewClient(rc)
|
||||||
|
return rc, ec, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize initializes ethereum rpc interface
|
// Initialize initializes ethereum rpc interface
|
||||||
func (b *EthereumRPC) Initialize() error {
|
func (b *EthereumRPC) Initialize() error {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
|
||||||
@ -187,6 +193,16 @@ func (b *EthereumRPC) InitializeMempool(addrDescForOutpoint bchain.AddrDescForOu
|
|||||||
|
|
||||||
b.Mempool.OnNewTxAddr = onNewTxAddr
|
b.Mempool.OnNewTxAddr = onNewTxAddr
|
||||||
|
|
||||||
|
if err = b.subscribeEvents(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
b.mempoolInitialized = true
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *EthereumRPC) subscribeEvents() error {
|
||||||
if b.isETC {
|
if b.isETC {
|
||||||
glog.Info(b.ChainConfig.CoinName, " does not support subscription to newHeads")
|
glog.Info(b.ChainConfig.CoinName, " does not support subscription to newHeads")
|
||||||
} else {
|
} else {
|
||||||
@ -224,8 +240,6 @@ func (b *EthereumRPC) InitializeMempool(addrDescForOutpoint bchain.AddrDescForOu
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b.mempoolInitialized = true
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,7 +260,7 @@ func (b *EthereumRPC) subscribe(f func() (*rpc.ClientSubscription, error)) error
|
|||||||
}
|
}
|
||||||
glog.Error("Subscription error ", e)
|
glog.Error("Subscription error ", e)
|
||||||
timer := time.NewTimer(time.Second * 2)
|
timer := time.NewTimer(time.Second * 2)
|
||||||
// try in 1 second interval to resubscribe
|
// try in 2 second interval to resubscribe
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case e = <-s.Err():
|
case e = <-s.Err():
|
||||||
@ -260,7 +274,7 @@ func (b *EthereumRPC) subscribe(f func() (*rpc.ClientSubscription, error)) error
|
|||||||
s = ns
|
s = ns
|
||||||
continue Loop
|
continue Loop
|
||||||
}
|
}
|
||||||
glog.Error("Resubscribe error ", e)
|
glog.Error("Resubscribe error ", err)
|
||||||
timer.Reset(time.Second * 2)
|
timer.Reset(time.Second * 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -269,8 +283,7 @@ func (b *EthereumRPC) subscribe(f func() (*rpc.ClientSubscription, error)) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown cleans up rpc interface to ethereum
|
func (b *EthereumRPC) closeRPC() {
|
||||||
func (b *EthereumRPC) Shutdown(ctx context.Context) error {
|
|
||||||
if b.newBlockSubscription != nil {
|
if b.newBlockSubscription != nil {
|
||||||
b.newBlockSubscription.Unsubscribe()
|
b.newBlockSubscription.Unsubscribe()
|
||||||
}
|
}
|
||||||
@ -280,6 +293,23 @@ func (b *EthereumRPC) Shutdown(ctx context.Context) error {
|
|||||||
if b.rpc != nil {
|
if b.rpc != nil {
|
||||||
b.rpc.Close()
|
b.rpc.Close()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *EthereumRPC) reconnectRPC() error {
|
||||||
|
glog.Info("Reconnecting RPC")
|
||||||
|
b.closeRPC()
|
||||||
|
rc, ec, err := openRPC(b.ChainConfig.RPCURL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.rpc = rc
|
||||||
|
b.client = ec
|
||||||
|
return b.subscribeEvents()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shutdown cleans up rpc interface to ethereum
|
||||||
|
func (b *EthereumRPC) Shutdown(ctx context.Context) error {
|
||||||
|
b.closeRPC()
|
||||||
close(b.chanNewBlock)
|
close(b.chanNewBlock)
|
||||||
glog.Info("rpc: shutdown")
|
glog.Info("rpc: shutdown")
|
||||||
return nil
|
return nil
|
||||||
@ -339,6 +369,14 @@ func (b *EthereumRPC) getBestHeader() (*ethtypes.Header, error) {
|
|||||||
b.bestHeader = nil
|
b.bestHeader = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if the best header was not updated for 15 minutes, there could be a subscription problem, reconnect RPC
|
||||||
|
if b.bestHeaderTime.Add(15 * time.Minute).Before(time.Now()) {
|
||||||
|
err := b.reconnectRPC()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
b.bestHeader = nil
|
||||||
|
}
|
||||||
if b.bestHeader == nil {
|
if b.bestHeader == nil {
|
||||||
var err error
|
var err error
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), b.timeout)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user