Skip to content

Commit

Permalink
Merge pull request #134 from ElrondNetwork/fix-relayers-stuck-in-set-…
Browse files Browse the repository at this point in the history
…status

Fix stuck relayers
  • Loading branch information
iulianpascalau authored Nov 18, 2021
2 parents 141d557 + 706e0e9 commit f6df1ad
Show file tree
Hide file tree
Showing 27 changed files with 368 additions and 76 deletions.
18 changes: 7 additions & 11 deletions bridge/elrond/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,15 @@ func checkGasMapValues(gasMap bridge.ElrondGasMapConfig) error {
}

// GetPending returns the pending batch
func (c *client) GetPending(_ context.Context) *bridge.Batch {
func (c *client) GetPending(_ context.Context) (*bridge.Batch, error) {
c.log.Info("Elrond: Getting pending batch")
responseData, err := c.getCurrentBatch()
if err != nil {
c.log.Error("Elrond: Failed to get the current batch", "error", err.Error())
return nil
return nil, err
}

if emptyResponse(responseData) {
return nil
return nil, nil
}

addrPkConv, _ := pubkeyConverter.NewBech32PubkeyConverter(32, c.log)
Expand All @@ -143,13 +142,11 @@ func (c *client) GetPending(_ context.Context) *bridge.Batch {
amount := new(big.Int).SetBytes(responseData[i+idxAmount])
blockNonce, errParse := parseIntFromByteSlice(responseData[i])
if errParse != nil {
c.log.Error("Elrond: parse error", "error", errParse.Error())
return nil
return nil, fmt.Errorf("%w in client.GetPending, parseIntFromByteSlice(responseData[i])", err)
}
depositNonce, errParse := parseIntFromByteSlice(responseData[i+1])
if errParse != nil {
c.log.Error("Elrond: parse error", "error", errParse.Error())
return nil
return nil, fmt.Errorf("%w in client.GetPending, parseIntFromByteSlice(responseData[i+1])", err)
}

tx := &bridge.DepositTransaction{
Expand All @@ -169,14 +166,13 @@ func (c *client) GetPending(_ context.Context) *bridge.Batch {

batchId, err := parseIntFromByteSlice(responseData[0])
if err != nil {
c.log.Error("Elrond: parse error", "error", err.Error())
return nil
return nil, fmt.Errorf("%w in client.GetPending, parseIntFromByteSlice(responseData[0])", err)
}

return &bridge.Batch{
Id: bridge.NewBatchId(batchId),
Transactions: transactions,
}
}, nil
}

func parseIntFromByteSlice(buff []byte) (int64, error) {
Expand Down
9 changes: 6 additions & 3 deletions bridge/elrond/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ func TestGetPending(t *testing.T) {
}
c, _ := buildTestClient(proxy)

actual := c.GetPending(context.TODO())
actual, err := c.GetPending(context.TODO())
assert.Nil(t, err)
tx1 := &bridge.DepositTransaction{
To: "0x264eeffe37aa569bec16a951c51ba25a98e07dab",
DisplayableTo: "0x264eeffe37aa569bec16a951c51ba25a98e07dab",
Expand Down Expand Up @@ -195,9 +196,10 @@ func TestGetPending(t *testing.T) {
}

c, _ := buildTestClient(proxy)
actual := c.GetPending(context.TODO())
actual, err := c.GetPending(context.TODO())

assert.Nil(t, actual)
assert.Nil(t, err)
})
t.Run("where there is no pending transaction it will return nil", func(t *testing.T) {
proxy := &testProxy{
Expand All @@ -207,9 +209,10 @@ func TestGetPending(t *testing.T) {
}

c, _ := buildTestClient(proxy)
actual := c.GetPending(context.TODO())
actual, err := c.GetPending(context.TODO())

assert.Nil(t, actual)
assert.Nil(t, err)
})
}

Expand Down
10 changes: 5 additions & 5 deletions bridge/eth/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ func NewClient(args ArgsClient) (*client, error) {
if err != nil {
return nil, err
}
privateKey, err := crypto.HexToECDSA(string(privateKeyBytes))
privateKeyString := core.TrimWhiteSpaceCharacters(string(privateKeyBytes))
privateKey, err := crypto.HexToECDSA(privateKeyString)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -162,12 +163,11 @@ func (c *client) retrieveAllCurrentErc20Balances() {
}

// GetPending returns the pending batch in the Ethereum contract
func (c *client) GetPending(ctx context.Context) *bridge.Batch {
func (c *client) GetPending(ctx context.Context) (*bridge.Batch, error) {
c.log.Info("ETH: Getting pending batch")
batch, err := c.clientWrapper.GetNextPendingBatch(ctx)
if err != nil {
c.log.Error(err.Error())
return nil
return nil, err
}

var result *bridge.Batch
Expand All @@ -192,7 +192,7 @@ func (c *client) GetPending(ctx context.Context) *bridge.Batch {
}
}

return result
return result, nil
}

// ProposeSetStatus will propose the status of an executed batch of transactions
Expand Down
9 changes: 5 additions & 4 deletions bridge/eth/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var (
}
)

const TestPrivateKey = "60f3849d7c8d93dfce1947d17c34be3e4ea974e74e15ce877f0df34d7192efab"
const TestPrivateKey = " 60f3849d7c8d93dfce1947d17c34be3e4ea974e74e15ce877f0df34d7192efab\n\t "
const GasLimit = uint64(400000)

func TestGetPending(t *testing.T) {
Expand Down Expand Up @@ -98,9 +98,10 @@ func TestGetPending(t *testing.T) {
}
c.addressConverter, _ = pubkeyConverter.NewBech32PubkeyConverter(32, c.log)

got := c.GetPending(context.TODO())
got, err := c.GetPending(context.TODO())

assert.Equal(t, tt.expectedBatch, got)
assert.Nil(t, err)
})
}
}
Expand Down Expand Up @@ -201,7 +202,7 @@ func TestSign(t *testing.T) {
},
}

