Skip to content

Commit

Permalink
NODE-2627 State Hash calculation changes (#3916)
Browse files Browse the repository at this point in the history
  • Loading branch information
phearnot authored Nov 29, 2023
1 parent d3be735 commit b94b9e7
Show file tree
Hide file tree
Showing 123 changed files with 3,543 additions and 4,300 deletions.
60 changes: 29 additions & 31 deletions grpc-server/src/main/scala/com/wavesplatform/events/events.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.wavesplatform.events
import cats.Monoid
import cats.implicits.catsSyntaxSemigroup
import com.google.protobuf.ByteString
import com.wavesplatform.account.{Address, AddressOrAlias, Alias, PublicKey}
import com.wavesplatform.account.{Address, AddressOrAlias, PublicKey}
import com.wavesplatform.block.{Block, MicroBlock}
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.common.utils.*
Expand All @@ -17,13 +17,12 @@ import com.wavesplatform.protobuf.transaction.InvokeScriptResult.Call.Argument
import com.wavesplatform.protobuf.transaction.{PBAmounts, PBTransactions, InvokeScriptResult as PBInvokeScriptResult}
import com.wavesplatform.state.*
import com.wavesplatform.state.diffs.invoke.InvokeScriptTransactionLike
import com.wavesplatform.state.reader.SnapshotBlockchain
import com.wavesplatform.transaction.Asset.IssuedAsset
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, Transaction}
import com.wavesplatform.transaction.{Asset, Authorized, CreateAliasTransaction, EthereumTransaction}

import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
Expand Down Expand Up @@ -386,14 +385,7 @@ 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,
txWithLeases: Iterable[(Transaction, Map[ByteStr, LeaseSnapshot])]
): StateUpdate = {
def atomic(blockchainBeforeWithMinerReward: Blockchain, snapshot: StateSnapshot): StateUpdate = {
val blockchain = blockchainBeforeWithMinerReward
val blockchainAfter = SnapshotBlockchain(blockchain, snapshot)

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

val updatedLeases = txWithLeases.flatMap { case (sourceTxId, leases) =>
leases.map { case (leaseId, newState) =>
val newLeaseUpdates = snapshot.newLeases.collect {
case (newId, staticInfo) if !snapshot.cancelledLeases.contains(newId) =>
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
newId,
LeaseStatus.Active,
staticInfo.amount.value,
staticInfo.sender,
staticInfo.recipientAddress,
staticInfo.sourceId
)
}
}.toVector
}

val cancelledLeaseUpdates = snapshot.cancelledLeases.map { case (id, _) =>
val si = snapshot.newLeases.get(id).orElse(blockchain.leaseDetails(id).map(_.static))
LeaseUpdate(
id,
LeaseStatus.Inactive,
si.fold(0L)(_.amount.value),
si.fold(PublicKey(new Array[Byte](32)))(_.sender),
si.fold(PublicKey(new Array[Byte](32)).toAddress)(_.recipientAddress),
si.fold(ByteStr.empty)(_.sourceId)
)
}

val updatedLeases = newLeaseUpdates ++ cancelledLeaseUpdates

val updatedScripts = snapshot.accountScriptsByAddress.map { case (address, newScript) =>
ScriptUpdate(ByteStr(address.bytes), blockchain.accountScript(address).map(_.script.bytes()), newScript.map(_.script.bytes()))
}.toVector

StateUpdate(balances.toVector, leaseBalanceUpdates, dataEntries, assets, updatedLeases, updatedScripts, Seq.empty)
StateUpdate(balances.toVector, leaseBalanceUpdates, dataEntries, assets, updatedLeases.toSeq, updatedScripts, Seq.empty)
}

