Skip to content

Commit

Permalink
/waves/external-payment return error if account balance not enough
Browse files Browse the repository at this point in the history
  • Loading branch information
gagarin55 committed Jun 8, 2016
1 parent 5995aa9 commit 30e1045
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 73 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
**0.2.0-RC4**

* Fixed issue with incorrect Handshake
* Balance with confirmations is the minimum balance
* /waves/external-payment returns error if account balance invalid

**0.2.0-RC3**

Expand Down
48 changes: 0 additions & 48 deletions src/main/scala/scorex/waves/Application.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,52 +91,4 @@ object Application extends App with ScorexLogging {
if (application.wallet.privateKeyAccounts().isEmpty)
application.wallet.generateNewAccounts(1)


def testingScript(application: Application): Unit = {
log.info("Going to execute testing scenario")
log.info("Current state is:" + application.blockStorage.state)
val wallet = application.wallet

if (wallet.privateKeyAccounts().isEmpty) {
wallet.generateNewAccounts(3)
log.info("Generated Accounts:\n" + wallet.privateKeyAccounts().toList.map(_.address).mkString("\n"))
}

log.info("Executing testing scenario with accounts" +
s"(${wallet.privateKeyAccounts().size}) : "
+ wallet.privateKeyAccounts().mkString(" "))

require(wallet.privateKeyAccounts().nonEmpty)

Thread.sleep(3.seconds.toMillis)

val genesisBlock = application.blockStorage.history.genesis
val genesisAccs = genesisBlock.transactions.flatMap(_ match {
case gtx: GenesisTransaction =>
Some(gtx.recipient)
case _ =>
log.error("Non-genesis tx in the genesis block!")
None
})

def genPayment(recipient: Option[Account] = None, amtOpt: Option[Long] = None): Option[Transaction] = {
val pkAccs = wallet.privateKeyAccounts().ensuring(_.nonEmpty)
val senderAcc = pkAccs(Random.nextInt(pkAccs.size))
val senderBalance = application.blockStorage.state.asInstanceOf[BalanceSheet].generationBalance(senderAcc)
val recipientAcc = recipient.getOrElse(pkAccs(Random.nextInt(pkAccs.size)))
val fee = Random.nextInt(5).toLong + 1
if (senderBalance - fee > 0) {
val amt = amtOpt.getOrElse(Math.abs(Random.nextLong() % (senderBalance - fee)))
Some(application.transactionModule.createPayment(senderAcc, recipientAcc, amt, fee))
} else None
}

log.info("Generate 200 transactions")
(1 to 200) foreach (_ => genPayment())

(1 to Int.MaxValue).foreach { _ =>
Thread.sleep(Random.nextInt(5.seconds.toMillis.toInt))
log.info(s"Payment created: ${genPayment()}")
}
}
}
46 changes: 24 additions & 22 deletions src/main/scala/scorex/waves/http/WavesApiRoute.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,28 @@ case class WavesApiRoute(override val application: Application)(implicit val con
case err: JsError =>
WrongJson.json
case JsSuccess(payment: ExternalPayment, _) =>
val tx = transactionModule.broadcastPayment(payment)
if (!tx.signatureValid)
InvalidSignature.json
else {
tx.validate match {
case ValidationResult.ValidateOke =>
tx.json
val txTry = transactionModule.broadcastPayment(payment)
if (txTry.isSuccess) {
val tx = txTry.get
if (!tx.signatureValid)
InvalidSignature.json
else {
tx.validate match {
case ValidationResult.ValidateOke =>
tx.json

case ValidationResult.InvalidAddress =>
InvalidAddress.json
case ValidationResult.InvalidAddress =>
InvalidAddress.json

case ValidationResult.NegativeAmount =>
NegativeAmount.json
case ValidationResult.NegativeAmount =>
NegativeAmount.json

case ValidationResult.NegativeFee =>
NegativeFee.json

case ValidationResult.NoBalance =>
NoBalance.json
case ValidationResult.NegativeFee =>
NegativeFee.json
}
}
} else {
NoBalance.json
}
}
}.getOrElse(WrongJson.json).toString
Expand All @@ -96,11 +98,11 @@ case class WavesApiRoute(override val application: Application)(implicit val con
}
}

//
// // Workaround to show datatype of post request without using it in another route
// // Related: https://github.com/swagger-api/swagger-core/issues/606
// // Why is this still showing even though it's set to hidden? See https://github.com/martypitt/swagger-springmvc/issues/447
// @ApiOperation(value = "IGNORE", notes = "", hidden = true, httpMethod = "GET", response = classOf[Payment])
// protected def paymentModel = Unit
//
// // Workaround to show datatype of post request without using it in another route
// // Related: https://github.com/swagger-api/swagger-core/issues/606
// // Why is this still showing even though it's set to hidden? See https://github.com/martypitt/swagger-springmvc/issues/447
// @ApiOperation(value = "IGNORE", notes = "", hidden = true, httpMethod = "GET", response = classOf[Payment])
// protected def paymentModel = Unit

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package scorex.waves.transaction

import scorex.account.{Account, PrivateKeyAccount, PublicKeyAccount}
import scorex.api.http.NoBalance
import scorex.app.Application
import scorex.block.BlockField
import scorex.crypto.encode.Base58
import scorex.settings.Settings
import scorex.transaction._
import scorex.utils.NTP

import scala.util.{Failure, Success, Try}

/**
* Waves Transaction Module
*/
Expand All @@ -24,16 +27,19 @@ class WavesTransactionModule(implicit override val settings: TransactionSettings
/**
* Publish signed payment transaction which generated outside node
*/
def broadcastPayment(externalPayment: ExternalPayment): PaymentTransaction = {
def broadcastPayment(externalPayment: ExternalPayment): Try[PaymentTransaction] = {
val time = externalPayment.timestamp
val sigBytes = Base58.decode(externalPayment.signature).get
val senderPubKey = Base58.decode(externalPayment.senderPublicKey).get
val recipientAccount = new Account(externalPayment.recipient)
val payment = new PaymentTransaction(new PublicKeyAccount(senderPubKey),
recipientAccount, externalPayment.amount, externalPayment.fee, time, sigBytes)
if (blockStorage.state.isValid(payment))
if (blockStorage.state.isValid(payment)) {
onNewOffchainTransaction(payment)
payment
Success(payment)
} else {
Failure(new Exception(NoBalance.message))
}
}

override def genesisData: BlockField[SimpleTransactionModule.StoredInBlock] = {
Expand Down

0 comments on commit 30e1045

Please sign in to comment.