From eb2f42b6c5f7ff8e15cd011520d4aa92255290dc Mon Sep 17 00:00:00 2001 From: Hellblazer Date: Sun, 7 Apr 2024 16:39:43 -0700 Subject: [PATCH] prevent view replay on ViewMember in GenesisAssembly and ViewAssembly. Remove second thread from CI build - just 4 forks of testing now --- .github/workflows/maven.yml | 2 +- .../com/salesforce/apollo/choam/CHOAM.java | 119 +++++++++++------- .../salesforce/apollo/choam/Committee.java | 20 +-- .../apollo/choam/GenesisAssembly.java | 83 ++++++------ .../com/salesforce/apollo/choam/Producer.java | 26 +++- .../salesforce/apollo/choam/ViewAssembly.java | 62 +++++---- .../salesforce/apollo/choam/ViewContext.java | 29 +++-- .../apollo/choam/comm/Concierge.java | 2 +- .../apollo/choam/comm/Terminal.java | 4 +- .../apollo/choam/comm/TerminalClient.java | 2 +- .../apollo/choam/comm/TerminalServer.java | 2 +- .../apollo/choam/GenesisAssemblyTest.java | 8 +- .../salesforce/apollo/choam/TestChain.java | 3 +- .../support/CheckpointAssemblerTest.java | 3 +- .../apollo/cryptography/Verifier.java | 5 +- grpc/src/main/proto/choam.proto | 30 ++--- .../apollo/state/CheckpointBootstrapTest.java | 15 ++- .../apollo/state/GenesisBootstrapTest.java | 13 +- 18 files changed, 255 insertions(+), 173 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 14386c18f..cd46bb550 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -16,4 +16,4 @@ jobs: cache: 'maven' github-token: ${{ secrets.GITHUB_TOKEN }} - name: Build with Maven - run: ./mvnw -T 0.5C -batch-mode clean install -Ppre --file pom.xml -Dforks=4 + run: ./mvnw -batch-mode clean install -Ppre --file pom.xml -Dforks=4 diff --git a/choam/src/main/java/com/salesforce/apollo/choam/CHOAM.java b/choam/src/main/java/com/salesforce/apollo/choam/CHOAM.java index 181795e57..757748518 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/CHOAM.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/CHOAM.java @@ -108,7 +108,7 @@ public CHOAM(Parameters params) { adapter); linear = Executors.newSingleThreadExecutor( Thread.ofVirtual().name("Linear " + params.member().getId()).factory()); - combine.registerHandler((ctx, messages) -> { + combine.registerHandler((_, messages) -> { try { linear.execute(Utils.wrapped(() -> combine(messages), log)); } catch (RejectedExecutionException e) { @@ -140,7 +140,8 @@ public CHOAM(Parameters params) { session = new Session(params, service()); } - public static Checkpoint checkpoint(DigestAlgorithm algo, File state, int segmentSize, Digest initial, int crowns) { + public static Checkpoint checkpoint(DigestAlgorithm algo, File state, int segmentSize, Digest initial, int crowns, + Digest id) { assert segmentSize > 0 : "segment size must be > 0 : " + segmentSize; long length = 0; if (state != null) { @@ -169,12 +170,12 @@ public static Checkpoint checkpoint(DigestAlgorithm algo, File state, int segmen } } var crown = accumulator.build(); - log.info("Checkpoint length: {} segment size: {} count: {} crown: {} initial: {}", length, segmentSize, - builder.getCount(), crown, initial); + log.info("Checkpoint length: {} segment size: {} count: {} crown: {} initial: {} on: {}", length, segmentSize, + builder.getCount(), crown, initial, id); var cp = builder.setCrown(crown.toHexBloome()).build(); var deserialized = HexBloom.from(cp.getCrown()); - log.info("Deserialized checkpoint crown: {} initial: {}", deserialized, initial); + log.info("Deserialized checkpoint crown: {} initial: {} on: {}", deserialized, initial, id); return cp; } @@ -195,8 +196,11 @@ public static Digest hashOf(Transaction transaction, DigestAlgorithm digestAlgor } public static String print(Join join, DigestAlgorithm da) { - return "J[view: " + Digest.from(join.getView()) + " member: " + ViewContext.print(join.getMember(), da) - + "certifications: " + join.getEndorsementsList().stream().map(c -> ViewContext.print(c, da)).toList() + "]"; + return "J[view: " + Digest.from(join.getMember().getVm().getView()) + " member: " + ViewContext.print( + join.getMember(), da) + "certifications: " + join.getEndorsementsList() + .stream() + .map(c -> ViewContext.print(c, da)) + .toList() + "]"; } public static Reconfigure reconfigure(Digest nextViewId, Map joins, Context context, @@ -353,8 +357,8 @@ private void accept(HashedCertifiedBlock next) { store.put(next); final Committee c = current.get(); c.accept(next); - log.info("Accepted block: {} hash: {} hash: {} height: {} body: {} on: {}", next.block.getBodyCase(), - next.block.getBodyCase(), next.hash, next.height(), next.block.getBodyCase(), params.member().getId()); + log.info("Accepted block: {} hash: {} height: {} body: {} on: {}", next.block.getBodyCase(), next.hash, + next.height(), next.block.getBodyCase(), params.member().getId()); } private void cancelBootstrap() { @@ -381,19 +385,19 @@ private boolean checkJoin(Digest nextView, Digest from) { } final var nextId = nextViewId.get(); if (nextId == null) { - log.debug("Cannot join view: {} from: {}, next view has not been defined on: {}", nextView, source, + log.debug("Cannot join view: {} from: {}, next view has not been defined on: {}", nextView, source.getId(), params.member().getId()); return false; } if (!nextId.equals(nextView)) { - log.debug("Request to join incorrect view: {} expected: {} from: {} on: {}", nextView, nextId, source, - params.member().getId()); + log.debug("Request to join incorrect view: {} expected: {} from: {} on: {}", nextView, nextId, + source.getId(), params.member().getId()); return false; } final Set members = Committee.viewMembersOf(nextView, pendingView().get()); if (!members.contains(params.member())) { - log.debug("Not a member of view: {} invalid join request from: {} members: {} on: {}", nextView, source, - members, params.member().getId()); + log.debug("Not a member of view: {} invalid join request from: {} members: {} on: {}", nextView, + source.getId(), members.stream().map(m -> m.getId()).toList(), params.member().getId()); return false; } return true; @@ -410,7 +414,7 @@ private Block checkpoint() { } final HashedBlock c = checkpoint.get(); Checkpoint cp = checkpoint(params.digestAlgorithm(), state, params.checkpointSegmentSize(), c.hash, - params.crowns()); + params.crowns(), params.member().getId()); if (cp == null) { transitions.fail(); return null; @@ -535,9 +539,10 @@ public Block produce(ULong height, Digest prev, Executions executions, HashedBlo @Override public void publish(CertifiedBlock cb) { + log.info("Publishing: {} hash: {} height: {} certifications: {} on: {}", cb.getBlock().getBodyCase(), + cb.hashCode(), cb.getBlock().getHeader().getHeight(), cb.getCertificationsCount(), + params.member().getId()); combine.publish(cb, true); - log.trace("Published: {} hash: {} height: {} on: {}", cb.getBlock().getBodyCase(), cb.hashCode(), - cb.getBlock().getHeader().getHeight(), params.member().getId()); } @Override @@ -575,10 +580,11 @@ private CheckpointSegments fetch(CheckpointReplication request, Digest from) { log.info("No cached checkpoint for {} on: {}", request.getCheckpoint(), params.member().getId()); return CheckpointSegments.getDefaultInstance(); } - CheckpointSegments.Builder replication = CheckpointSegments.newBuilder(); - return replication.addAllSegments( - state.fetchSegments(BloomFilter.from(request.getCheckpointSegments()), params.maxCheckpointSegments())).build(); + return CheckpointSegments.newBuilder() + .addAllSegments(state.fetchSegments(BloomFilter.from(request.getCheckpointSegments()), + params.maxCheckpointSegments())) + .build(); } private Blocks fetchBlocks(BlockReplication rep, Digest from) { @@ -626,10 +632,10 @@ private boolean isNext(HashedBlock next) { return isNext; } - private ViewMember join(Digest nextView, Digest from) { + private SignedViewMember join(Digest nextView, Digest from) { final var c = current.get(); if (c == null) { - return ViewMember.getDefaultInstance(); + return SignedViewMember.getDefaultInstance(); } return c.join(nextView, from); } @@ -728,14 +734,15 @@ private void reconfigure(Reconfigure reconfigure) { current.set(new Client(validators, getViewId())); } } catch (IllegalArgumentException e) { - log.debug("unable to create consensus: {} on: {}", e.getMessage(), params.member().getId()); - } - log.info("Reconfigured to view: {} validators: {} on: {}", new Digest(reconfigure.getId()), - validators.entrySet() - .stream() - .map(e -> String.format("id: %s key: %s", e.getKey().getId(), - params.digestAlgorithm().digest(e.toString()))) - .toList(), params.member().getId()); + log.debug("unable to create consensus: {} committee: {} on: {}", e.getMessage(), current.get(), + params.member().getId()); + } + log.info("Reconfigured to view: {} committee: {} validators: {} on: {}", new Digest(reconfigure.getId()), + current.get(), validators.entrySet() + .stream() + .map(e -> String.format("id: %s key: %s", e.getKey().getId(), + params.digestAlgorithm().digest(e.toString()))) + .toList(), params.member().getId()); } private void recover(HashedCertifiedBlock anchor) { @@ -945,6 +952,7 @@ private void synchronizedProcess(CertifiedBlock certifiedBlock) { if (hcb.height().compareTo(prevHeight) <= 0) { log.trace("Discarding previously committed block: {} height: {} current height: {} on: {}", hcb.hash, hcb.height(), prevHeight, params.member().getId()); + pending.add(hcb); return; } if (!hcb.height().equals(prevHeight.add(1))) { @@ -957,20 +965,20 @@ private void synchronizedProcess(CertifiedBlock certifiedBlock) { } if (!previousBlock.hash.equals(prev)) { log.error( - "Protocol violation on {}. New block does not refer to current block hash. Should be {} and next block's prev is {}, current height: {} next height: {}", - params.member().getId(), previousBlock.hash, prev, prevHeight, hcb.height()); + "Protocol violation on: {}. New block does not refer to current block hash. Should be {} and next block's prev is {}, current height: {} next height: {} on: {}", + params.member().getId(), previousBlock.hash, prev, prevHeight, hcb.height(), params.member().getId()); return; } final var c = current.get(); if (!c.validate(hcb)) { - log.error("Protocol violation. New block is not validated: {} hash: {} on {}", hcb.block.getBodyCase(), + log.error("Protocol violation. New block is not validated: {} hash: {} on: {}", hcb.block.getBodyCase(), hcb.hash, params.member().getId()); return; } } else { if (!block.hasGenesis()) { pending.add(hcb); - log.info("Deferring block on {}. Block: {} hash: {} height should be {} and block height is {}", + log.info("Deferring block on: {}. Block: {} hash: {} height should be {} and block height is {}", params.member().getId(), hcb.block.getBodyCase(), hcb.hash, 0, header.getHeight()); return; } @@ -980,6 +988,8 @@ private void synchronizedProcess(CertifiedBlock certifiedBlock) { return; } } + log.info("Deferring block on: {}. Block: {} hash: {} height is {}", params.member().getId(), + hcb.block.getBodyCase(), hcb.hash, header.getHeight()); pending.add(hcb); } @@ -1084,7 +1094,7 @@ public void cancelTimer(String timer) { @Override public void combine() { - CHOAM.this.combine(); + linear.execute(Utils.wrapped(() -> CHOAM.this.combine(), log)); } @Override @@ -1148,7 +1158,7 @@ public Blocks fetchViewChain(BlockReplication request, Digest from) { } @Override - public ViewMember join(Digest nextView, Digest from) { + public SignedViewMember join(Digest nextView, Digest from) { return CHOAM.this.join(nextView, from); } @@ -1186,18 +1196,23 @@ public boolean isMember() { } @Override - public ViewMember join(Digest nextView, Digest from) { + public SignedViewMember join(Digest nextView, Digest from) { if (!checkJoin(nextView, from)) { log.debug("Join requested for invalid view: {} from: {} on: {}", nextView, from, params.member().getId()); - return ViewMember.getDefaultInstance(); + return SignedViewMember.getDefaultInstance(); } final var c = next.get(); + var inView = ViewMember.newBuilder(c.member).setView(nextView.toDigeste()).build(); + if (log.isDebugEnabled()) { log.debug("Joining view: {} from: {} view member: {} on: {}", nextView, from, - ViewContext.print(c.member, params.digestAlgorithm()), params.member().getId()); + ViewContext.print(inView, params.digestAlgorithm()), params.member().getId()); } - return c.member; + return SignedViewMember.newBuilder() + .setVm(inView) + .setSignature(params.member().sign(inView.toByteString()).toSig()) + .build(); } @Override @@ -1316,7 +1331,12 @@ private Formation() { Signer signer = new SignerImpl(c.consensusKeyPair.getPrivate(), ULong.MIN); Supplier> supp = pendingView(); ViewContext vc = new GenesisContext(formation, supp, params, signer, constructBlock()); - assembly = new GenesisAssembly(vc, comm, next.get().member, getLabel()); + var inView = ViewMember.newBuilder(c.member).setView(params.genesisViewId().toDigeste()).build(); + var svm = SignedViewMember.newBuilder() + .setVm(inView) + .setSignature(params.member().sign(inView.toByteString()).toSig()) + .build(); + assembly = new GenesisAssembly(vc, comm, svm, getLabel()); log.info("Setting next view id to genesis: {} on: {}", params.genesisViewId(), params.member().getId()); nextViewId.set(params.genesisViewId()); } else { @@ -1348,17 +1368,22 @@ public boolean isMember() { } @Override - public ViewMember join(Digest nextView, Digest from) { + public SignedViewMember join(Digest nextView, Digest from) { if (!checkJoin(nextView, from)) { - return ViewMember.getDefaultInstance(); + return SignedViewMember.getDefaultInstance(); } final var c = next.get(); var cd = pendingView().get(); + var inView = ViewMember.newBuilder(c.member).setView(nextView.toDigeste()).build(); + if (log.isDebugEnabled()) { log.debug("Joining view: {} from: {} view member: {} on: {}", nextView, from, - ViewContext.print(c.member, params.digestAlgorithm()), params.member().getId()); + ViewContext.print(inView, params.digestAlgorithm()), params.member().getId()); } - return c.member; + return SignedViewMember.newBuilder() + .setVm(inView) + .setSignature(params.member().sign(inView.toByteString()).toSig()) + .build(); } @Override @@ -1423,8 +1448,8 @@ public boolean isMember() { } @Override - public ViewMember join(Digest nextView, Digest from) { - return ViewMember.getDefaultInstance(); + public SignedViewMember join(Digest nextView, Digest from) { + return SignedViewMember.getDefaultInstance(); } @Override diff --git a/choam/src/main/java/com/salesforce/apollo/choam/Committee.java b/choam/src/main/java/com/salesforce/apollo/choam/Committee.java index 2184f2f8e..c7ad7fcf4 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/Committee.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/Committee.java @@ -12,7 +12,6 @@ import com.salesforce.apollo.context.Context; import com.salesforce.apollo.context.StaticContext; import com.salesforce.apollo.cryptography.Digest; -import com.salesforce.apollo.cryptography.DigestAlgorithm; import com.salesforce.apollo.cryptography.JohnHancock; import com.salesforce.apollo.cryptography.Verifier; import com.salesforce.apollo.cryptography.Verifier.DefaultVerifier; @@ -34,9 +33,10 @@ public interface Committee { static Map validatorsOf(Reconfigure reconfigure, Context context) { var validators = reconfigure.getJoinsList() .stream() - .collect(Collectors.toMap(e -> context.getMember(new Digest(e.getMember().getId())), - e -> (Verifier) new DefaultVerifier( - publicKey(e.getMember().getConsensusKey())))); + .collect( + Collectors.toMap(e -> context.getMember(new Digest(e.getMember().getVm().getId())), + e -> (Verifier) new DefaultVerifier( + publicKey(e.getMember().getVm().getConsensusKey())))); assert !validators.isEmpty() : "No validators in this reconfiguration of: " + context.getId(); return validators; } @@ -71,7 +71,7 @@ default void assembled() { boolean isMember(); - ViewMember join(Digest nextView, Digest from); + SignedViewMember join(Digest nextView, Digest from); Logger log(); @@ -115,11 +115,11 @@ default boolean validate(HashedCertifiedBlock hb, Certification c, Map nextAssembly; private final Map proposals = new ConcurrentHashMap<>(); private final AtomicBoolean published = new AtomicBoolean(); @@ -60,7 +60,7 @@ public class GenesisAssembly implements Genesis { private volatile Thread blockingThread; private volatile HashedBlock reconfiguration; - public GenesisAssembly(ViewContext vc, CommonCommunications comms, ViewMember genesisMember, + public GenesisAssembly(ViewContext vc, CommonCommunications comms, SignedViewMember genesisMember, String label) { view = vc; ds = new OneShot(); @@ -136,7 +136,6 @@ public void gather() { var join = Join.newBuilder() .setMember(genesisMember) .addEndorsements(certification) - .setView(view.context().getId().toDigeste()) .setKerl(params().kerl().get()) .build(); var proposed = new Proposed(join, params().member()); @@ -160,8 +159,8 @@ public void gather(List preblock, boolean last) { }) .filter(Objects::nonNull) .filter(j -> !j.equals(Join.getDefaultInstance())) - .peek( - j -> log.info("Gathering: {} on: {}", Digest.from(j.getMember().getId()), params().member().getId())) + .peek(j -> log.info("Gathering: {} on: {}", Digest.from(j.getMember().getVm().getId()), + params().member().getId())) .forEach(this::join); } @@ -196,6 +195,16 @@ public void nominations(List preblock, boolean last) { @Override public void publish() { + if (witnesses.size() < params().majority()) { + log.warn("Cannot publish genesis: {} with: {} witnesses on: {}", reconfiguration.hash, witnesses.size(), + params().member().getId()); + return; + } + if (!published.compareAndSet(false, true)) { + log.debug("already published genesis: {} with {} witnesses on: {}", reconfiguration.hash, witnesses.size(), + params().member().getId()); + return; + } var b = CertifiedBlock.newBuilder().setBlock(reconfiguration.block); witnesses.entrySet() .stream() @@ -204,8 +213,8 @@ public void publish() { .forEach(v -> b.addCertifications(v.getWitness())); view.publish(new HashedCertifiedBlock(params().digestAlgorithm(), b.build())); // controller.completeIt(); - log.info("Genesis block: {} published for: {} on: {}", reconfiguration.hash, view.context().getId(), - params().member().getId()); + log.info("Genesis block: {} published with {} witnesses for: {} on: {}", reconfiguration.hash, witnesses.size(), + view.context().getId(), params().member().getId()); } public void start() { @@ -240,11 +249,7 @@ private void certify(Validate v) { var member = view.context().getMember(Digest.from(v.getWitness().getId())); if (member != null) { witnesses.put(member, v); - if (witnesses.size() >= params().majority()) { - if (published.compareAndSet(false, true)) { - publish(); - } - } + publish(); } } @@ -264,40 +269,46 @@ private DataSource dataSource() { } private void join(Join join) { - final var vm = join.getMember(); - final var mid = Digest.from(vm.getId()); + final var svm = join.getMember(); + final var mid = Digest.from(svm.getVm().getId()); final var m = nextAssembly.get(mid); if (m == null) { - if (log.isTraceEnabled()) { - log.trace("Invalid view member: {} on: {}", ViewContext.print(vm, params().digestAlgorithm()), - params().member().getId()); - } + log.warn("Invalid view member: {} on: {}", ViewContext.print(svm, params().digestAlgorithm()), + params().member().getId()); return; } if (m.equals(params().member())) { return; // Don't process ourselves } + final var viewId = Digest.from(svm.getVm().getView()); + if (!viewId.equals(params().genesisViewId())) { + log.warn("Invalid view id for member: {} on: {}", ViewContext.print(svm, params().digestAlgorithm()), + params().member().getId()); + return; + } - PubKey encoded = vm.getConsensusKey(); + if (!m.verify(signature(svm.getSignature()), svm.getVm().toByteString())) { + log.warn("Could not verify view member: {} on: {}", ViewContext.print(svm, params().digestAlgorithm()), + params().member().getId()); + return; + } - if (!m.verify(signature(vm.getSignature()), encoded.toByteString())) { - if (log.isTraceEnabled()) { - log.trace("Could not verify consensus key from view member: {} on: {}", - ViewContext.print(vm, params().digestAlgorithm()), params().member().getId()); - } + PubKey encoded = svm.getVm().getConsensusKey(); + + if (!m.verify(signature(svm.getVm().getSignature()), encoded.toByteString())) { + log.warn("Could not verify consensus key from view member: {} on: {}", + ViewContext.print(svm, params().digestAlgorithm()), params().member().getId()); return; } PublicKey consensusKey = publicKey(encoded); if (consensusKey == null) { - if (log.isTraceEnabled()) { - log.trace("Could not deserialize consensus key from view member: {} on: {}", - ViewContext.print(vm, params().digestAlgorithm()), params().member().getId()); - } + log.warn("Could not deserialize consensus key from view member: {} on: {}", + ViewContext.print(svm, params().digestAlgorithm()), params().member().getId()); return; } if (log.isTraceEnabled()) { - log.trace("Valid view member: {} on: {}", ViewContext.print(vm, params().digestAlgorithm()), + log.trace("Valid view member: {} on: {}", ViewContext.print(svm, params().digestAlgorithm()), params().member().getId()); } var proposed = proposals.computeIfAbsent(mid, k -> new Proposed(join, m)); @@ -326,29 +337,29 @@ private void validate(Validate v) { log.warn("Unknown certifier: {} on: {}", cid, params().member().getId()); return; // do not have the join yet } - final var hash = Digest.from(v.getHash()); - final var member = nextAssembly.get(hash); + final var vid = Digest.from(v.getHash()); + final var member = nextAssembly.get(vid); if (member == null) { return; } - var proposed = proposals.get(hash); + var proposed = proposals.get(vid); if (proposed == null) { - log.warn("Invalid certification, unknown view join: {} on: {}", hash, params().member().getId()); + log.warn("Invalid certification, unknown view join: {} on: {}", vid, params().member().getId()); return; // do not have the join yet } if (!view.validate(proposed.join.getMember(), v)) { - log.warn("Invalid certification for view join: {} from: {} on: {}", hash, + log.warn("Invalid certification for view join: {} from: {} on: {}", vid, Digest.from(v.getWitness().getId()), params().member().getId()); return; } var prev = proposed.certifications.put(certifier, v.getWitness()); if (prev == null) { log.debug("New validation of view member: {} hash: {} using certifier: {} witnesses: {} on: {}", - member.getId(), hash, certifier.getId(), proposed.certifications.values().size(), + member.getId(), vid, certifier.getId(), proposed.certifications.values().size(), params().member().getId()); } else { log.debug("Redundant validation of view member: {} hash: {} using certifier: {} on: {}", member.getId(), - hash, certifier.getId(), params().member().getId()); + vid, certifier.getId(), params().member().getId()); } } diff --git a/choam/src/main/java/com/salesforce/apollo/choam/Producer.java b/choam/src/main/java/com/salesforce/apollo/choam/Producer.java index c9cbbf641..9f661706d 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/Producer.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/Producer.java @@ -30,7 +30,8 @@ import java.util.*; import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -52,8 +53,9 @@ public class Producer { private final TxDataSource ds; private final int lastEpoch; private final Set nextAssembly = new HashSet<>(); - private final Map pending = new ConcurrentHashMap<>(); + private final Map pending = new ConcurrentSkipListMap<>(); private final BlockingQueue pendingReassembles = new LinkedBlockingQueue<>(); + private final Map> pendingValidations = new ConcurrentSkipListMap<>(); private final AtomicReference previousBlock = new AtomicReference<>(); private final AtomicBoolean reconfigured = new AtomicBoolean(); private final AtomicBoolean started = new AtomicBoolean(false); @@ -218,6 +220,7 @@ private void create(List preblock, boolean last) { p.witnesses.put(params().member(), validation); log.debug("Created block: {} hash: {} height: {} prev: {} last: {} on: {}", next.block.getBodyCase(), next.hash, next.height(), lb.hash, last, params().member().getId()); + processPendingValidations(next, p); } if (last) { started.set(true); @@ -238,6 +241,16 @@ private Parameters params() { return view.params(); } + private void processPendingValidations(HashedBlock block, PendingBlock p) { + var pending = pendingValidations.remove(block.hash); + if (pending != null) { + pending.forEach(v -> validate(v, p, block.hash)); + if (p.witnesses.size() >= params().majority()) { + publish(p); + } + } + } + private void produceAssemble() { final var vlb = previousBlock.get(); nextViewId = vlb.hash; @@ -257,13 +270,13 @@ private void produceAssemble() { ds.offer(validation); log.debug("Produced view assembly: {} block: {} height: {} body: {} from: {} on: {}", nextViewId, assemble.hash, assemble.height(), assemble.block.getBodyCase(), getViewId(), params().member().getId()); + processPendingValidations(assemble, p); } private void publish(PendingBlock p) { log.debug("Published pending: {} hash: {} height: {} witnesses: {} on: {}", p.block.block.getBodyCase(), p.block.hash, p.block.height(), p.witnesses.values().size(), params().member().getId()); p.published.set(true); - pending.remove(p.block.hash); final var cb = CertifiedBlock.newBuilder() .setBlock(p.block.block) .addAllCertifications( @@ -276,8 +289,13 @@ private PendingBlock validate(Validate v) { Digest hash = Digest.from(v.getHash()); var p = pending.get(hash); if (p == null) { + pendingValidations.computeIfAbsent(hash, h -> new CopyOnWriteArrayList<>()).add(v); return null; } + return validate(v, p, hash); + } + + private PendingBlock validate(Validate v, PendingBlock p, Digest hash) { if (!view.validate(p.block, v)) { log.trace("Invalid validate for: {} hash: {} on: {}", p.block.block.getBodyCase(), hash, params().member().getId()); @@ -312,6 +330,7 @@ public void assembled() { log.info("Reconfiguration block: {} height: {} slate: {} produced on: {}", reconfiguration.hash, reconfiguration.height(), slate.keySet().stream().map(m -> m.getId()).sorted().toList(), params().member().getId()); + processPendingValidations(reconfiguration, p); } @Override @@ -353,6 +372,7 @@ public void checkpoint() { p.witnesses.put(params().member(), validation); log.info("Produced checkpoint: {} height: {} for: {} on: {}", next.hash, next.height(), getViewId(), params().member().getId()); + processPendingValidations(next, p); transitions.checkpointed(); } diff --git a/choam/src/main/java/com/salesforce/apollo/choam/ViewAssembly.java b/choam/src/main/java/com/salesforce/apollo/choam/ViewAssembly.java index 909d1ad6a..2d83c2b4d 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/ViewAssembly.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/ViewAssembly.java @@ -15,6 +15,7 @@ import com.salesforce.apollo.choam.proto.*; import com.salesforce.apollo.context.Context; import com.salesforce.apollo.cryptography.Digest; +import com.salesforce.apollo.cryptography.JohnHancock; import com.salesforce.apollo.cryptography.proto.PubKey; import com.salesforce.apollo.membership.Member; import com.salesforce.apollo.ring.SliceIterator; @@ -145,24 +146,24 @@ private void completeSlice(AtomicReference retryDelay, AtomicReference } } - private boolean consider(Optional futureSailor, Terminal term, Member m) { + private boolean consider(Optional futureSailor, Terminal term, Member m) { if (futureSailor.isEmpty()) { return !gathered(); } - ViewMember member; - member = futureSailor.get(); + SignedViewMember signedViewMember; + signedViewMember = futureSailor.get(); log.debug("Join reply from: {} on: {}", term.getMember().getId(), params().member().getId()); - if (member.equals(ViewMember.getDefaultInstance())) { + if (signedViewMember.equals(SignedViewMember.getDefaultInstance())) { log.debug("Empty join response from: {} on: {}", term.getMember().getId(), params().member().getId()); return !gathered(); } - var vm = new Digest(member.getId()); + var vm = new Digest(signedViewMember.getVm().getId()); if (!m.getId().equals(vm)) { log.debug("Invalid join response from: {} expected: {} on: {}", term.getMember().getId(), vm, params().member().getId()); return !gathered(); } - join(member, true); + join(signedViewMember, true); return !gathered(); } @@ -183,26 +184,43 @@ private Reassemble getMemberProposal() { .build(); } - private void join(ViewMember vm, boolean direct) { - final var mid = Digest.from(vm.getId()); + private void join(SignedViewMember svm, boolean direct) { + final var mid = Digest.from(svm.getVm().getId()); final var m = nextAssembly.get(mid); if (m == null) { if (log.isTraceEnabled()) { - log.trace("Invalid view member: {} on: {}", ViewContext.print(vm, params().digestAlgorithm()), + log.trace("Invalid view member: {} on: {}", ViewContext.print(svm, params().digestAlgorithm()), + params().member().getId()); + } + return; + } + var viewId = Digest.from(svm.getVm().getView()); + if (!nextViewId.equals(viewId)) { + if (log.isTraceEnabled()) { + log.trace("Invalid view id for member: {} on: {}", ViewContext.print(svm, params().digestAlgorithm()), params().member().getId()); } return; } if (log.isDebugEnabled()) { log.debug("Join request from: {} vm: {} on: {}", m.getId(), - ViewContext.print(vm, params().digestAlgorithm()), params().member().getId()); + ViewContext.print(svm, params().digestAlgorithm()), params().member().getId()); } - PubKey encoded = vm.getConsensusKey(); - if (!m.verify(signature(vm.getSignature()), encoded.toByteString())) { + if (!m.verify(JohnHancock.from(svm.getSignature()), svm.getVm().toByteString())) { + if (log.isTraceEnabled()) { + log.trace("Invalid signature for view member: {} on: {}", + ViewContext.print(svm, params().digestAlgorithm()), params().member().getId()); + } + return; + } + + PubKey encoded = svm.getVm().getConsensusKey(); + + if (!m.verify(signature(svm.getVm().getSignature()), encoded.toByteString())) { if (log.isTraceEnabled()) { log.trace("Could not verify consensus key from view member: {} on: {}", - ViewContext.print(vm, params().digestAlgorithm()), params().member().getId()); + ViewContext.print(svm, params().digestAlgorithm()), params().member().getId()); } return; } @@ -211,7 +229,7 @@ private void join(ViewMember vm, boolean direct) { if (consensusKey == null) { if (log.isTraceEnabled()) { log.trace("Could not deserialize consensus key from view member: {} on: {}", - ViewContext.print(vm, params().digestAlgorithm()), params().member().getId()); + ViewContext.print(svm, params().digestAlgorithm()), params().member().getId()); } return; } @@ -219,23 +237,23 @@ private void join(ViewMember vm, boolean direct) { var proposed = proposals.computeIfAbsent(mid, k -> { newJoin.set(true); - return new Proposed(vm, m, new ConcurrentSkipListMap<>()); + return new Proposed(svm, m, new ConcurrentSkipListMap<>()); }); var builder = Reassemble.newBuilder(); proposed.validations.computeIfAbsent(params().member(), k -> { - var validate = view.generateValidation(vm); + var validate = view.generateValidation(svm); builder.addValidations(validate); return validate; }); if (newJoin.get()) { if (log.isTraceEnabled()) { - log.trace("Adding view member: {} on: {}", ViewContext.print(vm, params().digestAlgorithm()), + log.trace("Adding view member: {} on: {}", ViewContext.print(svm, params().digestAlgorithm()), params().member().getId()); } if (direct) { - builder.addMembers(vm); + builder.addMembers(svm); } var validations = unassigned.remove(mid); if (validations != null) { @@ -256,11 +274,7 @@ private Join joinOf(Proposed candidate) { .sorted( Comparator.comparing(c -> new Digest(c.getId()))) .toList(); - return Join.newBuilder() - .setMember(candidate.vm) - .setView(nextViewId.toDigeste()) - .addAllEndorsements(witnesses) - .build(); + return Join.newBuilder().setMember(candidate.vm).addAllEndorsements(witnesses).build(); } private Parameters params() { @@ -303,7 +317,7 @@ private void validate(Validate v) { } } - private record Proposed(ViewMember vm, Member member, Map validations) { + private record Proposed(SignedViewMember vm, Member member, Map validations) { } private class Recon implements Reconfiguration { diff --git a/choam/src/main/java/com/salesforce/apollo/choam/ViewContext.java b/choam/src/main/java/com/salesforce/apollo/choam/ViewContext.java index 2c46a9164..957d3c914 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/ViewContext.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/ViewContext.java @@ -63,8 +63,12 @@ public static String print(Validate v, DigestAlgorithm algo) { algo.digest(v.getWitness().getSignature().toByteString())); } + public static String print(SignedViewMember svm, DigestAlgorithm algo) { + return print(svm.getVm(), algo); + } + public static String print(ViewMember vm, DigestAlgorithm algo) { - return String.format("id: %s key: %s sig: %s", Digest.from(vm.getId()), + return String.format("id: %s vid: %s key: %s sig: %s", Digest.from(vm.getId()), Digest.from(vm.getView()), algo.digest(publicKey(vm.getConsensusKey()).getEncoded()), algo.digest(vm.getSignature().toByteString())); } @@ -96,19 +100,19 @@ public Validate generateValidation(HashedBlock block) { return validation; } - public Validate generateValidation(ViewMember vm) { - JohnHancock signature = signer.sign(vm.getSignature().toByteString()); + public Validate generateValidation(SignedViewMember svm) { + JohnHancock signature = signer.sign(svm.getVm().toByteString()); if (signature == null) { - log.error("Unable to sign view member: {} on: {}", print(vm, params.digestAlgorithm()), + log.error("Unable to sign view member: {} on: {}", print(svm, params.digestAlgorithm()), params.member().getId()); return null; } if (log.isTraceEnabled()) { - log.trace("Signed view member: {} with sig: {} on: {}", print(vm, params.digestAlgorithm()), + log.trace("Signed view member: {} with sig: {} on: {}", print(svm, params.digestAlgorithm()), params().digestAlgorithm().digest(signature.toSig().toByteString()), params.member().getId()); } var validation = Validate.newBuilder() - .setHash(vm.getId()) + .setHash(svm.getVm().getId()) .setWitness(Certification.newBuilder() .setId(params.member().getId().toDigeste()) .setSignature(signature.toSig()) @@ -171,17 +175,16 @@ public boolean validate(HashedBlock block, Validate validate) { return v.verify(JohnHancock.from(validate.getWitness().getSignature()), block.block.getHeader().toByteString()); } - public boolean validate(ViewMember vm, Validate validate) { + public boolean validate(SignedViewMember svm, Validate validate) { Verifier v = verifierOf(validate); if (v == null) { return false; } - final var valid = v.verify(JohnHancock.from(validate.getWitness().getSignature()), - vm.getSignature().toByteString()); + final var valid = v.verify(JohnHancock.from(validate.getWitness().getSignature()), svm.getVm().toByteString()); if (!valid) { if (log.isDebugEnabled()) { - log.debug("Unable to validate view member: {} from validation: {} key: {} on: {}", - print(vm, params.digestAlgorithm()), print(validate, params.digestAlgorithm()), + log.debug("Unable to validate view member: {} from validation: [{}] key: {} on: {}", + print(svm, params.digestAlgorithm()), print(validate, params.digestAlgorithm()), params.digestAlgorithm().digest(v.toString()), params.member().getId()); } } @@ -193,7 +196,7 @@ protected Verifier verifierOf(Validate validate) { var m = context.getMember(mid); if (m == null) { if (log.isDebugEnabled()) { - log.debug("Unable to validate key by non existent validator: {} on: {}", + log.debug("Unable to validate key by non existent validator: [{}] on: {}", print(validate, params.digestAlgorithm()), params.member().getId()); } return null; @@ -201,7 +204,7 @@ protected Verifier verifierOf(Validate validate) { Verifier v = validators.get(m); if (v == null) { if (log.isDebugEnabled()) { - log.debug("Unable to validate key by non existent validator: {} on: {}", + log.debug("Unable to validate key by non existent validator: [{}] on: {}", print(validate, params.digestAlgorithm()), params.member().getId()); } return null; diff --git a/choam/src/main/java/com/salesforce/apollo/choam/comm/Concierge.java b/choam/src/main/java/com/salesforce/apollo/choam/comm/Concierge.java index 099e8ccba..9aea366ba 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/comm/Concierge.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/comm/Concierge.java @@ -20,7 +20,7 @@ public interface Concierge { Blocks fetchViewChain(BlockReplication request, Digest from); - ViewMember join(Digest nextView, Digest from); + SignedViewMember join(Digest nextView, Digest from); Initial sync(Synchronize request, Digest from); diff --git a/choam/src/main/java/com/salesforce/apollo/choam/comm/Terminal.java b/choam/src/main/java/com/salesforce/apollo/choam/comm/Terminal.java index 4fa4187ee..a54b4c675 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/comm/Terminal.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/comm/Terminal.java @@ -47,7 +47,7 @@ public Member getMember() { } @Override - public ViewMember join(Digest nextView) { + public SignedViewMember join(Digest nextView) { return service.join(nextView, member.getId()); } @@ -64,7 +64,7 @@ public Initial sync(Synchronize sync) { Blocks fetchViewChain(BlockReplication replication); - ViewMember join(Digest nextView); + SignedViewMember join(Digest nextView); Initial sync(Synchronize sync); } diff --git a/choam/src/main/java/com/salesforce/apollo/choam/comm/TerminalClient.java b/choam/src/main/java/com/salesforce/apollo/choam/comm/TerminalClient.java index 1c72a65d2..0a3c237ff 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/comm/TerminalClient.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/comm/TerminalClient.java @@ -60,7 +60,7 @@ public Member getMember() { } @Override - public ViewMember join(Digest nextView) { + public SignedViewMember join(Digest nextView) { return client.join(nextView.toDigeste()); } diff --git a/choam/src/main/java/com/salesforce/apollo/choam/comm/TerminalServer.java b/choam/src/main/java/com/salesforce/apollo/choam/comm/TerminalServer.java index b780b0d60..28b74430b 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/comm/TerminalServer.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/comm/TerminalServer.java @@ -70,7 +70,7 @@ public void fetchViewChain(BlockReplication request, StreamObserver resp } @Override - public void join(Digeste nextView, StreamObserver responseObserver) { + public void join(Digeste nextView, StreamObserver responseObserver) { Digest from = identity.getFrom(); if (from == null) { responseObserver.onError(new IllegalStateException("Member has been removed")); diff --git a/choam/src/test/java/com/salesforce/apollo/choam/GenesisAssemblyTest.java b/choam/src/test/java/com/salesforce/apollo/choam/GenesisAssemblyTest.java index 6a0955441..f28eb3e14 100644 --- a/choam/src/test/java/com/salesforce/apollo/choam/GenesisAssemblyTest.java +++ b/choam/src/test/java/com/salesforce/apollo/choam/GenesisAssemblyTest.java @@ -76,6 +76,7 @@ public void genesis() throws Exception { var committee = Committee.viewFor(viewId, base); Parameters.Builder params = Parameters.newBuilder() + .setGenesisViewId(DigestAlgorithm.DEFAULT.getLast()) .setGenerateGenesis(true) .setProducer(ProducerParameters.newBuilder() .setGossipDuration(Duration.ofMillis(100)) @@ -173,10 +174,15 @@ public Block reconfigure(Map joining, Digest nextViewId, HashedBlo final PubKey consensus = bs(keyPair.getPublic()); var vm = ViewMember.newBuilder() .setId(m.getId().toDigeste()) + .setView(params.getGenesisViewId().toDigeste()) .setConsensusKey(consensus) .setSignature(((Signer) m).sign(consensus.toByteString()).toSig()) .build(); - genii.put(m, new GenesisAssembly(view, comms.get(m), vm, m.getId().toString())); + var svm = SignedViewMember.newBuilder() + .setVm(vm) + .setSignature(((SigningMember) m).sign(vm.toByteString()).toSig()) + .build(); + genii.put(m, new GenesisAssembly(view, comms.get(m), svm, m.getId().toString())); }); try { diff --git a/choam/src/test/java/com/salesforce/apollo/choam/TestChain.java b/choam/src/test/java/com/salesforce/apollo/choam/TestChain.java index 42e4de032..4e154f0a7 100644 --- a/choam/src/test/java/com/salesforce/apollo/choam/TestChain.java +++ b/choam/src/test/java/com/salesforce/apollo/choam/TestChain.java @@ -128,7 +128,8 @@ private HashedCertifiedBlock checkpointBlock() { CHOAM.checkpoint( DigestAlgorithm.DEFAULT, null, 1, - checkpoint.hash, 2)) + checkpoint.hash, 2, + DigestAlgorithm.DEFAULT.getOrigin())) .build()) .build()); store.put(lastBlock); diff --git a/choam/src/test/java/com/salesforce/apollo/choam/support/CheckpointAssemblerTest.java b/choam/src/test/java/com/salesforce/apollo/choam/support/CheckpointAssemblerTest.java index e77a0704a..6a0e2199e 100644 --- a/choam/src/test/java/com/salesforce/apollo/choam/support/CheckpointAssemblerTest.java +++ b/choam/src/test/java/com/salesforce/apollo/choam/support/CheckpointAssemblerTest.java @@ -93,7 +93,8 @@ public void functional() throws Exception { var context = new StaticContext<>(DigestAlgorithm.DEFAULT.getOrigin(), 0.2, members, 3); Checkpoint checkpoint = CHOAM.checkpoint(DigestAlgorithm.DEFAULT, chkptFile, SEGMENT_SIZE, - DigestAlgorithm.DEFAULT.getOrigin(), 2); + DigestAlgorithm.DEFAULT.getOrigin(), 2, + DigestAlgorithm.DEFAULT.getOrigin()); SigningMember bootstrapping = (SigningMember) members.get(0); diff --git a/cryptography/src/main/java/com/salesforce/apollo/cryptography/Verifier.java b/cryptography/src/main/java/com/salesforce/apollo/cryptography/Verifier.java index a76da3bef..3a198af47 100644 --- a/cryptography/src/main/java/com/salesforce/apollo/cryptography/Verifier.java +++ b/cryptography/src/main/java/com/salesforce/apollo/cryptography/Verifier.java @@ -130,7 +130,8 @@ public Filtered filtered(SigningThreshold threshold, JohnHancock signature, Inpu @Override public String toString() { - return "V[" + keys.values().stream().map(k -> ":" + k.getEncoded()).toList() + "]"; + return "V[" + keys.values().stream().map(k -> ":" + DigestAlgorithm.DEFAULT.digest(k.getEncoded())).toList() + + "]"; } @Override @@ -144,7 +145,7 @@ public boolean verify(SigningThreshold threshold, JohnHancock signature, InputSt } } - public class MockVerifier implements Verifier { + class MockVerifier implements Verifier { @Override public Filtered filtered(SigningThreshold threshold, JohnHancock signature, InputStream message) { diff --git a/grpc/src/main/proto/choam.proto b/grpc/src/main/proto/choam.proto index 76f9aae79..e644b79b6 100644 --- a/grpc/src/main/proto/choam.proto +++ b/grpc/src/main/proto/choam.proto @@ -15,7 +15,7 @@ service TransactionSubmission { service Terminal { /* reconfiguration */ - rpc join (crypto.Digeste) returns (ViewMember) {} + rpc join (crypto.Digeste) returns (SignedViewMember) {} /* bootstrapping */ rpc sync(Synchronize) returns (Initial) {} @@ -107,16 +107,21 @@ message UnitData { } message Join { - crypto.Digeste view = 1; - ViewMember member = 2; - repeated Certification endorsements = 3; - stereotomy.KERL_ kerl = 4; + SignedViewMember member = 1; + repeated Certification endorsements = 2; + stereotomy.KERL_ kerl = 3; } message ViewMember { crypto.Digeste id = 1; - crypto.PubKey consensusKey = 2; - crypto.Sig signature = 3; + crypto.Digeste view = 2; + crypto.PubKey consensusKey = 3; + crypto.Sig signature = 4; +} + +message SignedViewMember { + ViewMember vm = 1; + crypto.Sig signature = 2; } message Certification { @@ -142,19 +147,16 @@ message CheckpointProcessing { } message Validate { - crypto.Digeste hash = 1; - Certification witness = 2; + crypto.Digeste id = 1; + crypto.Digeste hash = 2; + Certification witness = 3; } message Reassemble { - repeated ViewMember members = 1; + repeated SignedViewMember members = 1; repeated Validate validations = 2; } -message ViewMembers { - repeated ViewMember members = 1; -} - message Validations { repeated Validate validations = 1; } diff --git a/sql-state/src/test/java/com/salesforce/apollo/state/CheckpointBootstrapTest.java b/sql-state/src/test/java/com/salesforce/apollo/state/CheckpointBootstrapTest.java index 11858080b..5e66b5ca2 100644 --- a/sql-state/src/test/java/com/salesforce/apollo/state/CheckpointBootstrapTest.java +++ b/sql-state/src/test/java/com/salesforce/apollo/state/CheckpointBootstrapTest.java @@ -7,8 +7,7 @@ package com.salesforce.apollo.state; import ch.qos.logback.classic.Level; -import com.chiralbehaviors.tron.Fsm; -import com.salesforce.apollo.choam.*; +import com.salesforce.apollo.choam.CHOAM; import com.salesforce.apollo.context.DynamicContext; import com.salesforce.apollo.utils.Utils; import org.joou.ULong; @@ -26,12 +25,12 @@ public class CheckpointBootstrapTest extends AbstractLifecycleTest { static { - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(CHOAM.class)).setLevel(Level.TRACE); - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(GenesisAssembly.class)).setLevel(Level.TRACE); - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ViewAssembly.class)).setLevel(Level.TRACE); - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Producer.class)).setLevel(Level.TRACE); - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Committee.class)).setLevel(Level.TRACE); - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Fsm.class)).setLevel(Level.TRACE); + ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(CHOAM.class)).setLevel(Level.INFO); + // ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(GenesisAssembly.class)).setLevel(Level.TRACE); + // ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ViewAssembly.class)).setLevel(Level.TRACE); + // ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Producer.class)).setLevel(Level.TRACE); + // ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Committee.class)).setLevel(Level.TRACE); + // ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Fsm.class)).setLevel(Level.TRACE); } @Test diff --git a/sql-state/src/test/java/com/salesforce/apollo/state/GenesisBootstrapTest.java b/sql-state/src/test/java/com/salesforce/apollo/state/GenesisBootstrapTest.java index 78628b3aa..e9de45563 100644 --- a/sql-state/src/test/java/com/salesforce/apollo/state/GenesisBootstrapTest.java +++ b/sql-state/src/test/java/com/salesforce/apollo/state/GenesisBootstrapTest.java @@ -7,8 +7,7 @@ package com.salesforce.apollo.state; import ch.qos.logback.classic.Level; -import com.chiralbehaviors.tron.Fsm; -import com.salesforce.apollo.choam.*; +import com.salesforce.apollo.choam.CHOAM; import com.salesforce.apollo.context.DynamicContext; import com.salesforce.apollo.utils.Utils; import org.junit.jupiter.api.Test; @@ -23,11 +22,11 @@ public class GenesisBootstrapTest extends AbstractLifecycleTest { static { ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(CHOAM.class)).setLevel(Level.TRACE); - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(GenesisAssembly.class)).setLevel(Level.TRACE); - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ViewAssembly.class)).setLevel(Level.TRACE); - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Producer.class)).setLevel(Level.TRACE); - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Committee.class)).setLevel(Level.TRACE); - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Fsm.class)).setLevel(Level.TRACE); + // ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(GenesisAssembly.class)).setLevel(Level.TRACE); + // ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ViewAssembly.class)).setLevel(Level.TRACE); + // ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Producer.class)).setLevel(Level.TRACE); + // ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Committee.class)).setLevel(Level.TRACE); + // ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Fsm.class)).setLevel(Level.TRACE); } @Test