Skip to content

Commit

Permalink
Edits to support --genesis option on peer start
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Oct 8, 2024
1 parent 48d2d05 commit b4903fa
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ EXPOSE 443
VOLUME ["/etc/ssl/certs"]
VOLUME ["/etc/convex/keystore"]

ENTRYPOINT ["java", "-jar", "convex.jar", "local", "start"]
ENTRYPOINT ["java", "-jar", "convex.jar", "peer", "start"]

43 changes: 34 additions & 9 deletions convex-cli/src/main/java/convex/cli/peer/PeerStart.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
import convex.cli.ExitCodes;
import convex.cli.mixins.RemotePeerMixin;
import convex.core.crypto.AKeyPair;
import convex.core.cvm.State;
import convex.core.data.AccountKey;
import convex.core.data.Address;
import convex.core.data.Blob;
import convex.core.data.Keyword;
import convex.core.data.Keywords;
import convex.core.init.Init;
import convex.etch.EtchStore;
import convex.peer.API;
import convex.peer.ConfigException;
Expand Down Expand Up @@ -56,12 +59,18 @@ public class PeerStart extends APeerCommand {
description = "Port number for the peer. Default is ${DEFAULT-VALUE}. If set to 0, will choose a random port.")
private int port = 0;

@Option(names = { "--url" }, description = "URL for the peer to publish. If not provided, the peer will have no public URL.")
@Option(names = { "--url" },
description = "URL for the peer to publish. If not provided, the peer will have no public URL.")
private String url;

@Option(names = { "--norest" }, description = "Disable REST srever.")
private boolean norest;

@Option(names = { "--genesis" },
defaultValue = "${env:CONVEX_GENESIS_SEED}",
description = "Governance seed for network genesis. For testing use only.")
private String genesis;

