code: private CompletableFuture<Void> copyTxnEpochSegmentsAndCommitTxns(String scope, String stream, List<UUID> transactionsToCommit,
                                                                        List<Long> segmentIds) {
          // 1. create duplicate segments
          // 2. merge transactions in those segments
          // 3. seal txn epoch segments
          String delegationToken = streamMetadataTasks.retrieveDelegationToken();
          CompletableFuture<Void> createSegmentsFuture = Futures.allOf(segmentIds.stream().map(segment -> {
              // Use fixed scaling policy for these segments as they are created, merged into and sealed and are not
              // supposed to auto scale.
              return streamMetadataTasks.notifyNewSegment(scope, stream, segment, ScalingPolicy.fixed(1), delegationToken);
          }).collect(Collectors.toList()));
  
          return createSegmentsFuture
                  .thenCompose(v -> {
                      log.debug("Rolling transaction, successfully created duplicate txn epoch {} for stream {}/{}", segmentIds, scope, stream);
                      // now commit transactions into these newly created segments
                      return commitTransactions(scope, stream, segmentIds, transactionsToCommit);
                  })
                  .thenCompose(v -> streamMetadataTasks.notifySealedSegments(scope, stream, segmentIds, delegationToken));
      }
docs: This method is called in the rolling transaction flow.
  This method creates duplicate segments for transaction epoch. It then merges all transactions from the list into
  those duplicate segments.