Skip to content

Commit

Permalink
Merge pull request #230 from ElrondNetwork/merge-master-feat-dynamic-gas
Browse files Browse the repository at this point in the history
Merge master feat dynamic gas
  • Loading branch information
iulianpascalau authored Apr 12, 2022
2 parents 310220d + 256d287 commit 0449661
Show file tree
Hide file tree
Showing 32 changed files with 860 additions and 39 deletions.
32 changes: 22 additions & 10 deletions bridges/ethElrond/bridgeExecutor.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ const minRetries = 1
// ArgsBridgeExecutor is the arguments DTO struct used in both bridges
type ArgsBridgeExecutor struct {
Log logger.Logger
TopologyProvider TopologyProvider
ElrondClient ElrondClient
EthereumClient EthereumClient
TopologyProvider TopologyProvider
TimeForWaitOnEthereum time.Duration
StatusHandler core.StatusHandler
SignaturesHolder SignaturesHolder
BatchValidator clients.BatchValidator
MaxQuorumRetriesOnEthereum uint64
MaxQuorumRetriesOnElrond uint64
MaxRestriesOnWasProposed uint64
Expand All @@ -37,18 +38,20 @@ type bridgeExecutor struct {
topologyProvider TopologyProvider
elrondClient ElrondClient
ethereumClient EthereumClient
batch *clients.TransferBatch
actionID uint64
msgHash common.Hash
quorumRetriesOnEthereum uint64
maxQuorumRetriesOnEthereum uint64
quorumRetriesOnElrond uint64
maxQuorumRetriesOnElrond uint64
retriesOnWasProposed uint64
maxRetriesOnWasProposed uint64
timeForWaitOnEthereum time.Duration
statusHandler core.StatusHandler
sigsHolder SignaturesHolder
batchValidator clients.BatchValidator
maxQuorumRetriesOnEthereum uint64
maxQuorumRetriesOnElrond uint64
maxRetriesOnWasProposed uint64

batch *clients.TransferBatch
actionID uint64
msgHash common.Hash
quorumRetriesOnEthereum uint64
quorumRetriesOnElrond uint64
retriesOnWasProposed uint64
}

// NewBridgeExecutor creates a bridge executor, which can be used for both half-bridges
Expand Down Expand Up @@ -84,6 +87,9 @@ func checkArgs(args ArgsBridgeExecutor) error {
if check.IfNil(args.SignaturesHolder) {
return ErrNilSignaturesHolder
}
if check.IfNil(args.BatchValidator) {
return ErrNilBatchValidator
}
if args.MaxQuorumRetriesOnEthereum < minRetries {
return fmt.Errorf("%w for args.MaxQuorumRetriesOnEthereum, got: %d, minimum: %d",
clients.ErrInvalidValue, args.MaxQuorumRetriesOnEthereum, minRetries)
Expand All @@ -108,6 +114,7 @@ func createBridgeExecutor(args ArgsBridgeExecutor) *bridgeExecutor {
statusHandler: args.StatusHandler,
timeForWaitOnEthereum: args.TimeForWaitOnEthereum,
sigsHolder: args.SignaturesHolder,
batchValidator: args.BatchValidator,
maxQuorumRetriesOnEthereum: args.MaxQuorumRetriesOnEthereum,
maxQuorumRetriesOnElrond: args.MaxQuorumRetriesOnElrond,
maxRetriesOnWasProposed: args.MaxRestriesOnWasProposed,
Expand Down Expand Up @@ -514,6 +521,11 @@ func (executor *bridgeExecutor) ClearStoredP2PSignaturesForEthereum() {
executor.sigsHolder.ClearStoredSignatures()
}

// ValidateBatch returns true if the given batch is validated on microservice side
func (executor *bridgeExecutor) ValidateBatch(ctx context.Context, batch *clients.TransferBatch) (bool, error) {
return executor.batchValidator.ValidateBatch(ctx, batch)
}

// IsInterfaceNil returns true if there is no value under the interface
func (executor *bridgeExecutor) IsInterfaceNil() bool {
return executor == nil
Expand Down
1 change: 1 addition & 0 deletions bridges/ethElrond/bridgeExecutor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func createMockExecutorArgs() ArgsBridgeExecutor {
StatusHandler: testsCommon.NewStatusHandlerMock("test"),
TimeForWaitOnEthereum: time.Second,
SignaturesHolder: &testsCommon.SignaturesHolderStub{},
BatchValidator: &testsCommon.BatchValidatorStub{},
MaxQuorumRetriesOnEthereum: minRetries,
MaxQuorumRetriesOnElrond: minRetries,
MaxRestriesOnWasProposed: minRetries,
Expand Down
3 changes: 3 additions & 0 deletions bridges/ethElrond/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ var ErrBatchNotFound = errors.New("batch not found")

// ErrNilSignaturesHolder signals that a nil signatures holder was provided
var ErrNilSignaturesHolder = errors.New("nil signatures holder")

// ErrNilBatchValidator signals that a nil batch validator was provided
var ErrNilBatchValidator = errors.New("nil batch validator")
3 changes: 3 additions & 0 deletions bridges/ethElrond/steps/elrondToEth/semiIntegrated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ func createMockBridge(args argsBridgeStub) (*bridgeTests.BridgeExecutorStub, *er
stub.ProcessMaxQuorumRetriesOnEthereumCalled = func() bool {
return args.maxRetriesReachedElrondHandler()
}
stub.ValidateBatchCalled = func(ctx context.Context, batch *clients.TransferBatch) (bool, error) {
return true, nil
}

return stub, errHandler
}
Expand Down
13 changes: 13 additions & 0 deletions bridges/ethElrond/steps/elrondToEth/step01GetPending.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package elrondToEth

import (
"context"
"encoding/json"

"github.com/ElrondNetwork/elrond-eth-bridge/bridges/ethElrond/steps"
"github.com/ElrondNetwork/elrond-eth-bridge/core"
Expand Down Expand Up @@ -33,6 +34,18 @@ func (step *getPendingStep) Execute(ctx context.Context) core.StepIdentifier {
return step.Identifier()
}

isValid, err := step.bridge.ValidateBatch(ctx, batch)
if err != nil {
body, _ := json.Marshal(batch)
step.bridge.PrintInfo(logger.LogError, "error validating Elrond batch", "error", err, "batch", string(body))
return step.Identifier()
}

if !isValid {
step.bridge.PrintInfo(logger.LogError, "batch not valid "+batch.String())
return step.Identifier()
}

step.bridge.PrintInfo(logger.LogInfo, "fetched new batch from Elrond "+batch.String())

wasPerformed, err := step.bridge.WasTransferPerformedOnEthereum(ctx)
Expand Down
35 changes: 35 additions & 0 deletions bridges/ethElrond/steps/elrondToEth/step01GetPending_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,38 @@ func TestExecute_GetPending(t *testing.T) {
assert.Equal(t, expectedStepIdentifier, stepIdentifier)
})

t.Run("error on ValidateBatch", func(t *testing.T) {
t.Parallel()
bridgeStub := createStubExecutorGetPending()
bridgeStub.ValidateBatchCalled = func(ctx context.Context, batch *clients.TransferBatch) (bool, error) {
return false, expectedError
}

step := getPendingStep{
bridge: bridgeStub,
}

expectedStepIdentifier := step.Identifier()
stepIdentifier := step.Execute(context.Background())
assert.Equal(t, expectedStepIdentifier, stepIdentifier)
})

t.Run("batch not validated on ValidateBatch", func(t *testing.T) {
t.Parallel()
bridgeStub := createStubExecutorGetPending()
bridgeStub.ValidateBatchCalled = func(ctx context.Context, batch *clients.TransferBatch) (bool, error) {
return false, nil
}

step := getPendingStep{
bridge: bridgeStub,
}

expectedStepIdentifier := step.Identifier()
stepIdentifier := step.Execute(context.Background())
assert.Equal(t, expectedStepIdentifier, stepIdentifier)
})

t.Run("error on WasTransferPerformedOnEthereum", func(t *testing.T) {
t.Parallel()
bridgeStub := createStubExecutorGetPending()
Expand Down Expand Up @@ -130,5 +162,8 @@ func createStubExecutorGetPending() *bridgeTests.BridgeExecutorStub {
stub.StoreBatchFromElrondCalled = func(batch *clients.TransferBatch) error {
return nil
}
stub.ValidateBatchCalled = func(ctx context.Context, batch *clients.TransferBatch) (bool, error) {
return true, nil
}
return stub
}
12 changes: 12 additions & 0 deletions bridges/ethElrond/steps/ethToElrond/semiIntegrated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const (
getAndStoreBatchFromEthereum = "GetAndStoreBatchFromEthereum"
getLastExecutedEthBatchIDFromElrond = "GetLastExecutedEthBatchIDFromElrond"
verifyLastDepositNonceExecutedOnEthereumBatch = "VerifyLastDepositNonceExecutedOnEthereumBatch"
validateBatch = "ValidateBatch"
wasTransferProposedOnElrond = "WasTransferProposedOnElrond"
wasActionSignedOnElrond = "WasActionSignedOnElrond"
signActionOnElrond = "SignActionOnElrond"
Expand Down Expand Up @@ -52,6 +53,7 @@ type argsBridgeStub struct {
isQuorumReachedHandler func() bool
wasActionIDPerformedHandler func() bool
maxRetriesReachedHandler func() bool
validateBatchHandler func() bool
}

func createMockBridge(args argsBridgeStub) (*bridgeTests.BridgeExecutorStub, *errorHandler) {
Expand Down Expand Up @@ -147,6 +149,12 @@ func createMockBridge(args argsBridgeStub) (*bridgeTests.BridgeExecutorStub, *er
stub.ProcessMaxQuorumRetriesOnElrondCalled = func() bool {
return args.maxRetriesReachedHandler()
}
stub.ValidateBatchCalled = func(ctx context.Context, batch *clients.TransferBatch) (bool, error) {
if args.failingStep == validateBatch {
return false, errHandler.storeAndReturnError(expectedErr)
}
return args.validateBatchHandler(), errHandler.storeAndReturnError(nil)
}

return stub, errHandler
}
Expand All @@ -169,6 +177,7 @@ func TestHappyCaseWhenLeader(t *testing.T) {
myTurnHandler: trueHandler,
isQuorumReachedHandler: trueHandler,
wasActionIDPerformedHandler: trueHandler,
validateBatchHandler: trueHandler,
maxRetriesReachedHandler: falseHandler,
wasProposedTransferSignedHandler: falseHandler,
wasTransferProposedHandler: falseHandler,
Expand Down Expand Up @@ -210,6 +219,7 @@ func TestHappyCaseWhenLeaderAndActionIdNotPerformed(t *testing.T) {
args := argsBridgeStub{
myTurnHandler: trueHandler,
isQuorumReachedHandler: trueHandler,
validateBatchHandler: trueHandler,
wasActionIDPerformedHandler: func() bool {
numCalled++
return numCalled > 1
Expand Down Expand Up @@ -254,6 +264,7 @@ func TestOneStepErrors_ShouldReturnToPendingBatch(t *testing.T) {
getAndStoreBatchFromEthereum,
getLastExecutedEthBatchIDFromElrond,
verifyLastDepositNonceExecutedOnEthereumBatch,
validateBatch,
wasTransferProposedOnElrond,
proposeTransferOnElrond,
wasTransferProposedOnElrond,
Expand All @@ -274,6 +285,7 @@ func testErrorFlow(t *testing.T, stepThatErrors core.StepIdentifier) {
failingStep: string(stepThatErrors),
myTurnHandler: trueHandler,
isQuorumReachedHandler: trueHandler,
validateBatchHandler: trueHandler,
wasActionIDPerformedHandler: func() bool {
numCalled++
return numCalled > 1
Expand Down
13 changes: 13 additions & 0 deletions bridges/ethElrond/steps/ethToElrond/step01GetPending.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ethToElrond

import (
"context"
"encoding/json"

"github.com/ElrondNetwork/elrond-eth-bridge/bridges/ethElrond/steps"
"github.com/ElrondNetwork/elrond-eth-bridge/core"
Expand Down Expand Up @@ -33,6 +34,18 @@ func (step *getPendingStep) Execute(ctx context.Context) core.StepIdentifier {
return step.Identifier()
}

isValid, err := step.bridge.ValidateBatch(ctx, batch)
if err != nil {
body, _ := json.Marshal(batch)
step.bridge.PrintInfo(logger.LogError, "error validating Ethereum batch", "error", err, "batch", body)
return step.Identifier()
}

if !isValid {
step.bridge.PrintInfo(logger.LogError, "batch not valid "+batch.String())
return step.Identifier()
}

step.bridge.PrintInfo(logger.LogInfo, "fetched new batch from Ethereum "+batch.String())

err = step.bridge.VerifyLastDepositNonceExecutedOnEthereumBatch(ctx)
Expand Down
56 changes: 56 additions & 0 deletions bridges/ethElrond/steps/ethToElrond/step01GetPending_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,56 @@ func TestExecuteGetPending(t *testing.T) {
assert.Equal(t, expectedStepIdentifier, stepIdentifier)
})

t.Run("error on ValidateBatch", func(t *testing.T) {
t.Parallel()
bridgeStub := createStubExecutor()
bridgeStub.GetLastExecutedEthBatchIDFromElrondCalled = func(ctx context.Context) (uint64, error) {
return 1122, nil
}
bridgeStub.GetAndStoreBatchFromEthereumCalled = func(ctx context.Context, nonce uint64) error {
return nil
}
bridgeStub.GetStoredBatchCalled = func() *clients.TransferBatch {
return testBatch
}
bridgeStub.ValidateBatchCalled = func(ctx context.Context, batch *clients.TransferBatch) (bool, error) {
return false, expectedError
}

step := getPendingStep{
bridge: bridgeStub,
}

expectedStepIdentifier := step.Identifier()
stepIdentifier := step.Execute(context.Background())
assert.Equal(t, expectedStepIdentifier, stepIdentifier)
})

t.Run("batch not validated on ValidateBatch", func(t *testing.T) {
t.Parallel()
bridgeStub := createStubExecutor()
bridgeStub.GetLastExecutedEthBatchIDFromElrondCalled = func(ctx context.Context) (uint64, error) {
return 1122, nil
}
bridgeStub.GetAndStoreBatchFromEthereumCalled = func(ctx context.Context, nonce uint64) error {
return nil
}
bridgeStub.GetStoredBatchCalled = func() *clients.TransferBatch {
return testBatch
}
bridgeStub.ValidateBatchCalled = func(ctx context.Context, batch *clients.TransferBatch) (bool, error) {
return false, nil
}

step := getPendingStep{
bridge: bridgeStub,
}

expectedStepIdentifier := step.Identifier()
stepIdentifier := step.Execute(context.Background())
assert.Equal(t, expectedStepIdentifier, stepIdentifier)
})

t.Run("error on VerifyLastDepositNonceExecutedOnEthereumBatch", func(t *testing.T) {
t.Parallel()
bridgeStub := createStubExecutor()
Expand All @@ -89,6 +139,9 @@ func TestExecuteGetPending(t *testing.T) {
bridgeStub.GetStoredBatchCalled = func() *clients.TransferBatch {
return testBatch
}
bridgeStub.ValidateBatchCalled = func(ctx context.Context, batch *clients.TransferBatch) (bool, error) {
return true, nil
}
bridgeStub.VerifyLastDepositNonceExecutedOnEthereumBatchCalled = func(ctx context.Context) error {
return expectedError
}
Expand Down Expand Up @@ -117,6 +170,9 @@ func TestExecuteGetPending(t *testing.T) {
bridgeStub.VerifyLastDepositNonceExecutedOnEthereumBatchCalled = func(ctx context.Context) error {
return nil
}
bridgeStub.ValidateBatchCalled = func(ctx context.Context, batch *clients.TransferBatch) (bool, error) {
return true, nil
}

step := getPendingStep{
bridge: bridgeStub,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,28 @@ func TestExecuteSignProposedTransferStep(t *testing.T) {
assert.Equal(t, expectedStepIdentifier, stepIdentifier)
})

t.Run("error on WasActionSignedOnElrond", func(t *testing.T) {
t.Parallel()
bridgeStub := createStubExecutor()
bridgeStub.GetStoredBatchCalled = func() *clients.TransferBatch {
return testBatch
}
bridgeStub.WasActionSignedOnElrondCalled = func(ctx context.Context) (bool, error) {
return false, expectedError
}
bridgeStub.GetAndStoreActionIDForProposeTransferOnElrondCalled = func(ctx context.Context) (uint64, error) {
return ethElrond.InvalidActionID, nil
}

step := signProposedTransferStep{
bridge: bridgeStub,
}

expectedStepIdentifier := core.StepIdentifier(GettingPendingBatchFromEthereum)
stepIdentifier := step.Execute(context.Background())
assert.Equal(t, expectedStepIdentifier, stepIdentifier)
})

t.Run("should work - transfer was already signed", func(t *testing.T) {
t.Parallel()
bridgeStub := createStubExecutor()
Expand Down
2 changes: 2 additions & 0 deletions bridges/ethElrond/steps/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,7 @@ type Executor interface {
ResetRetriesCountOnEthereum()
ClearStoredP2PSignaturesForEthereum()

ValidateBatch(ctx context.Context, batch *clients.TransferBatch) (bool, error)

IsInterfaceNil() bool
}
Loading

0 comments on commit 0449661

Please sign in to comment.