sk, err := crypto.HexToECDSA(TestPrivateKey)
sk, err := crypto.HexToECDSA(core.TrimWhiteSpaceCharacters(TestPrivateKey))
require.Nil(t, err)

pk := sk.Public()
Expand Down Expand Up @@ -623,7 +624,7 @@ func TestClient_GetTransactionsStatuses(t *testing.T) {
func privateKey(t *testing.T) *ecdsa.PrivateKey {
t.Helper()

sk, err := crypto.HexToECDSA(TestPrivateKey)
sk, err := crypto.HexToECDSA(core.TrimWhiteSpaceCharacters(TestPrivateKey))
if err != nil {
t.Fatal(err)
return nil
Expand Down
2 changes: 1 addition & 1 deletion bridge/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ type QuorumProvider interface {

// Bridge defines the operations available for a validator operating on a bridge between 2 chains
type Bridge interface {
GetPending(context.Context) *Batch
GetPending(context.Context) (*Batch, error)
ProposeSetStatus(context.Context, *Batch)
ProposeTransfer(context.Context, *Batch) (string, error)
WasProposedTransfer(context.Context, *Batch) bool
Expand Down
10 changes: 5 additions & 5 deletions cmd/bridge/config/config_ethereum.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[Eth]
NetworkAddress = "http://127.0.0.1:8545" # a network address
BridgeAddress = "3009d97FfeD62E57d444e552A9eDF9Ee6Bc8644c" # the eth address for the bridge contract
SafeContractAddress = "A6504Cc508889bbDBd4B748aFf6EA6b5D0d2684c"
BridgeAddress = "eB6859d7Fc1A47E2630dB83E244829Cb4A814888" # the eth address for the bridge contract
SafeContractAddress = "3A06278d31FA803320fB76Fc3C754AAEef842729"
PrivateKeyFile = "config/ethereum.sk" # the path to the file containing the relayer eth private key
GasLimit = 500000
ERC20Contracts = ["d1135C0307CEB01FD4728db8e5B8D38fbf984F9a", "214E935c87454e70B415510fBDf8528c1A1363D5"]
ERC20Contracts = ["ba3b1bF0b572aA6555718A12Af7CC63e0D103A26"]
[Eth.GasStation]
Enabled = true
URL = "https://ethgasstation.info/api/ethgasAPI.json?" # gas station URL. Suggestion to provide the api-key here
Expand All @@ -15,8 +15,8 @@
GasPriceSelector = "safeLow" # selector used to provide the gas price

[Elrond]
NetworkAddress = "https://devnet-gateway.elrond.com" # the network address
BridgeAddress = "erd1qqqqqqqqqqqqqpgqzyuaqg3dl7rqlkudrsnm5ek0j3a97qevd8sszj0glf" # the elrond address for the bridge contract
NetworkAddress = "https://testnet-gateway.elrond.com" # the network address
BridgeAddress = "erd1qqqqqqqqqqqqqpgqgewxhtrgjv4jzhgs9y0q9pnkdkkmqlnxd8sszjrhzv" # the elrond address for the bridge contract
PrivateKeyFile = "config/elrond.pem" # the path to the pem file containing the relayer elrond wallet
IntervalToResendTxsInSeconds = 60 # the time in seconds between nonce reads
[Elrond.GasMap]
Expand Down
2 changes: 1 addition & 1 deletion cmd/bridge/config/ethereum.sk
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9bb971db41e3815a669a71c3f1bcb24e0b81f21e04bf11faa7a34b9b40e7cfb1
9bb971db41e3815a669a71c3f1bcb24e0b81f21e04bf11faa7a34b9b40e7cfb1
9 changes: 9 additions & 0 deletions core/converters.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package core

import "strings"

// TODO - move this as a method in AddressHandler

// ConvertFromByteSliceToArray will convert the provided buffer to its [32]byte representation
Expand All @@ -9,3 +11,10 @@ func ConvertFromByteSliceToArray(buff []byte) [32]byte {

return result
}

// TrimWhiteSpaceCharacters will remove the white spaces from the input string
func TrimWhiteSpaceCharacters(input string) string {
cutset := "\n\t "

return strings.Trim(input, cutset)
}
18 changes: 18 additions & 0 deletions core/converters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,21 @@ func TestConvertFromByteSliceToArray(t *testing.T) {
result := ConvertFromByteSliceToArray(buff)
assert.Equal(t, buff, result[:])
}

func TestTrimWhiteSpaceCharacters(t *testing.T) {
t.Parallel()

data := "aaII139HSAh32q782!$#*$(nc"

input := " " + data
assert.Equal(t, data, TrimWhiteSpaceCharacters(input))

input = "\t " + data
assert.Equal(t, data, TrimWhiteSpaceCharacters(input))

input = "\t " + data + "\n"
assert.Equal(t, data, TrimWhiteSpaceCharacters(input))

input = "\t\n " + data + "\n\n\n\n\t"
assert.Equal(t, data, TrimWhiteSpaceCharacters(input))
}
21 changes: 19 additions & 2 deletions ethToElrond/bridgeExecutors/ethElrondBridgeExecutor.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,27 @@ func (executor *ethElrondBridgeExecutor) setExecutionMessageInStatusHandler(leve
}

// GetPendingBatch will fetch the pending batch from the source bridge
func (executor *ethElrondBridgeExecutor) GetPendingBatch(ctx context.Context) {
func (executor *ethElrondBridgeExecutor) GetPendingBatch(ctx context.Context) error {
executor.statusHandler.SetStringMetric(core.MetricLastError, "")

executor.pendingBatch = executor.sourceBridge.GetPending(ctx)
pendingBatch, err := executor.sourceBridge.GetPending(ctx)
if err != nil {
return err
}

executor.pendingBatch = pendingBatch

return nil
}

// IsPendingBatchReady returns true if a pending batch is ready
func (executor *ethElrondBridgeExecutor) IsPendingBatchReady(ctx context.Context) (bool, error) {
pendingBatch, err := executor.sourceBridge.GetPending(ctx)
if err != nil {
return false, err
}

return pendingBatch != nil, nil
}

// ProposeTransferOnDestination will propose the transfer for the existing pending batch on the destination bridge
Expand Down
Loading

0 comments on commit f6df1ad

Please sign in to comment.