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 09fde0e52..3c25f67a4 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/CHOAM.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/CHOAM.java @@ -87,10 +87,12 @@ public class CHOAM { private final Combine.Transitions transitions; private final TransSubmission txnSubmission = new TransSubmission(); private final AtomicReference view = new AtomicReference<>(); + private final AtomicReference diadem = new AtomicReference<>(); public CHOAM(Parameters params) { this.store = new Store(params.digestAlgorithm(), params.mvBuilder().clone().build()); this.params = params; + diadem.set(new HexBloom(params.digestAlgorithm().getLast(), 0)); executions = Executors.newVirtualThreadPerTaskExecutor(); nextView(); @@ -173,10 +175,10 @@ public static Checkpoint checkpoint(DigestAlgorithm algo, File state, int segmen return cp; } - public static Block genesis(Digest id, Map joins, HashedBlock head, Context context, - HashedBlock lastViewChange, Parameters params, HashedBlock lastCheckpoint, - Iterable initialization) { - var reconfigure = reconfigure(id, joins, context, params, params.checkpointBlockDelta()); + public static Block genesis(Digest id, HexBloom diadem, Map joins, HashedBlock head, + Context context, HashedBlock lastViewChange, Parameters params, + HashedBlock lastCheckpoint, Iterable initialization) { + var reconfigure = reconfigure(id, diadem, joins, context, params, params.checkpointBlockDelta()); return Block.newBuilder() .setHeader(buildHeader(params.digestAlgorithm(), reconfigure, head.hash, ULong.valueOf(0), lastCheckpoint.height(), lastCheckpoint.hash, lastViewChange.height(), @@ -194,9 +196,12 @@ public static String print(Join join, DigestAlgorithm da) { + "certifications: " + join.getEndorsementsList().stream().map(c -> ViewContext.print(c, da)).toList() + "]"; } - public static Reconfigure reconfigure(Digest nextViewId, Map joins, Context context, - Parameters params, int checkpointTarget) { - var builder = Reconfigure.newBuilder().setCheckpointTarget(checkpointTarget).setId(nextViewId.toDigeste()); + public static Reconfigure reconfigure(Digest nextViewId, HexBloom diadem, Map joins, + Context context, Parameters params, int checkpointTarget) { + var builder = Reconfigure.newBuilder() + .setCheckpointTarget(checkpointTarget) + .setId(nextViewId.toDigeste()) + .setView(diadem.toHexBloome()); // Canonical labeling of the view members for Ethereal var remapped = rosterMap(context, joins.keySet()); @@ -207,14 +212,14 @@ public static Reconfigure reconfigure(Digest nextViewId, Map joins return reconfigure; } - public static Block reconfigure(Digest nextViewId, Map joins, HashedBlock head, + public static Block reconfigure(Digest nextViewId, HexBloom diadem, Map joins, HashedBlock head, Context context, HashedBlock lastViewChange, Parameters params, HashedBlock lastCheckpoint) { final Block lvc = lastViewChange.block; int lastTarget = lvc.hasGenesis() ? lvc.getGenesis().getInitialView().getCheckpointTarget() : lvc.getReconfigure().getCheckpointTarget(); int checkpointTarget = lastTarget == 0 ? params.checkpointBlockDelta() : lastTarget - 1; - var reconfigure = reconfigure(nextViewId, joins, context, params, checkpointTarget); + var reconfigure = reconfigure(nextViewId, diadem, joins, context, params, checkpointTarget); return Block.newBuilder() .setHeader(buildHeader(params.digestAlgorithm(), reconfigure, head.hash, head.height().add(1), lastCheckpoint.height(), lastCheckpoint.hash, lastViewChange.height(), @@ -294,6 +299,10 @@ public String logState() { params.member().getId()); } + public void setDiadem(HexBloom diadem) { + this.diadem.set(diadem); + } + public void start() { if (!started.compareAndSet(false, true)) { return; @@ -467,7 +476,7 @@ public Block checkpoint() { public Block genesis(Map joining, Digest nextViewId, HashedBlock previous) { final HashedCertifiedBlock cp = checkpoint.get(); final HashedCertifiedBlock v = view.get(); - return CHOAM.genesis(nextViewId, joining, previous, params.context(), v, params, cp, + return CHOAM.genesis(nextViewId, diadem.get(), joining, previous, params.context(), v, params, cp, params.genesisData().apply(joining)); } @@ -504,7 +513,8 @@ public void publish(CertifiedBlock cb) { public Block reconfigure(Map joining, Digest nextViewId, HashedBlock previous, HashedBlock checkpoint) { final HashedCertifiedBlock v = view.get(); - return CHOAM.reconfigure(nextViewId, joining, previous, params.context(), v, params, checkpoint); + return CHOAM.reconfigure(nextViewId, diadem.get(), joining, previous, params.context(), v, params, + checkpoint); } }; } @@ -612,11 +622,13 @@ private void nextView() { log.error("Unable to generate and sign consensus key on: {}", params.member().getId()); return; } - log.trace("Generated next view consensus key: {} sig: {} on: {}", + var current = diadem.get(); + log.trace("Generated next view consensus key: {} sig: {} diadem: {} on: {}", params.digestAlgorithm().digest(pubKey.getEncoded()), - params.digestAlgorithm().digest(signed.toSig().toByteString()), params.member().getId()); + params.digestAlgorithm().digest(signed.toSig().toByteString()), current, params.member().getId()); next.set(new nextView(ViewMember.newBuilder() .setId(params.member().getId().toDigeste()) + .setDiadem(current.toHexBloome()) .setConsensusKey(pubKey) .setSignature(signed.toSig()) .build(), keyPair)); @@ -631,8 +643,9 @@ private void process() { case ASSEMBLE: { params.processor().beginBlock(h.height(), h.hash); nextViewId.set(Digest.from(h.block.getAssemble().getNextView())); - log.info("Next view id: {} on: {}", nextViewId.get(), params.member().getId()); - c.assembled(); + var diadem = HexBloom.from(h.block.getAssemble().getDiadem()); + log.info("Next view id: {} diadem: {} on: {}", nextViewId.get(), diadem.compact(), params.member().getId()); + c.assembled(diadem); break; } case RECONFIGURE: { @@ -1188,14 +1201,15 @@ private class Associate extends Administration { params.digestAlgorithm().digest(nextView.member.getSignature().toByteString()), viewId, params.member().getId()); Signer signer = new SignerImpl(nextView.consensusKeyPair.getPrivate(), ULong.MIN); - producer = new Producer(new ViewContext(context, params, signer, validators, constructBlock()), head.get(), - checkpoint.get(), comm, getLabel()); + producer = new Producer( + new ViewContext(context, () -> diadem.get(), params, signer, validators, constructBlock()), head.get(), + checkpoint.get(), comm, getLabel()); producer.start(); } @Override - public void assembled() { - producer.assembled(); + public void assembled(HexBloom diadem) { + producer.assembled(diadem); } @Override @@ -1231,7 +1245,7 @@ private Formation() { params.digestAlgorithm().digest(c.member.getSignature().toByteString()), params.member().getId()); Signer signer = new SignerImpl(c.consensusKeyPair.getPrivate(), ULong.MIN); - ViewContext vc = new GenesisContext(formation, params, signer, constructBlock()); + ViewContext vc = new GenesisContext(formation, () -> diadem.get(), params, signer, constructBlock()); assembly = new GenesisAssembly(vc, comm, next.get().member, getLabel()); nextViewId.set(params.genesisViewId()); } else { 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 acd13df04..48ba32b8f 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/Committee.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/Committee.java @@ -9,10 +9,7 @@ import com.salesforce.apollo.choam.proto.*; import com.salesforce.apollo.choam.proto.SubmitResult.Result; import com.salesforce.apollo.choam.support.HashedCertifiedBlock; -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.*; import com.salesforce.apollo.cryptography.Verifier.DefaultVerifier; import com.salesforce.apollo.membership.Context; import com.salesforce.apollo.membership.ContextImpl; @@ -63,7 +60,7 @@ static Set viewMembersOf(Digest hash, Context baseContex void accept(HashedCertifiedBlock next); - default void assembled() { + default void assembled(HexBloom diadem) { } void complete(); diff --git a/choam/src/main/java/com/salesforce/apollo/choam/GenesisContext.java b/choam/src/main/java/com/salesforce/apollo/choam/GenesisContext.java index fc8d5bca9..17fdfd734 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/GenesisContext.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/GenesisContext.java @@ -8,20 +8,23 @@ import com.salesforce.apollo.choam.CHOAM.BlockProducer; import com.salesforce.apollo.choam.proto.Validate; +import com.salesforce.apollo.cryptography.HexBloom; import com.salesforce.apollo.cryptography.Signer; import com.salesforce.apollo.cryptography.Verifier; import com.salesforce.apollo.membership.Context; import com.salesforce.apollo.membership.Member; import java.util.Collections; +import java.util.function.Supplier; /** * @author hal.hildebrand */ public class GenesisContext extends ViewContext { - public GenesisContext(Context context, Parameters params, Signer signer, BlockProducer blockProducer) { - super(context, params, signer, Collections.emptyMap(), blockProducer); + public GenesisContext(Context context, Supplier diadem, Parameters params, Signer signer, + BlockProducer blockProducer) { + super(context, diadem, params, signer, Collections.emptyMap(), blockProducer); } @Override 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 b918b40c8..4f29c3217 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/Producer.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/Producer.java @@ -20,6 +20,7 @@ import com.salesforce.apollo.choam.support.HashedCertifiedBlock; import com.salesforce.apollo.choam.support.TxDataSource; import com.salesforce.apollo.cryptography.Digest; +import com.salesforce.apollo.cryptography.HexBloom; import com.salesforce.apollo.ethereal.Config; import com.salesforce.apollo.ethereal.Config.Builder; import com.salesforce.apollo.ethereal.Ethereal; @@ -109,8 +110,8 @@ public Producer(ViewContext view, HashedBlock lastBlock, HashedBlock checkpoint, log.debug("Roster for: {} is: {} on: {}", getViewId(), view.roster(), params().member().getId()); } - public void assembled() { - transitions.assembled(); + public void assembled(HexBloom diadem) { + transitions.assembled(diadem); } public Digest getNextViewId() { @@ -247,6 +248,8 @@ private void produceAssemble() { Assemble.newBuilder() .setNextView( vlb.hash.toDigeste()) + .setDiadem(view.diadem() + .toHexBloome()) .build(), checkpoint.get())); previousBlock.set(assemble); @@ -367,14 +370,15 @@ public void produceAssemble() { } @Override - public void reconfigure() { - log.debug("Starting view reconfiguration for: {} on: {}", nextViewId, params().member().getId()); + public void reconfigure(HexBloom diadem) { + log.debug("Starting view reconfiguration: {} diadem: {} on: {}", nextViewId, diadem.compact(), + params().member().getId()); assembly.set(new ViewAssembly(nextViewId, view, Producer.this::addReassemble, comms) { @Override public void complete() { super.complete(); - log.debug("View reconfiguration: {} gathered: {} complete on: {}", nextViewId, getSlate().size(), - params().member().getId()); + log.debug("View reconfiguration: {} diadem: {} gathered: {} complete on: {}", nextViewId, + diadem.compact(), getSlate().size(), params().member().getId()); assembled.set(true); Producer.this.transitions.viewComplete(); } 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 8800c1d72..83fac081b 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/ViewContext.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/ViewContext.java @@ -19,6 +19,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.function.Supplier; import static com.salesforce.apollo.cryptography.QualifiedBase64.publicKey; @@ -34,15 +35,17 @@ public class ViewContext { private final Map roster; private final Signer signer; private final Map validators; + private final Supplier diadem; - public ViewContext(Context context, Parameters params, Signer signer, Map validators, - BlockProducer blockProducer) { + public ViewContext(Context context, Supplier diadem, Parameters params, Signer signer, + Map validators, BlockProducer blockProducer) { this.blockProducer = blockProducer; this.context = context; this.roster = new HashMap<>(); this.params = params; this.signer = signer; this.validators = validators; + this.diadem = diadem; var remapped = CHOAM.rosterMap(params.context(), context.allMembers().toList()); short pid = 0; @@ -74,6 +77,10 @@ public Context context() { return context; } + public HexBloom diadem() { + return diadem.get(); + } + public Validate generateValidation(HashedBlock block) { log.trace("Signing block: {} height: {} on: {}", block.hash, block.height(), params.member().getId()); JohnHancock signature = signer.sign(block.block.getHeader().toByteString()); diff --git a/choam/src/main/java/com/salesforce/apollo/choam/fsm/Driven.java b/choam/src/main/java/com/salesforce/apollo/choam/fsm/Driven.java index 3e0ec9ce6..60bac80db 100644 --- a/choam/src/main/java/com/salesforce/apollo/choam/fsm/Driven.java +++ b/choam/src/main/java/com/salesforce/apollo/choam/fsm/Driven.java @@ -9,6 +9,7 @@ import com.chiralbehaviors.tron.Entry; import com.chiralbehaviors.tron.FsmExecutor; import com.google.protobuf.ByteString; +import com.salesforce.apollo.cryptography.HexBloom; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,14 +38,14 @@ public interface Driven { void produceAssemble(); - void reconfigure(); + void reconfigure(HexBloom diadem); void startProduction(); enum Earner implements Driven.Transitions { AWAIT_VIEW { @Override - public Transitions assembled() { + public Transitions assembled(HexBloom diadem) { context().assembled(); return null; } @@ -93,7 +94,7 @@ public Transitions start() { } }, PROTOCOL_FAILURE { @Override - public Transitions assembled() { + public Transitions assembled(HexBloom diadem) { return null; } @@ -129,8 +130,8 @@ public void terminate() { } }, SPICE { @Override - public Transitions assembled() { - context().reconfigure(); + public Transitions assembled(HexBloom diadem) { + context().reconfigure(diadem); return null; } @@ -163,7 +164,7 @@ public Transitions viewComplete() { interface Transitions extends FsmExecutor { Logger log = LoggerFactory.getLogger(Transitions.class); - default Transitions assembled() { + default Transitions assembled(HexBloom diadem) { return null; } 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 95d681d14..15e5ead2d 100644 --- a/choam/src/test/java/com/salesforce/apollo/choam/GenesisAssemblyTest.java +++ b/choam/src/test/java/com/salesforce/apollo/choam/GenesisAssemblyTest.java @@ -6,8 +6,6 @@ */ package com.salesforce.apollo.choam; -import com.salesforce.apollo.choam.proto.*; -import com.salesforce.apollo.cryptography.proto.PubKey; import com.salesforce.apollo.archipelago.LocalServer; import com.salesforce.apollo.archipelago.Router; import com.salesforce.apollo.archipelago.ServerConnectionCache; @@ -18,10 +16,13 @@ import com.salesforce.apollo.choam.comm.Terminal; import com.salesforce.apollo.choam.comm.TerminalClient; import com.salesforce.apollo.choam.comm.TerminalServer; +import com.salesforce.apollo.choam.proto.*; import com.salesforce.apollo.choam.support.HashedBlock; import com.salesforce.apollo.cryptography.Digest; import com.salesforce.apollo.cryptography.DigestAlgorithm; +import com.salesforce.apollo.cryptography.HexBloom; import com.salesforce.apollo.cryptography.Signer; +import com.salesforce.apollo.cryptography.proto.PubKey; import com.salesforce.apollo.membership.Context; import com.salesforce.apollo.membership.ContextImpl; import com.salesforce.apollo.membership.Member; @@ -138,8 +139,8 @@ public Block checkpoint() { @Override public Block genesis(Map joining, Digest nextViewId, HashedBlock previous) { - return CHOAM.genesis(viewId, joining, previous, committee, previous, built, previous, - Collections.emptyList()); + return CHOAM.genesis(viewId, new HexBloom(), joining, previous, committee, previous, built, + previous, Collections.emptyList()); } @Override @@ -163,7 +164,8 @@ public Block reconfigure(Map joining, Digest nextViewId, HashedBlo return null; } }; - var view = new GenesisContext(committee, built, sm, reconfigure); + HexBloom diadem = new HexBloom(); + var view = new GenesisContext(committee, () -> diadem, built, sm, reconfigure); KeyPair keyPair = params.getViewSigAlgorithm().generateKeyPair(); final PubKey consensus = bs(keyPair.getPublic()); diff --git a/choam/src/test/java/com/salesforce/apollo/choam/ViewAssemblyTest.java b/choam/src/test/java/com/salesforce/apollo/choam/ViewAssemblyTest.java index 82e3d0bff..1ec56d90d 100644 --- a/choam/src/test/java/com/salesforce/apollo/choam/ViewAssemblyTest.java +++ b/choam/src/test/java/com/salesforce/apollo/choam/ViewAssemblyTest.java @@ -2,9 +2,6 @@ import com.google.protobuf.ByteString; import com.google.protobuf.InvalidProtocolBufferException; -import com.salesforce.apollo.choam.proto.Reassemble; -import com.salesforce.apollo.choam.proto.ViewMember; -import com.salesforce.apollo.cryptography.proto.PubKey; import com.salesforce.apollo.archipelago.LocalServer; import com.salesforce.apollo.archipelago.Router; import com.salesforce.apollo.archipelago.ServerConnectionCache; @@ -14,7 +11,10 @@ import com.salesforce.apollo.choam.comm.Terminal; import com.salesforce.apollo.choam.comm.TerminalClient; import com.salesforce.apollo.choam.comm.TerminalServer; +import com.salesforce.apollo.choam.proto.Reassemble; +import com.salesforce.apollo.choam.proto.ViewMember; import com.salesforce.apollo.cryptography.*; +import com.salesforce.apollo.cryptography.proto.PubKey; import com.salesforce.apollo.ethereal.Config; import com.salesforce.apollo.ethereal.DataSource; import com.salesforce.apollo.ethereal.Ethereal; @@ -53,16 +53,16 @@ public class ViewAssemblyTest { - private static short CARDINALITY = 4; - private Map assemblies = new HashMap<>(); - private Map communications = new HashMap<>(); - private CountDownLatch complete; - private Context context; - private List controllers = new ArrayList<>(); - private Map dataSources; - private List gossipers = new ArrayList<>(); - private List members; - private Digest nextViewId; + private static final short CARDINALITY = 4; + private final Map assemblies = new HashMap<>(); + private final Map communications = new HashMap<>(); + private final List controllers = new ArrayList<>(); + private final List gossipers = new ArrayList<>(); + private CountDownLatch complete; + private Context context; + private Map dataSources; + private List members; + private Digest nextViewId; @AfterEach public void after() { @@ -160,10 +160,11 @@ public ViewMember answer(InvocationOnMock invocation) throws Throwable { e -> new Verifier.DefaultVerifier( e.getValue().getPublic()))); Map views = new HashMap<>(); + HexBloom diadem = new HexBloom(DigestAlgorithm.DEFAULT.getLast(), 0); context.active().forEach(m -> { SigningMember sm = (SigningMember) m; Router router = communications.get(m); - ViewContext view = new ViewContext(context, params.build( + ViewContext view = new ViewContext(context, () -> diadem, params.build( RuntimeParameters.newBuilder().setContext(context).setMember(sm).setCommunications(router).build()), new Signer.SignerImpl(consensusPairs.get(m).getPrivate(), ULong.MIN), validators, null); @@ -213,7 +214,7 @@ private List process(List preblock, Boolean last) { } private static class VDataSource implements DataSource { - private BlockingQueue outbound = new ArrayBlockingQueue<>(100); + private final BlockingQueue outbound = new ArrayBlockingQueue<>(100); @Override public ByteString getData() { diff --git a/cryptography/src/main/java/com/salesforce/apollo/cryptography/HexBloom.java b/cryptography/src/main/java/com/salesforce/apollo/cryptography/HexBloom.java index 1149fdeeb..2db6a95bd 100644 --- a/cryptography/src/main/java/com/salesforce/apollo/cryptography/HexBloom.java +++ b/cryptography/src/main/java/com/salesforce/apollo/cryptography/HexBloom.java @@ -6,9 +6,9 @@ */ package com.salesforce.apollo.cryptography; -import com.salesforce.apollo.cryptography.proto.HexBloome; import com.salesforce.apollo.bloomFilters.BloomFilter; import com.salesforce.apollo.bloomFilters.Primes; +import com.salesforce.apollo.cryptography.proto.HexBloome; import java.util.Arrays; import java.util.Collections; @@ -36,7 +36,7 @@ public class HexBloom { private final BloomFilter membership; public HexBloom(Digest initial, int count) { - assert count > 0; + assert count >= 0; var hashes = hashes(count); crowns = new Digest[count]; cardinality = 0; @@ -57,8 +57,10 @@ public HexBloom(Digest initial, List> hashes) { } public HexBloom(HexBloome hb) { - this(hb.getCardinality(), hb.getCrownsList().stream().map(d -> Digest.from(d)).toList(), - BloomFilter.from(hb.getMembership())); + this(hb.getCardinality(), + hb.getCrownsList().isEmpty() ? Collections.singletonList(DigestAlgorithm.DEFAULT.getLast()) + : hb.getCrownsList().stream().map(d -> Digest.from(d)).toList(), + hb.hasMembership() ? BloomFilter.from(hb.getMembership()) : new BloomFilter.DigestBloomFilter(0, 1, 0.1)); } public HexBloom(int cardinality, List crowns, BloomFilter membership) { @@ -71,6 +73,10 @@ public HexBloom(int cardinality, List crowns, BloomFilter member this.cardinality = cardinality; } + public HexBloom() { + this(DigestAlgorithm.DEFAULT.getLast(), 0); + } + /** * Construct a HexBloom from the supplied parameters, using default hash functions and fpr * diff --git a/ethereal/src/main/java/com/salesforce/apollo/ethereal/Adder.java b/ethereal/src/main/java/com/salesforce/apollo/ethereal/Adder.java index d07c0a86b..4b2b3fd0f 100644 --- a/ethereal/src/main/java/com/salesforce/apollo/ethereal/Adder.java +++ b/ethereal/src/main/java/com/salesforce/apollo/ethereal/Adder.java @@ -6,38 +6,26 @@ */ package com.salesforce.apollo.ethereal; -import static com.salesforce.apollo.ethereal.Creator.parentsOnPreviousLevel; -import static com.salesforce.apollo.ethereal.PreUnit.id; +import com.salesforce.apollo.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter.DigestBloomFilter; +import com.salesforce.apollo.cryptography.Digest; +import com.salesforce.apollo.cryptography.DigestAlgorithm; +import com.salesforce.apollo.cryptography.JohnHancock; +import com.salesforce.apollo.cryptography.Signer; +import com.salesforce.apollo.cryptography.proto.Biff; +import com.salesforce.apollo.ethereal.proto.*; +import com.salesforce.apollo.utils.Entropy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; +import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Stream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.salesforce.apollo.ethereal.proto.Commit; -import com.salesforce.apollo.ethereal.proto.Have; -import com.salesforce.apollo.ethereal.proto.Missing; -import com.salesforce.apollo.ethereal.proto.PreUnit_s; -import com.salesforce.apollo.ethereal.proto.PreVote; -import com.salesforce.apollo.ethereal.proto.SignedCommit; -import com.salesforce.apollo.ethereal.proto.SignedPreVote; -import com.salesforce.apollo.cryptography.proto.Biff; -import com.salesforce.apollo.cryptography.Digest; -import com.salesforce.apollo.cryptography.DigestAlgorithm; -import com.salesforce.apollo.cryptography.JohnHancock; -import com.salesforce.apollo.cryptography.Signer; -import com.salesforce.apollo.utils.Entropy; -import com.salesforce.apollo.bloomFilters.BloomFilter; -import com.salesforce.apollo.bloomFilters.BloomFilter.DigestBloomFilter; +import static com.salesforce.apollo.ethereal.Creator.parentsOnPreviousLevel; +import static com.salesforce.apollo.ethereal.PreUnit.id; /** * Implements the chain Reliable Broadcast of Aleph. @@ -48,23 +36,24 @@ */ public class Adder { - private static final Logger log = LoggerFactory.getLogger(Adder.class); - private final Map> commits = new TreeMap<>(); - private final Config conf; - private final Dag dag; - private final int epoch; - private final Set failed; - private final ReentrantLock lock = new ReentrantLock(true); - private final int maxSize; - private final Map> missing = new TreeMap<>(); - private final Map> prevotes = new TreeMap<>(); - private final Map signedCommits = new TreeMap<>(); - private final Map signedPrevotes = new TreeMap<>(); - private final int threshold; - private final Map waiting = new TreeMap<>(); - private final Map waitingById = new TreeMap<>(); - private final Map waitingForRound = new TreeMap<>(); - private volatile int round = 0; + private static final Logger log = LoggerFactory.getLogger(Adder.class); + private final Map> commits = new TreeMap<>(); + private final Config conf; + private final Dag dag; + private final int epoch; + private final Set failed; + private final ReentrantLock lock = new ReentrantLock(true); + private final int maxSize; + private final Map> missing = new TreeMap<>(); + private final Map> prevotes = new TreeMap<>(); + private final Map signedCommits = new TreeMap<>(); + private final Map signedPrevotes = new TreeMap<>(); + private final int threshold; + private final Map waiting = new TreeMap<>(); + private final Map waitingById = new TreeMap<>(); + private final Map waitingForRound = new TreeMap<>(); + private volatile int round = 0; + public Adder(int epoch, Dag dag, int maxSize, Config conf, Set failed) { this.epoch = epoch; this.dag = dag; @@ -574,7 +563,7 @@ private boolean decodeParents(Waiting wp) { case DUPLICATE_UNIT: case UNKNOWN_PARENTS: return false; - case ABIGUOUS_PARENTS: + case AMBIGUOUS_PARENTS: case COMPLIANCE_ERROR: case DATA_ERROR: removeFailed(wp, decoded); @@ -589,7 +578,7 @@ private boolean decodeParents(Waiting wp) { return false; } var parents = decoded.parents(); - var digests = Stream.of(parents).map(e -> e == null ? (Digest) null : e.hash()).map(e -> e).toList(); + var digests = Stream.of(parents).map(e -> e == null ? null : e.hash()).map(e -> e).toList(); Digest calculated = Digest.combine(conf.digestAlgorithm(), digests.toArray(new Digest[digests.size()])); if (!calculated.equals(wp.pu().view().controlHash())) { removeFailed(wp); @@ -807,7 +796,7 @@ private boolean validateParents(Waiting wp) { * FAILED can occur at each state transition */ public enum State { - COMMITTED, FAILED, OUTPUT, PREVOTED, PROPOSED, WAITING_FOR_PARENTS, WAITING_ON_ROUND; + COMMITTED, FAILED, OUTPUT, PREVOTED, PROPOSED, WAITING_FOR_PARENTS, WAITING_ON_ROUND } public record Signed(Digest hash, T signed) { diff --git a/ethereal/src/main/java/com/salesforce/apollo/ethereal/Correctness.java b/ethereal/src/main/java/com/salesforce/apollo/ethereal/Correctness.java index 83a87a206..22c49d30c 100644 --- a/ethereal/src/main/java/com/salesforce/apollo/ethereal/Correctness.java +++ b/ethereal/src/main/java/com/salesforce/apollo/ethereal/Correctness.java @@ -8,5 +8,5 @@ package com.salesforce.apollo.ethereal; public enum Correctness { - ABIGUOUS_PARENTS, COMPLIANCE_ERROR, CORRECT, DATA_ERROR, DUPLICATE_PRE_UNIT, DUPLICATE_UNIT, UNKNOWN_PARENTS; -} \ No newline at end of file + AMBIGUOUS_PARENTS, COMPLIANCE_ERROR, CORRECT, DATA_ERROR, DUPLICATE_PRE_UNIT, DUPLICATE_UNIT, UNKNOWN_PARENTS +} diff --git a/ethereal/src/main/java/com/salesforce/apollo/ethereal/Dag.java b/ethereal/src/main/java/com/salesforce/apollo/ethereal/Dag.java index 02356644e..956191664 100644 --- a/ethereal/src/main/java/com/salesforce/apollo/ethereal/Dag.java +++ b/ethereal/src/main/java/com/salesforce/apollo/ethereal/Dag.java @@ -6,14 +6,16 @@ */ package com.salesforce.apollo.ethereal; -import static com.salesforce.apollo.ethereal.PreUnit.decode; +import com.salesforce.apollo.bloomFilters.BloomFilter; +import com.salesforce.apollo.bloomFilters.BloomFilter.DigestBloomFilter; +import com.salesforce.apollo.cryptography.Digest; +import com.salesforce.apollo.ethereal.PreUnit.DecodedId; +import com.salesforce.apollo.ethereal.proto.PreUnit_s; +import com.salesforce.apollo.membership.Context; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; @@ -24,21 +26,13 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.salesforce.apollo.ethereal.proto.PreUnit_s; -import com.salesforce.apollo.cryptography.Digest; -import com.salesforce.apollo.ethereal.PreUnit.DecodedId; -import com.salesforce.apollo.membership.Context; -import com.salesforce.apollo.bloomFilters.BloomFilter; -import com.salesforce.apollo.bloomFilters.BloomFilter.DigestBloomFilter; +import static com.salesforce.apollo.ethereal.PreUnit.decode; /** * @author hal.hildebrand */ public interface Dag { - static final Logger log = LoggerFactory.getLogger(Dag.class); + Logger log = LoggerFactory.getLogger(Dag.class); static short threshold(int np) { var nProcesses = (double) np; @@ -113,7 +107,7 @@ static boolean validate(int nProc) { void write(Runnable r); - public interface Decoded { + interface Decoded { default Correctness classification() { return Correctness.CORRECT; } @@ -127,7 +121,7 @@ default Unit[] parents() { } } - public class DagImpl implements Dag { + class DagImpl implements Dag { private final List> checks = new ArrayList<>(); private final Config config; @@ -449,7 +443,7 @@ private void updateMaximal(Unit u) { } } - public record DecodedR(Unit[] parents) implements Decoded { + record DecodedR(Unit[] parents) implements Decoded { @Override public boolean inError() { return false; @@ -462,6 +456,7 @@ record DagInfo(int epoch, int[] heights) { class fiberMap { private final List content = new ArrayList<>(); private final short width; + fiberMap(short width) { this.width = width; } @@ -578,7 +573,7 @@ record AmbiguousParents(List units) implements Decoded { @Override public Correctness classification() { - return Correctness.ABIGUOUS_PARENTS; + return Correctness.AMBIGUOUS_PARENTS; } } diff --git a/grpc/src/main/proto/choam.proto b/grpc/src/main/proto/choam.proto index 76f9aae79..07fa87acd 100644 --- a/grpc/src/main/proto/choam.proto +++ b/grpc/src/main/proto/choam.proto @@ -69,8 +69,9 @@ message Genesis { message Reconfigure { crypto.Digeste id = 1; - int32 checkpointTarget = 2; - repeated Join joins = 3; + crypto.HexBloome view = 2; + int32 checkpointTarget = 3; + repeated Join joins = 4; } message Checkpoint { @@ -86,6 +87,7 @@ message Executions { message Assemble { crypto.Digeste nextView = 1; + crypto.HexBloome diadem = 2; } message FoundationSeal { @@ -115,8 +117,9 @@ message Join { message ViewMember { crypto.Digeste id = 1; - crypto.PubKey consensusKey = 2; - crypto.Sig signature = 3; + crypto.HexBloome diadem = 2; + crypto.PubKey consensusKey = 3; + crypto.Sig signature = 4; } message Certification {