update canton to 20240325.12978.v1637d018 (#18864)

tell-slack: canton

Co-authored-by: Azure Pipelines Daml Build <support@digitalasset.com>
This commit is contained in:
azure-pipelines[bot] 2024-03-26 09:30:57 +01:00 committed by GitHub
parent 24a9e9f99f
commit 81016b19ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
51 changed files with 183 additions and 215 deletions

View File

@ -41,8 +41,12 @@ class SequencerXSetupGroup(parent: ConsoleCommandGroup) extends ConsoleCommandGr
}
@Help.Summary(
"Download the genesis state for a sequencer. We exclude the VettedPackages from this initial state. " +
"This method should be used when performing major upgrades."
"Download the genesis state for a sequencer. This method should be used when performing major upgrades."
)
@Help.Description(
"""Download the a topology snapshot which includes all the history for major upgrades. The validFrom and validUntil are set the MinValue.ImmediateSuccessor.
|timestamp: If not specified, the max effective time of the latest topology transaction is used. Otherwise, the given timestamp is used.
|""".stripMargin
)
def genesis_state_for_sequencer(
timestamp: Option[CantonTimestamp] = None

View File

@ -31,7 +31,6 @@ import com.digitalasset.canton.tracing.TraceContext
import scala.collection.concurrent.TrieMap
import scala.concurrent.{ExecutionContext, Future, Promise, blocking}
import scala.util.{Failure, Success}
/** Group of CantonNodes of the same type (domains, participants, sequencers). */
trait Nodes[+Node <: CantonNode, +NodeBootstrap <: CantonNodeBootstrap[Node]]
@ -180,13 +179,7 @@ class ManagedNodes[
import com.digitalasset.canton.util.Thereafter.syntax.*
promise.completeWith(startup.value)
// remove node upon failure
startup.thereafter {
case Success(Right(_)) => ()
case Success(Left(_)) =>
nodes.remove(name).discard
case Failure(_) =>
nodes.remove(name).discard
}
startup.thereafterSuccessOrFailure(_ => (), nodes.remove(name).discard)
}
blocking(synchronized {

View File

@ -320,6 +320,12 @@ object FutureUnlessShutdownImpl {
): FutureUnlessShutdown[A] = {
FutureUnlessShutdown(ThereafterAsync[Future].thereafterF(f.unwrap)(body))
}
override def maybeContent[A](content: FutureUnlessShutdownThereafterContent[A]): Option[A] =
content match {
case Success(UnlessShutdown.Outcome(x)) => Some(x)
case _ => None
}
}
/** Use a type synonym instead of a type lambda so that the Scala compiler does not get confused during implicit resolution,

View File

@ -47,13 +47,15 @@ object DomainParameters {
final case class WithValidity[+P](
validFrom: CantonTimestamp,
validUntil: Option[CantonTimestamp],
serial: PositiveInt,
parameter: P,
) {
def map[T](f: P => T): WithValidity[T] =
WithValidity(validFrom, validUntil, serial, f(parameter))
WithValidity(validFrom, validUntil, f(parameter))
def isValidAt(ts: CantonTimestamp) = validFrom < ts && validUntil.forall(ts <= _)
def emptyInterval: Boolean = validUntil.contains(validFrom)
}
final case class MaxRequestSize(value: NonNegativeInt) extends AnyVal {
def unwrap = value.unwrap
}
@ -791,17 +793,15 @@ object DynamicDomainParameters extends HasProtocolVersionedCompanion[DynamicDoma
*
* @param validFrom Start point of the validity interval (exclusive)
* @param validUntil End point of the validity interval (inclusive)
* @param serial The serial number of the corresponding topology transaction. It's incremented for each domain change.
*/
final case class DynamicDomainParametersWithValidity(
parameters: DynamicDomainParameters,
validFrom: CantonTimestamp,
validUntil: Option[CantonTimestamp],
serial: PositiveInt,
domainId: DomainId,
) {
def map[T](f: DynamicDomainParameters => T): DomainParameters.WithValidity[T] =
DomainParameters.WithValidity(validFrom, validUntil, serial, f(parameters))
DomainParameters.WithValidity(validFrom, validUntil, f(parameters))
def isValidAt(ts: CantonTimestamp): Boolean =
validFrom < ts && validUntil.forall(ts <= _)

View File

@ -4,7 +4,6 @@
package com.digitalasset.canton.sequencing.handlers
import com.digitalasset.canton.config.RequireTypes.PositiveInt
import com.digitalasset.canton.lifecycle.UnlessShutdown
import com.digitalasset.canton.metrics.SequencerClientMetrics
import com.digitalasset.canton.sequencing.ApplicationHandler
import com.digitalasset.canton.sequencing.protocol.Envelope
@ -12,7 +11,6 @@ import com.digitalasset.canton.util.Thereafter.syntax.*
import java.util.concurrent.{ArrayBlockingQueue, BlockingQueue}
import scala.concurrent.{ExecutionContext, blocking}
import scala.util.Success
object ThrottlingApplicationEventHandler {
@ -49,13 +47,13 @@ object ThrottlingApplicationEventHandler {
metrics.handler.actualInFlightEventBatches.dec()
}
}
.thereafter {
case Success(UnlessShutdown.Outcome(_)) =>
// don't forget to unblock other threads on shutdown or exception of the outer future such that we don't block other threads
case _ =>
.thereafterSuccessOrFailure(
_ => (), {
// don't forget to unblock other threads on shutdown or exception of the outer future such that we don't block other threads
queue.remove().discard
metrics.handler.actualInFlightEventBatches.dec()
}
},
)
}
}
}

View File