private[this] def transactionsMetadata(blockchain: Blockchain, snapshot: StateSnapshot): Seq[TransactionMetadata] = {
Expand Down Expand Up @@ -552,17 +554,13 @@ object StateUpdate {
val accBlockchain = SnapshotBlockchain(blockchainBeforeWithReward, accSnapshot)
(
accSnapshot |+| txInfo.snapshot,
updates :+ atomic(accBlockchain, txInfo.snapshot, Seq((txInfo.transaction, txInfo.snapshot.leaseStates)))
updates :+ atomic(accBlockchain, txInfo.snapshot)
)
}
val blockchainAfter = SnapshotBlockchain(blockchainBeforeWithReward, totalSnapshot)
val metadata = transactionsMetadata(blockchainAfter, totalSnapshot)
val refAssets = referencedAssets(blockchainAfter, txsStateUpdates)
val keyBlockUpdate = atomic(
blockchainBeforeWithReward,
keyBlockSnapshot,
keyBlockSnapshot.transactions.map { case (_, txInfo) => (txInfo.transaction, txInfo.snapshot.leaseStates) }
)
val keyBlockUpdate = atomic(blockchainBeforeWithReward, keyBlockSnapshot)
(keyBlockUpdate, txsStateUpdates, metadata, refAssets)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,15 @@ package com.wavesplatform.api.grpc.test
import com.google.protobuf.ByteString
import com.wavesplatform.TestValues
import com.wavesplatform.account.{Address, KeyPair}
import com.wavesplatform.api.grpc.{
AccountRequest,
AccountsApiGrpcImpl,
BalanceResponse,
BalancesRequest,
DataEntryResponse,
DataRequest,
LeaseResponse
}
import com.wavesplatform.api.grpc.*
import com.wavesplatform.block.Block
import com.wavesplatform.common.state.ByteStr
import com.wavesplatform.crypto.DigestLength
import com.wavesplatform.db.WithDomain
import com.wavesplatform.db.WithState.AddrWithBalance
import com.wavesplatform.history.Domain
import com.wavesplatform.protobuf.Amount
import com.wavesplatform.protobuf.transaction.{DataTransactionData, Recipient}
import com.wavesplatform.protobuf.transaction.{DataEntry, Recipient}
import com.wavesplatform.state.{BlockRewardCalculator, EmptyDataEntry, IntegerDataEntry}
import com.wavesplatform.test.*
import com.wavesplatform.transaction.Asset.Waves
Expand Down Expand Up @@ -151,7 +143,7 @@ class AccountsApiGrpcSpec extends FreeSpec with BeforeAndAfterAll with DiffMatch
result1.runSyncUnsafe() shouldBe List(
DataEntryResponse.of(
ByteString.copyFrom(sender.toAddress.bytes),
Some(DataTransactionData.DataEntry.of("key2", DataTransactionData.DataEntry.Value.IntValue(456)))
Some(DataEntry.of("key2", DataEntry.Value.IntValue(456)))
)
)

Expand All @@ -160,11 +152,11 @@ class AccountsApiGrpcSpec extends FreeSpec with BeforeAndAfterAll with DiffMatch
result2.runSyncUnsafe() shouldBe List(
DataEntryResponse.of(
ByteString.copyFrom(sender.toAddress.bytes),
Some(DataTransactionData.DataEntry.of("key2", DataTransactionData.DataEntry.Value.IntValue(456)))
Some(DataEntry.of("key2", DataEntry.Value.IntValue(456)))
),
DataEntryResponse.of(
ByteString.copyFrom(sender.toAddress.bytes),
Some(DataTransactionData.DataEntry.of("key3", DataTransactionData.DataEntry.Value.IntValue(789)))
Some(DataEntry.of("key3", DataEntry.Value.IntValue(789)))
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ import com.wavesplatform.events.protobuf.BlockchainUpdated.Append
import com.wavesplatform.test.NumericExt
import com.wavesplatform.transaction.Asset.Waves
import com.wavesplatform.transaction.EthTxGenerator.Arg
import com.wavesplatform.transaction.{Asset, EthTxGenerator, EthereumTransaction, TxHelpers, TxNonNegativeAmount}
import com.wavesplatform.transaction.TxHelpers.secondAddress
import com.wavesplatform.transaction.assets.IssueTransaction
import com.wavesplatform.transaction.transfer.MassTransferTransaction.ParsedTransfer
import com.wavesplatform.transaction.{Asset, EthTxGenerator, EthereumTransaction, TxHelpers}

class BlockchainUpdatesEthereumInvokeTxSpec extends BlockchainUpdatesTestBase {
val ethAddressBalanceAfterTx: Long = firstTxParticipantBalanceBefore - invokeFee
Expand Down Expand Up @@ -89,9 +88,9 @@ class BlockchainUpdatesEthereumInvokeTxSpec extends BlockchainUpdatesTestBase {
val massTx = TxHelpers.massTransfer(
assetDappAccount,
Seq(
ParsedTransfer(firstTxParticipantAddress, TxNonNegativeAmount.unsafeFrom(amount)),
ParsedTransfer(secondAddress, TxNonNegativeAmount.unsafeFrom(amount)),
ParsedTransfer(invokerDappAddress, TxNonNegativeAmount.unsafeFrom(amount))
firstTxParticipantAddress -> amount,
secondAddress -> amount,
invokerDappAddress -> amount
),
asset,
fee = 500000
Expand Down Expand Up @@ -141,23 +140,47 @@ class BlockchainUpdatesEthereumInvokeTxSpec extends BlockchainUpdatesTestBase {
doubleNestedInvokeTest(assetDappAccount, balancesSeq, issue, invoke, massTx, caller, Subscribe) { append =>
val invokeScriptMetadata = append.transactionsMetadata.head.getEthereum.getInvoke
checkEthereumBase(append, invoke, foo)
checkInvokeDoubleNestedBlockchainUpdates(append, invokeScriptMetadata, assetDappAddress, firstTxParticipantAddress, secondAddress, issue, callerBalancesMap)
checkInvokeDoubleNestedBlockchainUpdates(
append,
invokeScriptMetadata,
assetDappAddress,
firstTxParticipantAddress,
secondAddress,
issue,
callerBalancesMap
)
}
}

"BU-230. doubles nested i.caller. Invoke have to return correct data for getBlockUpdate" in {
doubleNestedInvokeTest(assetDappAccount, balancesSeq, issue, invoke, massTx, caller, GetBlockUpdate) { append =>
val invokeScriptMetadata = append.transactionsMetadata.head.getEthereum.getInvoke
checkEthereumBase(append, invoke, foo)
checkInvokeDoubleNestedBlockchainUpdates(append, invokeScriptMetadata, assetDappAddress, firstTxParticipantAddress, secondAddress, issue, callerBalancesMap)
checkInvokeDoubleNestedBlockchainUpdates(
append,
invokeScriptMetadata,
assetDappAddress,
firstTxParticipantAddress,
secondAddress,
issue,
callerBalancesMap
)
}
}

"BU-233. doubles nested i.caller. Invoke have to return correct data for getBlockUpdateRange" in {
doubleNestedInvokeTest(assetDappAccount, balancesSeq, issue, invoke, massTx, caller, GetBlockUpdateRange) { append =>
val invokeScriptMetadata = append.transactionsMetadata.head.getEthereum.getInvoke
checkEthereumBase(append, invoke, foo)
checkInvokeDoubleNestedBlockchainUpdates(append, invokeScriptMetadata, assetDappAddress, firstTxParticipantAddress, secondAddress, issue, callerBalancesMap)
checkInvokeDoubleNestedBlockchainUpdates(
append,
invokeScriptMetadata,
assetDappAddress,
firstTxParticipantAddress,
secondAddress,
issue,
callerBalancesMap
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ class BlockchainUpdatesGetBlockUpdatesRangeSpec extends BlockchainUpdatesTestBas

"BU-165. Return correct data for massTransfer" in {
val massTransferFee = fee * 6
val massTransfer = TxHelpers.massTransfer(firstTxParticipant, recipients, firstToken.asset, massTransferFee)
val massTransfer = TxHelpers.massTransfer(firstTxParticipant, recipients.map(v => v.address -> v.amount.value), firstToken.asset, massTransferFee)
withGenerateGetBlockUpdateRange(
GetBlockUpdatesRangeRequest.of(1, 3),
settings = currentSettings,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ class BlockchainUpdatesGetBlockUpdatesSpec extends BlockchainUpdatesTestBase {

"BU-200. Return correct data for massTransfer" in {
val massTransferFee = fee * 6
val massTransfer = TxHelpers.massTransfer(firstTxParticipant, recipients, firstToken.asset, massTransferFee)
val massTransfer =
TxHelpers.massTransfer(firstTxParticipant, recipients.map(r => r.address -> r.amount.value), firstToken.asset, massTransferFee)

withGenerateGetBlockUpdate(
height = 3,
Expand Down Expand Up @@ -271,7 +272,7 @@ class BlockchainUpdatesGetBlockUpdatesSpec extends BlockchainUpdatesTestBase {
val ethereumTransfer: EthereumTransaction =
EthTxGenerator.generateEthTransfer(firstTxParticipantEthereum, secondTxParticipantAddress, amount, secondTokenAsset)
val ethAddress = ethereumTransfer.senderAddress.value()
val transfer = TxHelpers.transfer(secondTxParticipant, ethAddress, secondTokenQuantity, secondTokenAsset)
val transfer = TxHelpers.transfer(secondTxParticipant, ethAddress, secondTokenQuantity, secondTokenAsset)

withGenerateGetBlockUpdate(
height = 4,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ import com.wavesplatform.events.fixtures.BlockchainUpdateGrpcMethod.*
import com.wavesplatform.events.fixtures.InvokeWavesTxCheckers.checkInvokeDoubleNestedBlockchainUpdates
import com.wavesplatform.events.fixtures.PrepareInvokeTestData.*
import com.wavesplatform.events.fixtures.WavesTxChecks.*
import com.wavesplatform.lang.v1.compiler.Terms.{CONST_BYTESTR, CONST_LONG, CONST_STRING, EXPR}
import com.wavesplatform.events.protobuf.BlockchainUpdated.Append
import com.wavesplatform.lang.v1.compiler.Terms.{CONST_BYTESTR, CONST_LONG, CONST_STRING, EXPR}
import com.wavesplatform.test.NumericExt
import com.wavesplatform.transaction.Asset.Waves
import com.wavesplatform.transaction.{Asset, TxHelpers, TxNonNegativeAmount}
import com.wavesplatform.transaction.TxHelpers.secondAddress
import com.wavesplatform.transaction.transfer.MassTransferTransaction.ParsedTransfer
import com.wavesplatform.transaction.assets.IssueTransaction
import com.wavesplatform.transaction.smart.InvokeScriptTransaction
import com.wavesplatform.transaction.{Asset, TxHelpers}

class BlockchainUpdatesInvokeTxSpec extends BlockchainUpdatesTestBase {
"Simple invoke transaction" - {
Expand Down Expand Up @@ -87,9 +86,9 @@ class BlockchainUpdatesInvokeTxSpec extends BlockchainUpdatesTestBase {
val massTx = TxHelpers.massTransfer(
assetDappAccount,
Seq(
ParsedTransfer(firstTxParticipantAddress, TxNonNegativeAmount.unsafeFrom(amount)),
ParsedTransfer(secondAddress, TxNonNegativeAmount.unsafeFrom(amount)),
ParsedTransfer(invokerDappAddress, TxNonNegativeAmount.unsafeFrom(amount))
firstTxParticipantAddress -> amount,
secondAddress -> amount,
invokerDappAddress -> amount
),
asset,
fee = 500000
Expand Down Expand Up @@ -144,7 +143,8 @@ class BlockchainUpdatesInvokeTxSpec extends BlockchainUpdatesTestBase {
append,
invokeScriptMetadata,
assetDappAddress,
firstTxParticipantAddress, secondAddress,
firstTxParticipantAddress,
secondAddress,
issue,
callerBalancesMap
)
Expand All @@ -159,7 +159,8 @@ class BlockchainUpdatesInvokeTxSpec extends BlockchainUpdatesTestBase {
append,
invokeScriptMetadata,
assetDappAddress,
firstTxParticipantAddress, secondAddress,
firstTxParticipantAddress,
secondAddress,
issue,
callerBalancesMap
)
Expand All @@ -174,7 +175,8 @@ class BlockchainUpdatesInvokeTxSpec extends BlockchainUpdatesTestBase {
append,
invokeScriptMetadata,
assetDappAddress,
firstTxParticipantAddress, secondAddress,
firstTxParticipantAddress,
secondAddress,
issue,
callerBalancesMap
)
Expand All @@ -201,15 +203,31 @@ class BlockchainUpdatesInvokeTxSpec extends BlockchainUpdatesTestBase {
doubleNestedInvokeTest(assetDappAccount, balancesSeq, issue, invoke, massTx, originCaller, GetBlockUpdate) { append =>
val invokeScriptMetadata = append.transactionsMetadata.head.getInvokeScript
checkInvokeBase(append, invoke)
checkInvokeDoubleNestedBlockchainUpdates(append, invokeScriptMetadata, assetDappAddress, invokerDappAddress, invokerDappAddress, issue, originalCallerBalancesMap)
checkInvokeDoubleNestedBlockchainUpdates(
append,
invokeScriptMetadata,
assetDappAddress,
invokerDappAddress,
invokerDappAddress,
issue,
originalCallerBalancesMap
)
}
}

"BU-174. doubles nested i.originCaller. Invoke have to return correct data for getBlockUpdateRange" in {
doubleNestedInvokeTest(assetDappAccount, balancesSeq, issue, invoke, massTx, originCaller, GetBlockUpdateRange) { append =>
val invokeScriptMetadata = append.transactionsMetadata.head.getInvokeScript
checkInvokeBase(append, invoke)
checkInvokeDoubleNestedBlockchainUpdates(append, invokeScriptMetadata, assetDappAddress, invokerDappAddress, invokerDappAddress, issue, originalCallerBalancesMap)
checkInvokeDoubleNestedBlockchainUpdates(
append,
invokeScriptMetadata,
assetDappAddress,
invokerDappAddress,
invokerDappAddress,
issue,
originalCallerBalancesMap
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,7 @@ import com.wavesplatform.crypto.DigestLength
import com.wavesplatform.db.InterferableDB
import com.wavesplatform.events.FakeObserver.*
import com.wavesplatform.events.StateUpdate.LeaseUpdate.LeaseStatus
import com.wavesplatform.utils.byteStrOrdering
import com.wavesplatform.events.StateUpdate.{
AssetInfo,
AssetStateUpdate,
BalanceUpdate,
DataEntryUpdate,
LeaseUpdate,
LeasingBalanceUpdate,
ScriptUpdate
}
import com.wavesplatform.events.StateUpdate.{AssetInfo, AssetStateUpdate, BalanceUpdate, DataEntryUpdate, LeaseUpdate, LeasingBalanceUpdate, ScriptUpdate}
import com.wavesplatform.events.api.grpc.protobuf.{GetBlockUpdateRequest, GetBlockUpdatesRangeRequest, SubscribeRequest}
import com.wavesplatform.events.protobuf.BlockchainUpdated.Rollback.RollbackType
import com.wavesplatform.events.protobuf.BlockchainUpdated.Update
Expand All @@ -36,8 +27,7 @@ import com.wavesplatform.lang.v1.compiler.Terms.FUNCTION_CALL
import com.wavesplatform.lang.v1.compiler.TestCompiler
import com.wavesplatform.protobuf.*
import com.wavesplatform.protobuf.block.PBBlocks
import com.wavesplatform.protobuf.transaction.DataTransactionData.DataEntry
import com.wavesplatform.protobuf.transaction.InvokeScriptResult
import com.wavesplatform.protobuf.transaction.{DataEntry, InvokeScriptResult}
import com.wavesplatform.protobuf.transaction.InvokeScriptResult.{Call, Invocation, Payment}
import com.wavesplatform.settings.{Constants, WavesSettings}
import com.wavesplatform.state.{AssetDescription, BlockRewardCalculator, EmptyDataEntry, Height, LeaseBalance, StringDataEntry}
Expand All @@ -51,6 +41,7 @@ import com.wavesplatform.transaction.smart.SetScriptTransaction
import com.wavesplatform.transaction.transfer.TransferTransaction
import com.wavesplatform.transaction.utils.Signed
import com.wavesplatform.transaction.{Asset, CreateAliasTransaction, DataTransaction, GenesisTransaction, PaymentTransaction, TxHelpers}
import com.wavesplatform.utils.byteStrOrdering
import io.grpc.StatusException
import monix.execution.Scheduler.Implicits.global
import org.scalactic.source.Position
Expand Down
Loading

0 comments on commit b94b9e7

Please sign in to comment.