Skip to content

Commit

Permalink
Merge branch 'version-1.5.x' into node-2608-removed-diff-from-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
phearnot committed Nov 27, 2023
2 parents ae8ed7f + 26f5194 commit 1512b6f
Show file tree
Hide file tree
Showing 40 changed files with 563 additions and 334 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,15 @@ class AccountsApiGrpcImpl(commonApi: CommonAccountsApi)(implicit sc: Scheduler)

override def getScript(request: AccountRequest): Future[ScriptResponse] = Future {
commonApi.script(request.address.toAddress()) match {
case Some(desc) => ScriptResponse(PBTransactions.toPBScript(Some(desc.script)), desc.script.expr.toString, desc.verifierComplexity, desc.publicKey.toByteString)
case None => ScriptResponse()
case Some(desc) =>
ScriptResponse(
PBTransactions.toPBScript(Some(desc.script)),
desc.script.expr.toString,
desc.verifierComplexity,
desc.publicKey.toByteString
)
case None =>
ScriptResponse()
}
}

Expand Down
42 changes: 26 additions & 16 deletions grpc-server/src/main/scala/com/wavesplatform/events/events.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import com.wavesplatform.transaction.assets.exchange.ExchangeTransaction
import com.wavesplatform.transaction.lease.LeaseTransaction
import com.wavesplatform.transaction.smart.InvokeScriptTransaction
import com.wavesplatform.transaction.transfer.{MassTransferTransaction, TransferTransaction}
import com.wavesplatform.transaction.{Asset, Authorized, CreateAliasTransaction, EthereumTransaction}
import com.wavesplatform.transaction.{Asset, Authorized, CreateAliasTransaction, EthereumTransaction, Transaction}