@ -182,7 +182,6 @@ class StoreBasedTopologySnapshotX(
mapping.parameters,
storedTx.validFrom.value,
storedTx.validUntil.map(_.value),
storedTx.serial,
mapping.domain,
)
}
@ -210,7 +209,6 @@ class StoreBasedTopologySnapshotX(
dps.parameters,
storedTx.validFrom.value,
storedTx.validUntil.map(_.value),
storedTx.serial,
dps.domain,
)
}

View File

@ -73,10 +73,7 @@ final class StoreBasedTopologyStateForInitializationService(
// This is not a mistake: all transactions with `sequenced <= validFrom` need to come from this onboarding snapshot
// because the member only receives transactions once its onboarding transaction becomes effective.
val referenceSequencedTime = SequencedTime(effectiveFrom.value)
domainTopologyStore.findEssentialStateAtSequencedTime(
referenceSequencedTime,
excludeMappings = Nil,
)
domainTopologyStore.findEssentialStateAtSequencedTime(referenceSequencedTime)
}
// TODO(#12390) should this error out if nothing can be found?
.getOrElse(Future.successful(StoredTopologyTransactionsX.empty))

View File

@ -248,8 +248,7 @@ abstract class TopologyStoreX[+StoreID <: TopologyStoreId](implicit
): Future[Option[StoredTopologyTransactionX[TopologyChangeOpX.Replace, DomainTrustCertificateX]]]
def findEssentialStateAtSequencedTime(
asOfInclusive: SequencedTime,
excludeMappings: Seq[TopologyMappingX.Code],
asOfInclusive: SequencedTime
)(implicit traceContext: TraceContext): Future[GenericStoredTopologyTransactionsX]
protected def signedTxFromStoredTx(

View File

@ -452,16 +452,14 @@ class DbTopologyStoreX[StoreId <: TopologyStoreId](
}
override def findEssentialStateAtSequencedTime(
asOfInclusive: SequencedTime,
excludeMappings: Seq[TopologyMappingX.Code],
asOfInclusive: SequencedTime
)(implicit
traceContext: TraceContext
): Future[GenericStoredTopologyTransactionsX] = {
val timeFilter = sql" AND sequenced <= ${asOfInclusive.value}"
val mappingFilter = excludeMapping(excludeMappings.toSet)
logger.debug(s"Querying essential state as of asOfInclusive")
queryForTransactions(timeFilter ++ mappingFilter, "essentialState").map(
queryForTransactions(timeFilter, "essentialState").map(
_.asSnapshotAtMaxEffectiveTime.retainAuthorizedHistoryAndEffectiveProposals
)
}
@ -712,14 +710,6 @@ class DbTopologyStoreX[StoreId <: TopologyStoreId](
.intercalate(sql", ") ++ sql")"
}
private def excludeMapping(types: Set[TopologyMappingX.Code]): SQLActionBuilderChain = {
if (types.isEmpty) sql""
else
sql" AND transaction_type NOT IN (" ++ types.toSeq
.map(t => sql"$t")
.intercalate(sql", ") ++ sql")"
}
private def findAsOfExclusive(
effective: EffectiveTime,
subQuery: SQLActionBuilder,

View File

@ -445,8 +445,7 @@ class InMemoryTopologyStoreX[+StoreId <: TopologyStoreId](
}
override def findEssentialStateAtSequencedTime(
asOfInclusive: SequencedTime,
excludeMappings: Seq[TopologyMappingX.Code],
asOfInclusive: SequencedTime
)(implicit
traceContext: TraceContext
): Future[GenericStoredTopologyTransactionsX] = {
@ -456,9 +455,7 @@ class InMemoryTopologyStoreX[+StoreId <: TopologyStoreId](
blocking(synchronized {
topologyTransactionStore.toSeq
}),
entry =>
entry.sequenced <= asOfInclusive &&
!excludeMappings.contains(entry.mapping.code),
entry => entry.sequenced <= asOfInclusive,
).map(
// 2. transform the result such that the validUntil fields are set as they were at maxEffective time of the snapshot
_.asSnapshotAtMaxEffectiveTime

View File

@ -27,13 +27,7 @@ object EitherTUtil {
def onErrorOrFailure[A, B](errorHandler: () => Unit)(
fn: => EitherT[Future, A, B]
)(implicit executionContext: ExecutionContext): EitherT[Future, A, B] =
fn.thereafter {
case Failure(_) =>
errorHandler()
case Success(Left(_)) =>
errorHandler()
case _ => ()
}
fn.thereafterSuccessOrFailure(_ => (), errorHandler())
def onErrorOrFailureUnlessShutdown[A, B](
errorHandler: Either[Throwable, A] => Unit,

View File

@ -38,6 +38,13 @@ trait Thereafter[F[_]] {
* If `body` throws, the result includes the thrown exception.
*/
def thereafter[A](f: F[A])(body: Content[A] => Unit): F[A]
/** Returns the single `A` in `content` if any. */
def maybeContent[A](content: Content[A]): Option[A]
def thereafterSuccessOrFailure[A](f: F[A])(success: A => Unit, failure: => Unit): F[A] =
thereafter(f)(result => maybeContent(result).fold(failure)(success))
}
/** Extension of [[Thereafter]] that adds the possibility to run an asynchronous piece of code afterwards
@ -53,6 +60,11 @@ trait ThereafterAsync[F[_]] extends Thereafter[F] {
* If `body` produces a failed computation, the result includes the thrown exception.
*/
def thereafterF[A](f: F[A])(body: Content[A] => Future[Unit]): F[A]
def thereafterFSuccessOrFailure[A](
f: F[A]
)(success: A => Future[Unit], failure: => Future[Unit]): F[A] =
thereafterF(f)(result => maybeContent(result).fold(failure)(success))
}
object Thereafter {
@ -71,6 +83,8 @@ object Thereafter {
protected val typeClassInstance: Thereafter.Aux[F, C]
def thereafter(body: C[A] => Unit): F[A] =
typeClassInstance.thereafter(self)(body)
def thereafterSuccessOrFailure(success: A => Unit, failure: => Unit): F[A] =
typeClassInstance.thereafterSuccessOrFailure(self)(success, failure)
}
/** Extension method for instances of [[Thereafter]]. */
@ -98,6 +112,8 @@ object Thereafter {
}
result
}
override def maybeContent[A](content: Try[A]): Option[A] = content.toOption
}
implicit def TryThereafter: Thereafter.Aux[Try, Try] = TryTherafter
@ -109,6 +125,8 @@ object Thereafter {
f: Future[A]
)(body: Try[A] => Unit): Future[A] =
f.transform { result => TryThereafter.thereafter(result)(body) }
override def maybeContent[A](content: Try[A]): Option[A] = content.toOption
}
implicit def futureThereafter(implicit ec: ExecutionContext): Thereafter.Aux[Future, Try] =
new FutureThereafter
@ -123,6 +141,8 @@ object Thereafter {
override type Content[A] = EitherTThereafterContent[FContent, E, A]
override def thereafter[A](f: EitherT[F, E, A])(body: Content[A] => Unit): EitherT[F, E, A] =
EitherT(F.thereafter(f.value)(body))
override def maybeContent[A](content: EitherTThereafterContent[FContent, E, A]): Option[A] =
F.maybeContent(content).flatMap(_.toOption)
}
/** [[Thereafter]] instance lifted through [[cats.data.EitherT]]. */
@ -143,6 +163,8 @@ object Thereafter {
override type Content[A] = OptionTThereafterContent[FContent, A]
override def thereafter[A](f: OptionT[F, A])(body: Content[A] => Unit): OptionT[F, A] =
OptionT(F.thereafter(f.value)(body))
override def maybeContent[A](content: OptionTThereafterContent[FContent, A]): Option[A] =
F.maybeContent(content).flatten
}
/** [[Thereafter]] instance lifted through [[cats.data.OptionT]]. */
@ -180,6 +202,8 @@ object ThereafterAsync {
protected override val typeClassInstance: ThereafterAsync.Aux[F, C]
def thereafterF(body: C[A] => Future[Unit]): F[A] =
typeClassInstance.thereafterF(self)(body)
def thereafterFSuccessOrFailure(success: A => Future[Unit], failure: => Future[Unit]): F[A] =
typeClassInstance.thereafterFSuccessOrFailure(self)(success, failure)
}
class FutureThereafterAsync(implicit ec: ExecutionContext)

View File

@ -5,6 +5,7 @@ package com.daml.ledger.javaapi.data.codegen;
import com.daml.ledger.javaapi.data.Value;
import com.daml.ledger.javaapi.data.codegen.json.JsonLfDecoder;
import com.daml.ledger.javaapi.data.codegen.json.JsonLfEncoder;
import java.util.function.Function;
/**
@ -20,13 +21,16 @@ public final class Choice<Tpl, ArgType, ResType> {
/** The choice name * */
public final String name;
final Function<ArgType, Value> encodeArg;
public final Function<ArgType, Value> encodeArg;
final ValueDecoder<ArgType> argTypeDecoder;
final ValueDecoder<ResType> returnTypeDecoder;
public final ValueDecoder<ArgType> argTypeDecoder;
public final ValueDecoder<ResType> returnTypeDecoder;
final JsonLfDecoder<ArgType> argJsonDecoder;
final JsonLfDecoder<ResType> resultJsonDecoder;
public final JsonLfDecoder<ArgType> argJsonDecoder;
public final JsonLfDecoder<ResType> resultJsonDecoder;
public final Function<ArgType, JsonLfEncoder> argJsonEncoder;
public final Function<ResType, JsonLfEncoder> resultJsonEncoder;
private Choice(
final String name,
@ -34,13 +38,17 @@ public final class Choice<Tpl, ArgType, ResType> {
ValueDecoder<ArgType> argTypeDecoder,
ValueDecoder<ResType> returnTypeDecoder,
JsonLfDecoder<ArgType> argJsonDecoder,
JsonLfDecoder<ResType> resultJsonDecoder) {
JsonLfDecoder<ResType> resultJsonDecoder,
Function<ArgType, JsonLfEncoder> argJsonEncoder,
Function<ResType, JsonLfEncoder> resultJsonEncoder) {
this.name = name;
this.encodeArg = encodeArg;
this.argTypeDecoder = argTypeDecoder;
this.returnTypeDecoder = returnTypeDecoder;
this.argJsonDecoder = argJsonDecoder;
this.resultJsonDecoder = resultJsonDecoder;
this.argJsonEncoder = argJsonEncoder;
this.resultJsonEncoder = resultJsonEncoder;
}
/**
@ -58,7 +66,35 @@ public final class Choice<Tpl, ArgType, ResType> {
final Function<ArgType, Value> encodeArg,
ValueDecoder<ArgType> argTypeDecoder,
ValueDecoder<ResType> returnTypeDecoder) {
return create(name, encodeArg, argTypeDecoder, returnTypeDecoder, null, null);
return create(name, encodeArg, argTypeDecoder, returnTypeDecoder, null, null, null, null);
}
/**
* <strong>INTERNAL API</strong>: this is meant for use by <a
* href="https://docs.daml.com/app-dev/bindings-java/codegen.html">the Java code generator</a>,
* and <em>should not be referenced directly</em>. Applications should refer to the generated
* {@code CHOICE_*} fields on templates or interfaces.
*
* <p>TODO(raphael-speyer-da): Delete this method altogether, once codegen uses the other one.
*
* @hidden
*/
public static <Tpl, ArgType, ResType> Choice<Tpl, ArgType, ResType> create(
final String name,
final Function<ArgType, Value> encodeArg,
ValueDecoder<ArgType> argTypeDecoder,
ValueDecoder<ResType> returnTypeDecoder,
JsonLfDecoder<ArgType> argJsonDecoder,
JsonLfDecoder<ResType> resultJsonDecoder) {
return create(
name,
encodeArg,
argTypeDecoder,
returnTypeDecoder,
argJsonDecoder,
resultJsonDecoder,
null,
null);
}
/**
@ -75,8 +111,17 @@ public final class Choice<Tpl, ArgType, ResType> {
ValueDecoder<ArgType> argTypeDecoder,
ValueDecoder<ResType> returnTypeDecoder,
JsonLfDecoder<ArgType> argJsonDecoder,
JsonLfDecoder<ResType> resultJsonDecoder) {
JsonLfDecoder<ResType> resultJsonDecoder,
Function<ArgType, JsonLfEncoder> argJsonEncoder,
Function<ResType, JsonLfEncoder> resultJsonEncoder) {
return new Choice<>(
name, encodeArg, argTypeDecoder, returnTypeDecoder, argJsonDecoder, resultJsonDecoder);
name,
encodeArg,
argTypeDecoder,
returnTypeDecoder,
argJsonDecoder,
resultJsonDecoder,
argJsonEncoder,
resultJsonEncoder);
}
}

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --target=2.1
name: CantonExamples

View File

@ -5,7 +5,6 @@ package com.digitalasset.canton.topology
import cats.data.EitherT
import cats.syntax.either.*
import com.digitalasset.canton.config.RequireTypes.PositiveInt
import com.digitalasset.canton.crypto.*
import com.digitalasset.canton.data.CantonTimestamp
import com.digitalasset.canton.protocol.{DomainParameters, DynamicDomainParameters}
@ -33,14 +32,12 @@ class TestingIdentityFactoryTest extends AnyWordSpec with BaseTest with HasExecu
private val domainParameters1 = DomainParameters.WithValidity(
CantonTimestamp.Epoch,
Some(CantonTimestamp.ofEpochSecond(10)),
PositiveInt.one,
increaseConfirmationResponseTimeout(defaultDynamicDomainParameters),
)
private val domainParameters2 = DomainParameters.WithValidity(
CantonTimestamp.ofEpochSecond(10),
None,
PositiveInt.two,
increaseConfirmationResponseTimeout(domainParameters1.parameter),
)

View File

@ -306,43 +306,6 @@ trait TopologyStoreXTest extends AsyncWordSpec with TopologyStoreXTestBase {
)
}
}
"able to findEssentialStateAtSequencedTime" in {
val store = mk()
for {
_ <- update(store, ts2, add = Seq(tx2_OTK))
_ <- update(store, ts5, add = Seq(tx5_DTC))
_ <- update(store, ts6, add = Seq(tx6_MDS))
proposalTransactions <- store.findEssentialStateAtSequencedTime(
asOfInclusive = SequencedTime(ts6),
excludeMappings = Nil,
)
proposalTransactionsFiltered <- store.findEssentialStateAtSequencedTime(
asOfInclusive = SequencedTime(ts6),
excludeMappings = TopologyMappingX.Code.all.diff(
Seq(DomainTrustCertificateX.code, OwnerToKeyMappingX.code)
),
)
} yield {
expectTransactions(
proposalTransactions,
Seq(
tx2_OTK,
tx5_DTC,
tx6_MDS,
),
)
expectTransactions(
proposalTransactionsFiltered,
Seq(
tx2_OTK,
tx5_DTC,
),
)
}
}
"able to inspect" in {
val store = mk()
@ -460,8 +423,7 @@ trait TopologyStoreXTest extends AsyncWordSpec with TopologyStoreXTestBase {
)
essentialStateTransactions <- store.findEssentialStateAtSequencedTime(
asOfInclusive = SequencedTime(ts5),
excludeMappings = Nil,
SequencedTime(ts5)
)
upcomingTransactions <- store.findUpcomingEffectiveChanges(asOfInclusive = ts4)

View File

@ -61,7 +61,6 @@ class TrafficBalanceSubmissionHandlerTest
DomainParameters.WithValidity(
validFrom = CantonTimestamp.Epoch.minusSeconds(1),
validUntil = None,
serial = PositiveInt.one,
parameter = DynamicDomainParameters
.defaultValues(testedProtocolVersion)
.tryUpdate(trafficControlParameters = Some(trafficParams)),

View File

@ -85,6 +85,17 @@ trait ThereafterTest extends AnyWordSpec with BaseTest {
Try(fixture.theContent(z)) shouldBe Failure(ex)
}
}
"theContent" should {
"return the content" in {
forEvery(fixture.contents) { content =>
sut.maybeContent(content) match {
case Some(x) => x shouldBe fixture.theContent(content)
case None => a[Throwable] should be thrownBy fixture.theContent(content)
}
}
}
}
}
def thereafterAsync[F[_], Content[_]](

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --target=2.1
name: ai-analysis

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --target=2.1
name: bank

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --target=2.1
name: doctor

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --target=2.1
name: health-insurance

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --target=2.1
name: medical-records

View File

@ -34,7 +34,7 @@ service SequencerAdministrationService {
// the returned bytestring can be used directly to initialize the given sequencer later on
rpc OnboardingState(OnboardingStateRequest) returns (OnboardingStateResponse);
// Fetch the genesis state for a given sequencer. In the genesis state, we exclude VettedPackages transactions.
// Fetch the genesis state for a given sequencer.
// the returned bytestring can be used directly to initialize the given sequencer later on
rpc GenesisState(GenesisStateRequest) returns (GenesisStateResponse);
@ -109,7 +109,7 @@ message OnboardingStateResponse {
}
}
message GenesisStateRequest {
// Optional - the effective time used to fetch the topology transactions
// Optional - the effective time used to fetch the topology transactions. If not provided the effective time of the last topology transaction is used.
google.protobuf.Timestamp timestamp = 1;
}

View File

@ -243,17 +243,14 @@ class BlockSequencerStateManager(
NotUsed,
] = {
implicit val traceContext: TraceContext = TraceContext.empty
Flow[Traced[OrderedBlockUpdate[UnsignedChunkEvents]]].mapAsyncAndDrainUS(parallelism =
chunkSigningParallelism
)(
_.traverseWithTraceContext { implicit traceContext => update =>
update match {
Flow[Traced[OrderedBlockUpdate[UnsignedChunkEvents]]]
.mapAsyncAndDrainUS(parallelism = chunkSigningParallelism)(
_.traverse {
case chunk: ChunkUpdate[UnsignedChunkEvents] =>
chunk.events.parTraverse(bug.signChunkEvents).map(signed => chunk.copy(events = signed))
case complete: CompleteBlockUpdate => FutureUnlessShutdown.pure(complete)
}
}
)
)
}
override def applyBlockUpdate

View File

@ -15,6 +15,7 @@ import com.digitalasset.canton.domain.sequencing.sequencer.InFlightAggregationUp
import com.digitalasset.canton.domain.sequencing.sequencer.block.BlockSequencer.LocalEvent
import com.digitalasset.canton.sequencing.protocol.SequencedEventTrafficState
import com.digitalasset.canton.topology.Member
import com.digitalasset.canton.tracing.TraceContext
import com.digitalasset.canton.util.MapsUtil
import scala.collection.MapView
@ -116,6 +117,7 @@ final case class UnsignedChunkEvents(
sequencingTimestamp: CantonTimestamp,
sequencingSnapshot: SyncCryptoApi,
trafficStates: MapView[Member, SequencedEventTrafficState],
traceContext: TraceContext,
) extends ChunkEvents {
override def members: Set[Member] = events.keySet
override def counters: Map[Member, SequencerCounter] = events.fmap(_.counter)

View File

@ -96,8 +96,7 @@ trait BlockUpdateGenerator {
): FutureUnlessShutdown[(InternalState, OrderedBlockUpdate[UnsignedChunkEvents])]
def signChunkEvents(events: UnsignedChunkEvents)(implicit
ec: ExecutionContext,
traceContext: TraceContext,
ec: ExecutionContext
): FutureUnlessShutdown[SignedChunkEvents]
}
@ -611,6 +610,7 @@ class BlockUpdateGeneratorImpl(
sequencingTimestamp,
sequencingSnapshot,
trafficUpdatedState.trafficState.view.mapValues(_.toSequencedEventTrafficState),
traceContext,
)
(
unsignedEvents +: reversedEvents,
@ -1355,8 +1355,7 @@ class BlockUpdateGeneratorImpl(
}
override def signChunkEvents(unsignedEvents: UnsignedChunkEvents)(implicit
ec: ExecutionContext,
traceContext: TraceContext,
ec: ExecutionContext
): FutureUnlessShutdown[SignedChunkEvents] = {
val UnsignedChunkEvents(
sender,
@ -1365,7 +1364,9 @@ class BlockUpdateGeneratorImpl(
sequencingTimestamp,
sequencingSnapshot,
trafficStates,
submissionRequestTraceContext,
) = unsignedEvents
implicit val traceContext: TraceContext = submissionRequestTraceContext
val signingTimestamp = signingSnapshot.ipsSnapshot.timestamp
val signedEventsF = maybeLowerTopologyTimestampBound match {
case Some(bound) if bound > signingTimestamp =>
@ -1430,16 +1431,15 @@ class BlockUpdateGeneratorImpl(
)
)
.map { signedContent =>
val trafficStateO = Option
.when(!unifiedSequencer || member == sender) { // only include traffic state for the sender
trafficStates.getOrElse(
member,
ErrorUtil.invalidState(s"Sender $sender unknown by rate limiter."),
)
}
member -> OrdinarySequencedEvent(signedContent, trafficStateO)(
traceContext
)
// only include traffic state for the sender
val trafficStateO = Option.when(!unifiedSequencer || member == sender) {
trafficStates.getOrElse(
member,
ErrorUtil.invalidState(s"Sender $sender unknown by rate limiter."),
)
}
member ->
OrdinarySequencedEvent(signedContent, trafficStateO)(traceContext)
}
}
)

View File

@ -172,10 +172,7 @@ class GrpcSequencerAdministrationService(
sequencerSnapshot <- sequencer.snapshot(referenceEffective.value)
topologySnapshot <- EitherT.right[String](
topologyStore.findEssentialStateAtSequencedTime(
SequencedTime(sequencerSnapshot.lastTs),
excludeMappings = Nil,
)
topologyStore.findEssentialStateAtSequencedTime(SequencedTime(sequencerSnapshot.lastTs))
)
} yield (topologySnapshot, sequencerSnapshot))
.fold[v30.OnboardingStateResponse](
@ -227,11 +224,7 @@ class GrpcSequencerAdministrationService(
}
topologySnapshot <- EitherT.right[String](
topologyStore.findEssentialStateAtSequencedTime(
SequencedTime(sequencedTimestamp),
// we exclude vetted packages from the genesis state because we need to upload them again anyway
excludeMappings = Seq(TopologyMappingX.Code.VettedPackagesX),
)
topologyStore.findEssentialStateAtSequencedTime(SequencedTime(sequencedTimestamp))
)
// reset effective time and sequenced time if we are initializing the sequencer from the beginning
genesisState: StoredTopologyTransactionsX[TopologyChangeOpX, TopologyMappingX] =

View File

@ -49,7 +49,6 @@ class MediatorEventStageProcessorTest extends AsyncWordSpec with BaseTest with H
DomainParameters.WithValidity(
CantonTimestamp.Epoch,
None,
PositiveInt.one,
initialDomainParameters.tryUpdate(confirmationResponseTimeout = confirmationResponseTimeout),
)
)
@ -233,7 +232,6 @@ class MediatorEventStageProcessorTest extends AsyncWordSpec with BaseTest with H
DomainParameters.WithValidity(
CantonTimestamp.Epoch,
Some(CantonTimestamp.ofEpochSecond(5)),
PositiveInt.two,
initialDomainParameters.tryUpdate(confirmationResponseTimeout =
NonNegativeFiniteDuration.tryOfSeconds(4)
),
@ -241,7 +239,6 @@ class MediatorEventStageProcessorTest extends AsyncWordSpec with BaseTest with H
DomainParameters.WithValidity(
CantonTimestamp.ofEpochSecond(5),
None,
PositiveInt.three,
initialDomainParameters.tryUpdate(confirmationResponseTimeout =
NonNegativeFiniteDuration.tryOfSeconds(6)
),

View File

@ -5,7 +5,6 @@ package com.digitalasset.canton.domain.mediator
import cats.data.NonEmptySeq
import com.digitalasset.canton.BaseTest
import com.digitalasset.canton.config.RequireTypes.PositiveInt
import com.digitalasset.canton.data.CantonTimestamp
import com.digitalasset.canton.domain.mediator.Mediator.{Safe, SafeUntil}
import com.digitalasset.canton.protocol.{DynamicDomainParametersWithValidity, TestDomainParameters}
@ -35,7 +34,6 @@ class MediatorTest extends AnyWordSpec with BaseTest {
defaultParameters,
CantonTimestamp.Epoch,
None,
serial = PositiveInt.one,
domainId,
)
@ -56,7 +54,6 @@ class MediatorTest extends AnyWordSpec with BaseTest {
defaultParameters,
validFrom,
validUntil,
PositiveInt.one,
domainId,
)
@ -81,7 +78,6 @@ class MediatorTest extends AnyWordSpec with BaseTest {
defaultParameters,
origin,
None,
PositiveInt.one,
domainId,
)
@ -99,7 +95,6 @@ class MediatorTest extends AnyWordSpec with BaseTest {
defaultParameters,
origin,
Some(dpChangeTs),
PositiveInt.one,
domainId,
)
@ -140,7 +135,6 @@ class MediatorTest extends AnyWordSpec with BaseTest {
defaultParameters,
origin,
Some(dpChangeTs1),
PositiveInt.one,
domainId,
),
// This one prevents pruning for some time
@ -148,14 +142,12 @@ class MediatorTest extends AnyWordSpec with BaseTest {
parametersWith(hugeTimeout),
dpChangeTs1,
Some(dpChangeTs2),
PositiveInt.two,
domainId,
),
DynamicDomainParametersWithValidity(
defaultParameters,
dpChangeTs2,
None,
PositiveInt.three,
domainId,
),
)

View File

@ -1,9 +1,9 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
build-options:
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --enable-interfaces=yes
name: carbonv1-tests
source: .
version: 3.0.0
dependencies:
dependencies:
- daml-prim
- daml-stdlib

View File

@ -1,11 +1,11 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
build-options:
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --enable-interfaces=yes
name: carbonv2-tests
data-dependencies:
data-dependencies:
- ../../../../scala-2.13/resource_managed/main/carbonv1-tests-3.0.0.dar
source: .
version: 3.0.0
dependencies:
dependencies:
- daml-prim
- daml-stdlib

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
name: experimental-tests
source: .
version: 3.0.0

View File

@ -1,9 +1,9 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
build-options:
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --enable-interfaces=yes
name: model-tests
source: .
version: 3.0.0
dependencies:
dependencies:
- daml-prim
- daml-stdlib

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
name: package-management-tests
source: .
version: 3.0.0

View File

@ -1,9 +1,9 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
build-options:
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --enable-interfaces=yes
name: semantic-tests
source: .
version: 3.0.0
dependencies:
dependencies:
- daml-prim
- daml-stdlib

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
name: upgrade-tests
source: .
version: 1.0.0

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
name: upgrade-tests
source: .
version: 2.0.0

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
name: upgrade-tests
source: .
version: 3.0.0

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --target=2.1
name: JsonEncodingTest

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --target=2.dev
name: JsonEncodingTestDev

View File

@ -1,4 +1,4 @@
sdk-version: 3.0.0-snapshot.20240320.12926.0.v99c6b363
sdk-version: 3.0.0-snapshot.20240324.12944.0.vacdb2970
build-options:
- --target=2.1
name: AdminWorkflows

View File

@ -202,6 +202,11 @@ private[transfer] class TransferInValidation(
_ <- EitherT.fromEither[Future](checkSubmitterIsStakeholder)
res <-
if (transferringParticipant) {
// This happens either in case of malicious transfer-ins (incorrectly declared transferring participants)
// OR if the transfer data has been pruned.
// The transfer-in should be rejected due to other validations (e.g. conflict detection), but
// we could code this more defensively at some point
val targetIps = targetCrypto.ipsSnapshot
val confirmingPartiesF = targetIps
.canConfirm(

View File

@ -3,7 +3,6 @@
package com.digitalasset.canton.participant.pruning
import com.digitalasset.canton.config.RequireTypes.PositiveInt
import com.digitalasset.canton.data.{CantonTimestamp, CantonTimestampSecond}
import com.digitalasset.canton.participant.pruning.SortedReconciliationIntervals.ReconciliationInterval
import com.digitalasset.canton.protocol.DomainParameters
@ -163,20 +162,13 @@ object SortedReconciliationIntervals {
validUntil: CantonTimestamp,
): Either[String, SortedReconciliationIntervals] = {
val sortedReconciliationIntervals =
reconciliationIntervals.sortBy(interval => (interval.serial, interval.validFrom))(
implicitly[Ordering[(PositiveInt, CantonTimestamp)]].reverse
)
reconciliationIntervals.sortBy(_.validFrom)(implicitly[Ordering[CantonTimestamp]].reverse)
val overlappingValidityIntervals =
sortedReconciliationIntervals
// Right now during a major upgrade, we reset the valid from and valid until to MinValue.immediateSuccessor, so we are not
// able to sort the transactions anymore. We end up with transactions that seems to never have been valid because validFrom = validUntil.
// TODO(i18053): This is a temporary fix to avoid overlapping interval error, when it's not.
.filterNot(p =>
p.validUntil.forall(
_ == p.validFrom
) && p.validFrom <= CantonTimestamp.MinValue.immediateSuccessor
)
// filter the transaction with empty interval, we cannot sort them using validFrom.
// When we import topology transactions during an upgrade, we set the validFrom and validUntil to MinValue.immediateSuccessor which leads to empty intervals.
.filterNot(_.emptyInterval)
.sliding(2)
.collectFirst { // If validUntil is None it means no end validity, so it should be the first interval
case Seq(p1, p2) if p2.validUntil.forall(_ > p1.validFrom) => Some((p1, p2))
@ -192,7 +184,6 @@ object SortedReconciliationIntervals {
case DomainParameters.WithValidity(
validFrom,
validUntil,
_serial,
reconciliationInterval,
) =>
ReconciliationInterval(validFrom, validUntil, reconciliationInterval)

View File

@ -195,7 +195,6 @@ class ProtocolProcessorTest
DynamicDomainParameters.initialValues(NonNegativeFiniteDuration.Zero, testedProtocolVersion),
CantonTimestamp.MinValue,
None,
PositiveInt.one,
domain,
)

View File

@ -7,7 +7,6 @@ import cats.Eval
import cats.implicits.*
import com.daml.nonempty.{NonEmpty, NonEmptyUtil}
import com.digitalasset.canton.concurrent.FutureSupervisor
import com.digitalasset.canton.config.RequireTypes.PositiveInt
import com.digitalasset.canton.config.{CachingConfigs, DefaultProcessingTimeouts}
import com.digitalasset.canton.crypto.provider.symbolic.SymbolicCrypto
import com.digitalasset.canton.crypto.{DomainSnapshotSyncCryptoApi, TestHash}
@ -797,7 +796,6 @@ final class TransferOutProcessingStepsTest
DynamicDomainParameters.defaultValues(testedProtocolVersion),
CantonTimestamp.MinValue,
None,
PositiveInt.one,
targetDomain.unwrap,
)

View File

@ -289,7 +289,6 @@ sealed trait AcsCommitmentProcessorBaseTest
.sortBy(_.validFrom)
.headOption
.fold(Some(CantonTimestamp.MaxValue))(param => Some(param.validFrom)),
serial = PositiveInt.MaxValue,
parameter = defaultParameters.tryUpdate(acsCommitmentsCatchUpConfigParameter =
acsCommitmentsCatchUpConfig
),
@ -2213,7 +2212,6 @@ class AcsCommitmentProcessorTest
val startConfigWithValidity = DomainParameters.WithValidity(
validFrom = CantonTimestamp.MinValue,
validUntil = Some(CantonTimestamp.MaxValue),
serial = PositiveInt.MaxValue,
parameter = defaultParameters.tryUpdate(acsCommitmentsCatchUpConfigParameter =
Some(startConfig)
),
@ -2298,7 +2296,6 @@ class AcsCommitmentProcessorTest
val startConfigWithValidity = DomainParameters.WithValidity(
validFrom = testSequences.head.addMicros(-1),
validUntil = Some(CantonTimestamp.MaxValue),
serial = PositiveInt.MaxValue,
parameter =
defaultParameters.tryUpdate(acsCommitmentsCatchUpConfigParameter = Some(startConfig)),
)
@ -2370,7 +2367,6 @@ class AcsCommitmentProcessorTest
val startConfigWithValidity = DomainParameters.WithValidity(
validFrom = testSequences.head.addMicros(-1),
validUntil = Some(CantonTimestamp.MaxValue),
serial = PositiveInt.MaxValue,
parameter =
defaultParameters.tryUpdate(acsCommitmentsCatchUpConfigParameter = Some(startConfig)),
)
@ -2651,7 +2647,6 @@ class AcsCommitmentProcessorTest
val changedConfigWithValidity = DomainParameters.WithValidity(
validFrom = testSequences.last.head,
validUntil = None,
serial = PositiveInt.MaxValue,
parameter =
defaultParameters.tryUpdate(acsCommitmentsCatchUpConfigParameter = Some(midConfig)),
)
@ -2659,7 +2654,6 @@ class AcsCommitmentProcessorTest
val disabledConfigWithValidity = DomainParameters.WithValidity(
validFrom = testSequences.apply(1).head,
validUntil = Some(testSequences.apply(1).last),
serial = PositiveInt.one,
parameter =
defaultParameters.tryUpdate(acsCommitmentsCatchUpConfigParameter = Some(disabledConfig)),
)
@ -2750,7 +2744,6 @@ class AcsCommitmentProcessorTest
val startConfigWithValidity = DomainParameters.WithValidity(
validFrom = testSequences.head.addMicros(-1),
validUntil = Some(changeConfigTimestamp),
serial = PositiveInt.one,
parameter =
defaultParameters.tryUpdate(acsCommitmentsCatchUpConfigParameter = Some(startConfig)),
)
@ -2758,7 +2751,6 @@ class AcsCommitmentProcessorTest
val disabledConfigWithValidity = DomainParameters.WithValidity(
validFrom = changeConfigTimestamp,
validUntil = None,
serial = PositiveInt.MaxValue,
parameter = defaultParameters.tryUpdate(acsCommitmentsCatchUpConfigParameter = None),
)
val (processor, store, sequencerClient, changes) =
@ -2829,7 +2821,6 @@ class AcsCommitmentProcessorTest
val startConfigWithValidity = DomainParameters.WithValidity(
validFrom = testSequences.head.addMicros(-1),
validUntil = Some(changeConfigTimestamp),
serial = PositiveInt.one,
parameter =
defaultParameters.tryUpdate(acsCommitmentsCatchUpConfigParameter = Some(startConfig)),
)
@ -2839,7 +2830,6 @@ class AcsCommitmentProcessorTest
val changeConfigWithValidity = DomainParameters.WithValidity(
validFrom = changeConfigTimestamp,
validUntil = None,
serial = PositiveInt.MaxValue,
parameter =
defaultParameters.tryUpdate(acsCommitmentsCatchUpConfigParameter = Some(changeConfig)),
)

View File

@ -5,7 +5,6 @@ package com.digitalasset.canton.participant.pruning
import com.digitalasset.canton.BaseTest
import com.digitalasset.canton.concurrent.FutureSupervisor
import com.digitalasset.canton.config.RequireTypes.PositiveInt
import com.digitalasset.canton.data.{CantonTimestamp, CantonTimestampSecond}
import com.digitalasset.canton.protocol.messages.CommitmentPeriod
import com.digitalasset.canton.protocol.{
@ -34,7 +33,6 @@ trait SortedReconciliationIntervalsHelpers {
validFrom: Long,
validTo: Long,
reconciliationInterval: Long,
serial: PositiveInt,
protocolVersion: ProtocolVersion,
): DynamicDomainParametersWithValidity =
DynamicDomainParametersWithValidity(
@ -45,7 +43,6 @@ trait SortedReconciliationIntervalsHelpers {
),
fromEpoch(validFrom),
Some(fromEpoch(validTo)),
serial,
defaultDomainId,
)
@ -62,7 +59,6 @@ trait SortedReconciliationIntervalsHelpers {
),
fromEpoch(validFrom),
None,
PositiveInt.MaxValue,
defaultDomainId,
)
@ -74,7 +70,6 @@ trait SortedReconciliationIntervalsHelpers {
DomainParameters.WithValidity(
validFrom,
Some(validTo),
serial = PositiveInt.one,
PositiveSeconds.tryOfSeconds(reconciliationInterval),
)
@ -85,7 +80,6 @@ trait SortedReconciliationIntervalsHelpers {
DomainParameters.WithValidity(
validFrom,
None,
serial = PositiveInt.MaxValue,
PositiveSeconds.tryOfSeconds(reconciliationInterval),
)
@ -97,7 +91,6 @@ trait SortedReconciliationIntervalsHelpers {
defaultParameters.tryUpdate(reconciliationInterval = reconciliationInterval),
validFrom,
None,
serial = PositiveInt.MaxValue,
defaultDomainId,
)

View File

@ -4,7 +4,6 @@
package com.digitalasset.canton.participant.pruning
import com.digitalasset.canton.concurrent.FutureSupervisor
import com.digitalasset.canton.config.RequireTypes.PositiveInt
import com.digitalasset.canton.data.CantonTimestamp
import com.digitalasset.canton.protocol.messages.CommitmentPeriod
import com.digitalasset.canton.time.{NonNegativeFiniteDuration, PositiveSeconds, SimClock}
@ -29,7 +28,7 @@ class SortedReconciliationIntervalsProviderTest
val clock = new SimClock(fromEpoch(0), loggerFactory)
val domainParameters = Vector(
mkDynamicDomainParameters(0, 10, 1, PositiveInt.one, protocolVersion),
mkDynamicDomainParameters(0, 10, 1, protocolVersion),
mkDynamicDomainParameters(10, 2, protocolVersion),
)
@ -111,7 +110,7 @@ class SortedReconciliationIntervalsProviderTest
val clock = new SimClock(fromEpoch(0), loggerFactory)
val domainParameters = Vector(
mkDynamicDomainParameters(0, 13, 2, PositiveInt.one, testedProtocolVersion),
mkDynamicDomainParameters(0, 13, 2, testedProtocolVersion),
mkDynamicDomainParameters(13, 9, testedProtocolVersion),
)

View File

@ -104,7 +104,6 @@ final case class TestingTopologyX(
DomainParameters.WithValidity(
validFrom = CantonTimestamp.Epoch,
validUntil = None,
serial = PositiveInt.one,
parameter = DefaultTestIdentities.defaultDynamicDomainParameters,
)
),
@ -738,7 +737,6 @@ object TestingIdentityFactoryX {
DomainParameters.WithValidity(
validFrom = CantonTimestamp.Epoch,
validUntil = None,
serial = PositiveInt.one,
parameter = dynamicDomainParameters,
)
),

View File

@ -1 +1 @@
20240325.12966.v2a7db959
20240325.12978.v1637d018