Skip to content

Commit

Permalink
BridgeTestSuite WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
vsuharnikov committed Oct 30, 2024
1 parent c9eb84c commit 0b7e497
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.wavesplatform.api

import cats.syntax.either.*
import cats.syntax.option.*
import com.wavesplatform.account.Address
import com.wavesplatform.api.LoggingBackend.{LoggingOptions, LoggingOptionsTag}
Expand Down Expand Up @@ -56,7 +57,10 @@ class NodeHttpApi(apiUri: Uri, backend: SttpBackend[Identity, ?]) extends HasRet
def broadcastAndWait(txn: Transaction): TransactionInfoResponse = {
implicit val loggingOptions: LoggingOptions = LoggingOptions(logResponseBody = false)
log.debug(s"${loggingOptions.prefix} broadcastAndWait($txn)")
broadcastImpl(txn)(loggingOptions.copy(logRequestBody = false))
broadcastImpl(txn)(loggingOptions.copy(logRequestBody = false)).left.foreach { e =>
throw new RuntimeException(s"Can't broadcast ${txn.id()}: code=${e.error}, message=${e.message}")
}

retryWithAttempts { attempt =>
val subsequentLoggingOptions = loggingOptions.copy(logRequest = attempt == 1)
transactionInfoImpl(TransactionId(txn.id()))(subsequentLoggingOptions) match {
Expand All @@ -66,16 +70,23 @@ class NodeHttpApi(apiUri: Uri, backend: SttpBackend[Identity, ?]) extends HasRet
}
}

protected def broadcastImpl[T <: Transaction](txn: T)(implicit loggingOptions: LoggingOptions = LoggingOptions()): T =
def broadcast(txn: Transaction): Either[ErrorResponse, Transaction] = {
implicit val loggingOptions: LoggingOptions = LoggingOptions()
log.debug(s"${loggingOptions.prefix} broadcast($txn)")
broadcastImpl(txn)
}

protected def broadcastImpl[T <: Transaction](txn: T)(implicit loggingOptions: LoggingOptions = LoggingOptions()): Either[ErrorResponse, T] =
basicRequest
.post(uri"$apiUri/transactions/broadcast")
.body(txn: Transaction)
.response(asJson[BroadcastResponse])
.response(asJsonEither[ErrorResponse, BroadcastResponse])
.tag(LoggingOptionsTag, loggingOptions)
.send(backend)
.body match {
case Left(e) => throw new RuntimeException(e)
case _ => txn
case Left(HttpError(e, _)) => e.asLeft
case Left(e) => throw new RuntimeException(e)
case _ => txn.asRight
}

protected def transactionInfoImpl(id: TransactionId)(implicit loggingOptions: LoggingOptions = LoggingOptions()): Option[TransactionInfoResponse] =
Expand Down Expand Up @@ -174,4 +185,9 @@ object NodeHttpApi {
object ConnectedPeersResponse {
implicit val connectedPeersResponseFormat: OFormat[ConnectedPeersResponse] = Json.format[ConnectedPeersResponse]
}

case class ErrorResponse(error: Int, message: String)
object ErrorResponse {
implicit val errorResponseFormat: OFormat[ErrorResponse] = Json.format[ErrorResponse]
}
}
61 changes: 42 additions & 19 deletions consensus-client-it/src/test/scala/units/BridgeTestSuite.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package units

import com.wavesplatform.account.KeyPair
import com.wavesplatform.api.NodeHttpApi.ErrorResponse
import com.wavesplatform.api.http.ApiError.ScriptExecutionError
import com.wavesplatform.common.utils.EitherExt2
import com.wavesplatform.settings.Constants
import com.wavesplatform.utils.EthEncoding
Expand All @@ -21,19 +24,11 @@ class BridgeTestSuite extends TwoNodesTestSuite {
val ethAmount = Convert.toWei(userAmount.toString, Convert.Unit.ETHER).toBigIntegerExact
val sendTxnReceipt = ec1.elBridge.sendNativeAndWait(elSender, clRecipient.toAddress, ethAmount)

// TODO check the balance of contract wasn't changed

val blockHash = BlockHash(sendTxnReceipt.getBlockHash)
log.info(s"Block with transaction: $blockHash")

log.info(s"Wait block $blockHash on contract")
val blockConfirmationHeight = retry {
waves1.chainContract.getBlock(blockHash).get.height
}

log.info(s"Wait block $blockHash finalization")
retry {
blockConfirmationHeight <= waves1.chainContract.getFinalizedBlock.height
}

val rawLogsInBlock = ec1.web3j
.ethGetLogs(new EthFilter(blockHash, ec1.elBridge.address.hex).addSingleTopic(Bridge.ElSentNativeEventTopic))
.send()
Expand All @@ -59,22 +54,50 @@ class BridgeTestSuite extends TwoNodesTestSuite {
val transferProofs = Bridge.mkTransferProofs(transferEvents, sendTxnLogIndex).reverse
val wavesAmount = userAmount * Constants.UnitsInWave

log.info(s"Wait block $blockHash on contract")
val blockConfirmationHeight = retry {
waves1.chainContract.getBlock(blockHash).get.height
}

val currFinalizedHeight = waves1.chainContract.getFinalizedBlock.height
if (currFinalizedHeight >= blockConfirmationHeight)
fail(s"Can't continue the test: the block ($blockConfirmationHeight) is already finalized ($currFinalizedHeight)")

log.info("Trying to withdraw before finalization")
def withdraw(sender: KeyPair = clRecipient) = chainContract.withdraw(
sender = sender,
blockHash = BlockHash(sendTxnReceipt.getBlockHash),
merkleProof = transferProofs,
transferIndexInBlock = sendTxnLogIndex,
amount = wavesAmount
)

val attempt1 = waves1.api.broadcast(withdraw()).left.value
attempt1.error shouldBe ScriptExecutionError.Id
attempt1.message should include("is not finalized")

log.info(s"Wait block $blockHash ($blockConfirmationHeight) finalization")
retry {
val currFinalizedHeight = waves1.chainContract.getFinalizedBlock.height
log.info(s"Current finalized height: $currFinalizedHeight")
if (currFinalizedHeight < blockConfirmationHeight) fail("Not yet finalized")
}

// TODO: try to send from other person
withClue("Try ") {
val attempt2 = waves1.api.broadcast(withdraw(clRichAccount2)).left.value
attempt2.error shouldBe ScriptExecutionError.Id
attempt2.message should include("Check your withdraw arguments")
}

def balance: Long = waves1.api.balance(clRecipient.toAddress, waves1.chainContract.token)
val balanceBefore = balance

log.info(
s"Broadcast withdraw transaction: transferIndexInBlock=$sendTxnLogIndex, amount=$wavesAmount, " +
s"merkleProof={${transferProofs.map(EthEncoding.toHexString).mkString(",")}}"
)
waves1.api.broadcastAndWait(
chainContract.withdraw(
sender = clRecipient,
blockHash = BlockHash(sendTxnReceipt.getBlockHash),
merkleProof = transferProofs,
transferIndexInBlock = sendTxnLogIndex,
amount = wavesAmount
)
)
waves1.api.broadcastAndWait(withdraw())

val balanceAfter = balance
withClue("Received") {
Expand Down

0 comments on commit 0b7e497

Please sign in to comment.