mirror of
https://github.com/digital-asset/daml.git
synced 2024-11-10 10:46:11 +03:00
Fix TransactionCommitter.trimUnnecessaryNodes for rollback nodes (#9536)
* Fix TransactionCommitter.trimUnnecessaryNodes for rollback nodes changelog_begin changelog_end * Update ledger/participant-state/kvutils/src/test/suite/scala/com/daml/ledger/participant/state/kvutils/committer/transaction/TransactionCommitterSpec.scala Co-authored-by: Samir Talwar <samir.talwar@digitalasset.com> * switch error code changelog_begin changelog_end Co-authored-by: Samir Talwar <samir.talwar@digitalasset.com>
This commit is contained in:
parent
b25c904fc8
commit
a937a66463
@ -36,6 +36,7 @@ import com.daml.logging.{ContextualizedLogger, LoggingContext}
|
||||
import com.daml.metrics.Metrics
|
||||
import com.google.protobuf.{Timestamp => ProtoTimestamp}
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.jdk.CollectionConverters._
|
||||
|
||||
// The parameter inStaticTimeMode indicates that the ledger is running in static time mode.
|
||||
@ -387,9 +388,29 @@ private[kvutils] class TransactionCommitter(
|
||||
)(implicit loggingContext: LoggingContext): StepResult[DamlTransactionEntrySummary] = {
|
||||
val transaction = transactionEntry.submission.getTransaction
|
||||
val nodes = transaction.getNodesList.asScala
|
||||
val nodesToKeep = nodes.iterator.collect {
|
||||
case node if node.hasCreate || node.hasExercise => node.getNodeId
|
||||
}.toSet
|
||||
val nodeMap: Map[String, TransactionOuterClass.Node] =
|
||||
nodes.view.map(n => n.getNodeId -> n).toMap
|
||||
|
||||
@tailrec
|
||||
def goNodesToKeep(todo: List[String], result: Set[String]): Set[String] = todo match {
|
||||
case Nil => result
|
||||
case head :: tail =>
|
||||
import TransactionOuterClass.Node.NodeTypeCase
|
||||
val node = nodeMap
|
||||
.get(head)
|
||||
.getOrElse(throw Err.InternalError(s"Invalid transaction node id $head"))
|
||||
node.getNodeTypeCase match {
|
||||
case NodeTypeCase.CREATE =>
|
||||
goNodesToKeep(tail, result + head)
|
||||
case NodeTypeCase.EXERCISE =>
|
||||
goNodesToKeep(node.getExercise.getChildrenList.asScala.toList ++ tail, result + head)
|
||||
case NodeTypeCase.ROLLBACK | NodeTypeCase.FETCH | NodeTypeCase.LOOKUP_BY_KEY |
|
||||
NodeTypeCase.NODETYPE_NOT_SET =>
|
||||
goNodesToKeep(tail, result)
|
||||
}
|
||||
}
|
||||
|
||||
val nodesToKeep = goNodesToKeep(transaction.getRootsList.asScala.toList, Set.empty)
|
||||
|
||||
val filteredRoots = transaction.getRootsList.asScala.filter(nodesToKeep)
|
||||
|
||||
|
@ -99,6 +99,13 @@ class TransactionCommitterSpec extends AnyWordSpec with Matchers with MockitoSug
|
||||
)
|
||||
)
|
||||
),
|
||||
createNode("Rollback-1")(
|
||||
_.setRollback(
|
||||
rollbackNodeBuilder.addAllChildren(Seq("RollbackChild-1", "RollbackChild-2").asJava)
|
||||
)
|
||||
),
|
||||
createNode("RollbackChild-1")(_.setCreate(createNodeBuilder)),
|
||||
createNode("RollbackChild-2")(_.setFetch(fetchNodeBuilder)),
|
||||
)
|
||||
val tx = TransactionOuterClass.Transaction
|
||||
.newBuilder()
|
||||
@ -122,13 +129,16 @@ class TransactionCommitterSpec extends AnyWordSpec with Matchers with MockitoSug
|
||||
private def exerciseNodeBuilder =
|
||||
TransactionOuterClass.NodeExercise.newBuilder()
|
||||
|
||||
private def rollbackNodeBuilder =
|
||||
TransactionOuterClass.NodeRollback.newBuilder()
|
||||
|
||||
private def createNodeBuilder = TransactionOuterClass.NodeCreate.newBuilder()
|
||||
|
||||
private def lookupByKeyNodeBuilder =
|
||||
TransactionOuterClass.NodeLookupByKey.newBuilder()
|
||||
|
||||
"trimUnnecessaryNodes" should {
|
||||
"remove `Fetch` and `LookupByKey` nodes from transaction tree" in {
|
||||
"remove `Fetch`, `LookupByKey`, and `Rollback` nodes from the transaction tree" in {
|
||||
val context = createCommitContext(recordTime = None)
|
||||
|
||||
val actual = transactionCommitter.trimUnnecessaryNodes(
|
||||
|
Loading…
Reference in New Issue
Block a user