@Option(names = { "--api-port" },
defaultValue = "8080",
description = "Port for REST API.")
Expand Down Expand Up @@ -115,15 +124,25 @@ public void execute() throws InterruptedException {

storeMixin.ensureKeyStore();
try (EtchStore store = etchMixin.getEtchStore()) {

AKeyPair peerKey=findPeerKey(store);
if (peerKey==null) {
informWarning("No --peer-key specified or inferred from Etch Store "+store);
showUsage();
return;
AKeyPair peerKey;
AKeyPair genesisKey=null;
if (genesis!=null&&(!genesis.isEmpty())) {
paranoia("Should't use Genesis Seed in strict security mode! Consider key compromised!");
Blob seed=Blob.parse(genesis);
if (seed.count()!=32) {
throw new CLIError("Genesis seed must be 32 byte hex blob");
}
peerKey = AKeyPair.create(seed);
genesisKey=peerKey;
informWarning("Using test genesis seed: "+seed);
} else {
peerKey=findPeerKey(store);
if (peerKey==null) {
informWarning("No --peer-key specified or inferred from Etch Store "+store);
showUsage();
return;
}
}

inform("Preparing to start peer: "+peerKey.getAccountKey());

Address controller=Address.parse(controllerAddress);
if (controller==null) {
Expand All @@ -136,6 +155,12 @@ public void execute() throws InterruptedException {
HashMap<Keyword,Object> config=new HashMap<>();
config.put(Keywords.KEYPAIR, peerKey);
config.put(Keywords.STORE, store);
if (genesisKey!=null) {
AccountKey gpk=genesisKey.getAccountKey();
State state=Init.createState(gpk,gpk,List.of(gpk));
informWarning("Greated genesis State: "+state.getHash());
config.put(Keywords.STATE, state);
}
Server server=API.launchPeer(config);

if (!norest) {
Expand Down
7 changes: 5 additions & 2 deletions convex-core/src/main/java/convex/core/data/MapTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import convex.core.exceptions.BadFormatException;
import convex.core.exceptions.InvalidDataException;
import convex.core.exceptions.TODOException;
import convex.core.lang.RT;
import convex.core.exceptions.Panic;
import convex.core.util.Bits;
import convex.core.util.MergeFunction;
Expand Down Expand Up @@ -859,8 +860,10 @@ protected void validateWithPrefix(Hash prefix, int shift) throws InvalidDataExce
throw new InvalidDataException(
"Expected AHashMap child at " + prefix + Utils.toHexChar(digitForIndex(i, mask)), this);
}
@SuppressWarnings("unchecked")
AHashMap<K, V> child = (AHashMap<K, V>) o;
AHashMap<K, V> child = RT.ensureHashMap(o);
if (child==null) {
throw new InvalidDataException("Non-hashmap child at position "+i,this);
}
if (child.isEmpty())
throw new InvalidDataException("Empty child at " + prefix + Utils.toHexChar(digitForIndex(i, mask)),
this);
Expand Down
51 changes: 49 additions & 2 deletions convex-core/src/test/java/convex/core/data/SetsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@
import convex.core.lang.RT;
import convex.test.Samples;

/**
* Tests for general set behaviour and logic
*/
public class SetsTest {

@Test
public void testEmptySet() {
ASet<ACell> e = Sets.empty();
assertEquals(0, e.size());
assertFalse(e.contains(null));
assertSame(e,Sets.create(Vectors.empty()));
assertSame(e,Sets.of(1).exclude(CVMLong.ONE));
}

@Test
Expand All @@ -35,18 +40,23 @@ public void testIncludeExclude() {
assertEquals("#{1}", s.toString());
s = s.include(RT.cvm(2L));
assertEquals("#{2,1}", s.toString());
assertSame(s,s.exclude(null));

s = s.exclude(RT.cvm(1L));
assertEquals("#{2}", s.toString());
s = s.exclude(RT.cvm(2L));
assertTrue(s.isEmpty());
assertSame(s, Sets.empty());
assertSame(Sets.empty(),s);

s = s.exclude(RT.cvm(2L));
assertSame(Sets.empty(),s);
}

@Test
public void testSetEncoding() {
// Set should be encoded as a map with different tag and extra value Ref(s)
ASet<?> s=Sets.of(123);
AMap<?,?> m=Maps.of(123,null);
// compare encodings ignoring tag
assertEquals(m.getEncoding().slice(1),s.getEncoding().append(Blob.SINGLE_ZERO).slice(1));
}

Expand Down Expand Up @@ -139,6 +149,14 @@ public void testMergingIdentity() {
assertSame(a, a.includeAll(Sets.of(1L, 3L)));
}

@Test
public void testNilMembership() {
ASet<CVMLong> a = Sets.of(1, 2, 3, null);
assertTrue(a.containsKey(null));
a=a.exclude(null);
assertEquals(3,a.size());
}

@Test
public void testIntersection() {
ASet<CVMLong> a = Sets.of(1, 2, 3);
Expand Down Expand Up @@ -184,10 +202,16 @@ public void testBigSlice() {
ObjectsTest.doEqualityTests(s,s1.includeAll(s2).includeAll(s3));
}

@SuppressWarnings("unchecked")
@Test
public void testBigMerging() {
ASet<CVMLong> s = Sets.create(Samples.INT_VECTOR_300);
assertEquals(0,((SetTree<CVMLong>)s).shift);
SetsTest.doSetTests(s);

SetTree<CVMLong> child=(SetTree<CVMLong>)(s.getRef(1).getValue());
assertEquals(1,child.shift);
SetsTest.doSetTests(child);

ASet<CVMLong> s2 = s.includeAll(Sets.of(1, 2, 3, 100));
assertEquals(s, s2);
Expand Down Expand Up @@ -231,6 +255,29 @@ public void testIncrementalBuilding() {
}

doSetTests(set);

// now build the same set in hash order
ASet<CVMLong> set2=Sets.empty();
for (int i=0; i<320; i++) {
assertEquals(i,set2.size());

// extend set with one new element
CVMLong v=set.get(i);
set2=set2.conj(v);
}
assertEquals(set2,set);
doSetTests(set); // check nothing is odd

// now deconstruct the set in hash order
ASet<CVMLong> set3=set2;
for (int i=0; i<320; i++) {
assertEquals(320-i,set3.size());

// extend set with one new element
CVMLong v=set.get(i);
set3=set3.exclude(v);
}
assertSame(Sets.EMPTY,set3);
}

/**
Expand Down
1 change: 1 addition & 0 deletions convex-core/src/test/java/convex/core/lang/CoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1935,6 +1935,7 @@ public void testInto() {
assertEquals(Lists.of(2L, 1L, 3L, 4L), eval("(into '(3 4) '(1 2))"));

assertEquals(Sets.of(1L, 2L, 3L), eval("(into #{} [1 2 1 2 3])"));
assertEquals(Sets.of(1L, 2L, 3L), eval("(into #{} #{1 2 3})"));

// map as data structure
assertEquals(Maps.empty(), eval("(into {} [])"));
Expand Down

0 comments on commit b4903fa

Please sign in to comment.