import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
Expand Down Expand Up @@ -389,7 +389,11 @@ object StateUpdate {
private lazy val WavesAlias = Alias.fromString("alias:W:waves", Some('W'.toByte)).explicitGet()
private lazy val WavesAddress = Address.fromString("3PGd1eQR8EhLkSogpmu9Ne7hSH1rQ5ALihd", Some('W'.toByte)).explicitGet()

def atomic(blockchainBeforeWithMinerReward: Blockchain, snapshot: StateSnapshot): StateUpdate = {
def atomic(
blockchainBeforeWithMinerReward: Blockchain,
snapshot: StateSnapshot,
txWithLeases: Iterable[(Transaction, Map[ByteStr, LeaseSnapshot])]
): StateUpdate = {
val blockchain = blockchainBeforeWithMinerReward
val blockchainAfter = SnapshotBlockchain(blockchain, snapshot)

Expand Down Expand Up @@ -426,18 +430,20 @@ object StateUpdate {
assetAfter = blockchainAfter.assetDescription(asset)
} yield AssetStateUpdate(asset.id, assetBefore, assetAfter)

val updatedLeases = snapshot.leaseStates.map { case (leaseId, newState) =>
LeaseUpdate(
leaseId,
if (newState.isActive) LeaseStatus.Active else LeaseStatus.Inactive,
newState.amount,
newState.sender,
newState.recipient match {
case `WavesAlias` => WavesAddress
case other => blockchainAfter.resolveAlias(other).explicitGet()
},
newState.sourceId
)
val updatedLeases = txWithLeases.flatMap { case (sourceTxId, leases) =>
leases.map { case (leaseId, newState) =>
LeaseUpdate(
leaseId,
if (newState.isActive) LeaseStatus.Active else LeaseStatus.Inactive,
newState.amount,
newState.sender,
newState.recipient match {
case `WavesAlias` => WavesAddress
case other => blockchainAfter.resolveAlias(other).explicitGet()
},
newState.toDetails(blockchain, Some(sourceTxId), blockchain.leaseDetails(leaseId)).sourceId
)
}
}.toVector

val updatedScripts = snapshot.accountScriptsByAddress.map { case (address, newScript) =>
Expand Down Expand Up @@ -546,13 +552,17 @@ object StateUpdate {
val accBlockchain = SnapshotBlockchain(blockchainBeforeWithReward, accSnapshot)
(
accSnapshot |+| txInfo.snapshot,
updates :+ atomic(accBlockchain, txInfo.snapshot)
updates :+ atomic(accBlockchain, txInfo.snapshot, Seq((txInfo.transaction, txInfo.snapshot.leaseStates)))
)
}
val blockchainAfter = SnapshotBlockchain(blockchainBeforeWithReward, totalSnapshot)
val metadata = transactionsMetadata(blockchainAfter, totalSnapshot)
val refAssets = referencedAssets(blockchainAfter, txsStateUpdates)
val keyBlockUpdate = atomic(blockchainBeforeWithReward, keyBlockSnapshot)
val keyBlockUpdate = atomic(
blockchainBeforeWithReward,
keyBlockSnapshot,
keyBlockSnapshot.transactions.map { case (_, txInfo) => (txInfo.transaction, txInfo.snapshot.leaseStates) }
)
(keyBlockUpdate, txsStateUpdates, metadata, refAssets)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import com.wavesplatform.lang.v1.FunctionHeader
import com.wavesplatform.lang.v1.compiler.Terms
import com.wavesplatform.lang.v1.compiler.Terms.FUNCTION_CALL
import com.wavesplatform.state.DataEntry.Format
import com.wavesplatform.state.{AssetDistributionPage, DataEntry, EmptyDataEntry, LeaseBalance, Portfolio}
import com.wavesplatform.state.{AssetDistribution, AssetDistributionPage, DataEntry, EmptyDataEntry, LeaseBalance, Portfolio}
import com.wavesplatform.transaction.Asset.{IssuedAsset, Waves}
import com.wavesplatform.transaction.assets.*
import com.wavesplatform.transaction.assets.exchange.{Order, ExchangeTransaction as ExchangeTx}
Expand Down Expand Up @@ -338,6 +338,11 @@ object AsyncHttpApi extends Assertions {
get(url, amountsAsStrings).as[AssetDistributionPage](amountsAsStrings)
}

def assetDistribution(asset: String, amountsAsStrings: Boolean = false): Future[AssetDistribution] = {
val req = s"/assets/$asset/distribution"
get(req, amountsAsStrings).as[AssetDistribution](amountsAsStrings)
}

def effectiveBalance(address: String, confirmations: Option[Int] = None, amountsAsStrings: Boolean = false): Future[Balance] = {
val maybeConfirmations = confirmations.fold("")(a => s"/$a")
get(s"/addresses/effectiveBalance/$address$maybeConfirmations", amountsAsStrings).as[Balance](amountsAsStrings)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import com.wavesplatform.it.Node
import com.wavesplatform.it.sync.*
import com.wavesplatform.lang.script.v1.ExprScript
import com.wavesplatform.lang.v1.compiler.Terms
import com.wavesplatform.state.{AssetDistributionPage, DataEntry}
import com.wavesplatform.state.{AssetDistribution, AssetDistributionPage, DataEntry}
import com.wavesplatform.transaction.assets.exchange.Order
import com.wavesplatform.transaction.lease.{LeaseCancelTransaction, LeaseTransaction}
import com.wavesplatform.transaction.smart.InvokeScriptTransaction
Expand Down Expand Up @@ -261,6 +261,9 @@ object SyncHttpApi extends Assertions with matchers.should.Matchers {
): AssetDistributionPage =
sync(async(n).assetDistributionAtHeight(asset, height, limit, maybeAfter, amountsAsStrings))

def assetDistribution(asset: String): AssetDistribution =
sync(async(n).assetDistribution(asset))

def broadcastIssue(
source: KeyPair,
name: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,15 +250,15 @@ class IssueReissueBurnAssetSuite extends BaseFreeSpec {
val acc = createDapp(script(simpleReissuableAsset))
val asset = issueValidated(acc, simpleReissuableAsset)
invokeScript(acc, "transferAndBurn", assetId = asset, count = 100)
val height1 = nodes.waitForHeightArise()
sender.assetDistributionAtHeight(asset, height1 - 1, 10).items.map { case (a, v) => a.toString -> v } shouldBe Map(
nodes.waitForHeightArise()
sender.assetDistribution(asset).map { case (a, v) => a.toString -> v } shouldBe Map(
miner.address -> 100L,
acc.toAddress.toString -> (simpleReissuableAsset.quantity - 200)
)
reissue(acc, CallableMethod, asset, 400, reissuable = false)
invokeScript(acc, "transferAndBurn", assetId = asset, count = 100)
val height2 = nodes.waitForHeightArise()
sender.assetDistributionAtHeight(asset, height2 - 1, 10).items.map { case (a, v) => a.toString -> v } shouldBe Map(
nodes.waitForHeightArise()
sender.assetDistribution(asset).map { case (a, v) => a.toString -> v } shouldBe Map(
miner.address -> 200L,
acc.toAddress.toString -> simpleReissuableAsset.quantity
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import com.wavesplatform.state.AssetDistributionPage
import com.wavesplatform.transaction.transfer.MassTransferTransaction
import org.scalatest.CancelAfterFailure

import scala.concurrent.duration.*

class AssetDistributionSuite extends BaseTransactionSuite with CancelAfterFailure {

lazy val node: Node = nodes.head
Expand All @@ -23,7 +25,7 @@ class AssetDistributionSuite extends BaseTransactionSuite with CancelAfterFailur

nodes.waitForHeightArise()

val issueTx = node.issue(issuer, "TestCoin", "no description", issueAmount, 8, false, issueFee, waitForTx = true).id
val issueTx = node.issue(issuer, "TestCoin", "no description", issueAmount, 8, reissuable = false, issueFee, waitForTx = true).id

node.massTransfer(
issuer,
Expand All @@ -47,6 +49,8 @@ class AssetDistributionSuite extends BaseTransactionSuite with CancelAfterFailur

val issuerAssetDis = assetDis.view.filterKeys(_ == issuer.toAddress).values

assetDis should be equals node.assetDistribution(issueTx)

issuerAssetDis.size shouldBe 1
issuerAssetDis.head shouldBe (issueAmount - addresses.length * transferAmount)

Expand All @@ -68,10 +72,34 @@ class AssetDistributionSuite extends BaseTransactionSuite with CancelAfterFailur
)
}

test("'Asset distribution' works properly") {
val receivers = for (i <- 0 until 10) yield KeyPair(s"receiver#$i".getBytes("UTF-8"))

val issueTx = node.issue(issuer, "TestCoin#2", "no description", issueAmount, 8, reissuable = false, issueFee, waitForTx = true).id

node
.massTransfer(
issuer,
receivers.map(rc => MassTransferTransaction.Transfer(rc.toAddress.toString, 10)).toList,
minFee + minFee * receivers.length,
assetId = Some(issueTx),
waitForTx = true
)

nodes.waitForHeightArise()

val distribution = node.assetDistribution(issueTx)

distribution.size shouldBe (receivers.size + 1)
distribution(issuer.toAddress) shouldBe (issueAmount - 10 * receivers.length)

assert(receivers.forall(rc => distribution(rc.toAddress) == 10), "Distribution correct")
}

test("Correct last page and entry count") {
val receivers = for (i <- 0 until 50) yield KeyPair(s"receiver#$i".getBytes("UTF-8"))

val issueTx = node.issue(issuer, "TestCoin#2", "no description", issueAmount, 8, false, issueFee, waitForTx = true).id
val issueTx = node.issue(issuer, "TestCoin#2", "no description", issueAmount, 8, reissuable = false, issueFee, waitForTx = true).id

node
.massTransfer(
Expand All @@ -96,6 +124,24 @@ class AssetDistributionSuite extends BaseTransactionSuite with CancelAfterFailur
assert(pages.map(_.items.size).sum == 51)
}

test("Unlimited list") {
val assetId = node.issue(issuer, "TestCoin#2", "no description", issueAmount, 8, reissuable = false, issueFee, waitForTx = true).id

val receivers = for (i <- 0 until 2000) yield KeyPair(s"receiver#$i".getBytes("UTF-8"))

val transfers = receivers.map { r => MassTransferTransaction.Transfer(r.toAddress.toString, 10L) }.toList

transfers.grouped(100).foreach { t =>
node.massTransfer(issuer, t, minFee + t.length * minFee, assetId = Some(assetId))
}

node.waitFor("empty utx")(_.utxSize, (_: Int) == 0, 1 second)
nodes.waitForHeightArise()

val list = node.assetDistribution(assetId)
list should have size 2001
}

def distributionPages(asset: String, height: Int, limit: Int): List[AssetDistributionPage] = {
def _load(acc: List[AssetDistributionPage], maybeAfter: Option[String]): List[AssetDistributionPage] = {
val page = node.assetDistributionAtHeight(asset, height, limit, maybeAfter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ class AcceptFailedScriptActivationSuite extends BaseTransactionSuite with NTPTim
smartMatcherFee,
100L,
ts,
ts + Order.MaxLiveTime,
ts + 2.days.toMillis,
smartMatcherFee
)
.explicitGet()
Expand All @@ -314,7 +314,7 @@ class AcceptFailedScriptActivationSuite extends BaseTransactionSuite with NTPTim
smartMatcherFee,
100L,
ts,
ts + Order.MaxLiveTime,
ts + 2.days.toMillis,
smartMatcherFee
)
.explicitGet()
Expand Down Expand Up @@ -375,7 +375,7 @@ class AcceptFailedScriptActivationSuite extends BaseTransactionSuite with NTPTim
10L,
100L,
ts,
ts + Order.MaxLiveTime,
ts + 2.days.toMillis,
smartMatcherFee,
matcherFeeAssetId = IssuedAsset(ByteStr.decodeBase58(feeAsset).get)
)
Expand All @@ -390,7 +390,7 @@ class AcceptFailedScriptActivationSuite extends BaseTransactionSuite with NTPTim
10L,
100L,
ts,
ts + Order.MaxLiveTime,
ts + 2.days.toMillis,
smartMatcherFee,
matcherFeeAssetId = IssuedAsset(ByteStr.decodeBase58(feeAsset).get)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,31 +121,6 @@ class FailedTransactionGrpcSuite extends GrpcBaseTransactionSuite with FailedTra
sender.setScript(contract, Right(Some(script)), setScriptFee, waitForTx = true)
}

test("InvokeScriptTransaction: insufficient action fees propagates failed transaction") {
val invokeFee = 0.005.waves
val setAssetScriptMinFee = setAssetScriptFee + smartFee * 2
val priorityFee = setAssetScriptMinFee + invokeFee

updateAssetScript(result = true, smartAsset, contract, setAssetScriptMinFee)

for (typeName <- Seq("transfer", "issue", "reissue", "burn")) {
updateTikTok("unknown", setAssetScriptMinFee)

overflowBlock()
sendTxsAndThenPriorityTx(
_ =>
sender
.broadcastInvokeScript(
caller,
Recipient().withPublicKeyHash(contractAddr),
Some(FUNCTION_CALL(FunctionHeader.User("tikTok"), List.empty)),
fee = invokeFee
),
() => updateTikTok(typeName, priorityFee, waitForTx = false)
)((txs, _) => assertFailedTxs(txs))
}
}

test("InvokeScriptTransaction: invoke script error in payment asset propagates failed transaction") {
val invokeFee = 0.005.waves + smartFee
val setAssetScriptMinFee = setAssetScriptFee + smartFee
Expand Down
Loading

0 comments on commit 1512b6f

Please sign in to comment.