Skip to content

Commit 7d4d4d5

Browse files
committed
Merge branch 'netty-server' into develop
2 parents fa037b5 + a1b92a2 commit 7d4d4d5

File tree

101 files changed

+2496
-1292
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+2496
-1292
lines changed

convex-cli/GENESIS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ alias convex="java -jar ~/convex.jar"
3838
### Upload keystore
3939

4040

41+
### Critical public keys:
42+
43+
Genesis/Admin Key: `0xc1d3b0104d55ddf7680181a46e93422e49e2ea9298e37794860f1ef1128427f7`
44+
Governance key: `0xaE9C747a9730D63Fc16BcccEBd12B5dD4c8fBe1328e9a953025e8C02164Ed5E6`
45+
mikera key: `0x89b5142678bfef7a2245af5ae5b9ab1e10c282b375fa297c5aaeccc48ac97cac`
4146

4247

4348
### Managing with screen

convex-cli/src/main/java/convex/cli/mixins/RemotePeerMixin.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ public Convex connect() {
4343
throw new CLIError("Timeout while attempting to connect to peer: "+hostname,e);
4444
} catch (IOException e) {
4545
throw new CLIError("IO Error: "+e.getMessage(),e);
46+
} catch (InterruptedException e) {
47+
Thread.currentThread().interrupt();
48+
throw new CLIError("Connection interrupted",e);
4649
}
4750
}
4851

convex-core/src/main/cvx/convex/asset/multi-token.cvx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@
160160
(assoc rec 1 (assoc os receiver quantity)))]
161161
(set-holding *caller* (assoc hs id nrec)))
162162
(do ;; create a new record with given offer
163-
(or (get tokens id) (fail "token does not exist"))
163+
(or (get tokens id) (fail :STATE "token does not exist"))
164164
(set-holding *caller* {id [0 {receiver quantity}]})))
165165
quantity ;; return value is quantity offered
166166
))
@@ -203,7 +203,7 @@
203203
[a b]
204204
(let [a (cond a (int a) 0)
205205
b (cond b (int b) 0)]
206-
(if (>= a b) (- a b) 0)))
206+
(cond (>= a b) (- a b) 0)))
207207

208208
(defn quantity-subset?
209209
^{:callable true}

convex-core/src/main/cvx/convex/torus/exchange.cvx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
;;;;;;;;;; Imports
1010

11+
(set-controller #2)
1112

1213
(import convex.asset :as asset)
1314
(import convex.fungible :as fungible)
@@ -45,6 +46,8 @@
4546
(def torus ~torus)
4647
(def token-balance 0)
4748

49+
(set-controller torus)
50+
4851
(defn -qc
4952
[q]
5053
(cond (int? q) q ;; base case, quantity should always be an integer

convex-core/src/main/java/convex/core/Constants.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class Constants {
1919
/**
2020
* Initial timestamp for new States
2121
*/
22-
public static final long INITIAL_TIMESTAMP = Instant.parse("2020-12-06T05:08:13.0864Z").toEpochMilli();
22+
public static final long INITIAL_TIMESTAMP = Instant.parse("2024-12-20T02:21:42.0200Z").toEpochMilli();
2323
// public static final long INITIAL_TIMESTAMP = Instant.parse("2024-12-06T05:08:13.0864Z").toEpochMilli();
2424

2525
/**
@@ -38,15 +38,15 @@ public class Constants {
3838
public static final long INITIAL_MEMORY_PRICE = 1000000L;
3939

4040
/**
41-
* Memory Pool of growth increment 1mb
41+
* Memory Pool of growth increment 40kb / hour i.e. approx. 1mb per day
4242
*/
43-
public static final long MEMORY_POOL_GROWTH = 1000000L;
43+
public static final long MEMORY_POOL_GROWTH = 40000L;
4444

4545
/**
46-
* Memory Pool of growth interval (once per day). This means regular price drops
46+
* Memory Pool of growth interval (once per hour). This means regular price drops
4747
* in memory pool
4848
*/
49-
public static final long MEMORY_POOL_GROWTH_INTERVAL = 1000L * 24 * 3600;
49+
public static final long MEMORY_POOL_GROWTH_INTERVAL = 1000L * 3600;
5050

5151
/**
5252
* Max juice allowable during execution of a single transaction.
@@ -161,7 +161,7 @@ public class Constants {
161161
* Flag to omit filling in stack traces on validation exceptions. This helps
162162
* performance against DoS attacks
163163
*/
164-
public static final boolean OMIT_VALIDATION_STACKTRACES = true;
164+
public static final boolean OMIT_VALIDATION_STACKTRACES = false;
165165

166166
public static final int PBE_ITERATIONS = 100000;
167167

convex-core/src/main/java/convex/core/Result.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ public static Result error(Keyword errorCode, AString message) {
129129
return error(errorCode,message,null);
130130
}
131131

132+
public static Result value(ACell value) {
133+
return create(null,value);
134+
}
135+
132136
public static Result error(Keyword errorCode, String message) {
133137
return error(errorCode,Strings.create(message),null);
134138
}
@@ -320,7 +324,7 @@ public boolean isError() {
320324
* @return New Result instance
321325
*/
322326

323-
public static Result fromContext(CVMLong id,ResultContext rc) {
327+
public static Result fromContext(ACell id,ResultContext rc) {
324328
Context ctx=rc.context;
325329
Object result=ctx.getValue();
326330
ACell errorCode=null;
@@ -377,6 +381,7 @@ public static Result fromContext(Context ctx) {
377381
* @return Updated Result
378382
*/
379383
public Result withID(ACell id) {
384+
if (Cells.equals(id, getID())) return this;
380385
return withValues(values.assoc(ID_POS, id));
381386
}
382387

@@ -386,7 +391,9 @@ public Result withID(ACell id) {
386391
* @return Result instance representing the exception (will be an error)
387392
*/
388393
public static Result fromException(Throwable e) {
389-
if (e==null) return Result.error(ErrorCodes.EXCEPTION,Strings.NIL);
394+
if (e==null) {
395+
return Result.error(ErrorCodes.EXCEPTION,Strings.NIL);
396+
}
390397
if (e instanceof TimeoutException) {
391398
String msg=e.getMessage();
392399
return Result.error(ErrorCodes.TIMEOUT,Strings.create(msg));
@@ -426,6 +433,12 @@ public static Result fromException(Throwable e) {
426433
// Note interrupts are always caused by CLIENT from a local perspective
427434
private static final Result INTERRUPTED_RESULT=Result.error(ErrorCodes.INTERRUPTED,Strings.create("Interrupted!")).withSource(SourceCodes.CLIENT);
428435
private static final Result MISSING_RESULT=Result.error(ErrorCodes.MISSING,Strings.create("Missing Data!")).withSource(SourceCodes.CLIENT);
436+
public static final Result CLOSED_CONNECTION = Result.error(ErrorCodes.CONNECT,Strings.create("Connection Closed")).withSource(SourceCodes.COMM);
437+
public static final Result SENT_MESSAGE = Result.value(Strings.intern("Sent"));
438+
public static final Result FULL_CLIENT_BUFFER = Result.error(ErrorCodes.LOAD, Strings.FULL_BUFFER).withSource(SourceCodes.COMM);
439+
public static final Result BAD_FORMAT = Result.error(ErrorCodes.FORMAT, "Bad format");
440+
441+
429442

430443
/**
431444
* Returns a Result representing a thread interrupt, AND sets the interrupt status on the current thread
@@ -436,6 +449,8 @@ private static Result interruptThread() {
436449
return INTERRUPTED_RESULT;
437450
}
438451

452+
453+
439454
/**
440455
* Converts this result to a JSON representation. WARNING: some information may be lost because JSON is a terrible format.
441456
*
@@ -461,6 +476,7 @@ public HashMap<String, Object> toJSON() {
461476

462477
private static final StringShort RESULT_TAG=StringShort.create("#Result");
463478

479+
464480
@Override
465481
public boolean print(BlobBuilder sb, long limit) {
466482
sb.append(RESULT_TAG);
@@ -532,6 +548,11 @@ public static Result fromJSON(Object json) {
532548
return Result.create(id, value, errorCode);
533549
}
534550

551+
public static ACell peekResultID(Blob messageData, int i) throws BadFormatException {
552+
Result r=Result.read(messageData, i);
553+
return r.getID();
554+
}
555+
535556

536557

537558
}

convex-core/src/main/java/convex/core/cpos/Belief.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ public static Collection<SignedData<Order>> extractOrders(ACell payload) {
237237
@Override
238238
public void validateStructure() throws InvalidDataException {
239239
super.validateStructure();
240-
if (!(values.get(IX_ORDERS) instanceof Index)) {
240+
if (!(values.get(IX_ORDERS) instanceof Index)) {
241241
throw new InvalidDataException("Orders should be an Index",this);
242242
}
243243
}
@@ -248,20 +248,25 @@ public void validateStructure() throws InvalidDataException {
248248
* @param signedBlock Signed Block of transactions
249249
* @return Updated Belief with new Order
250250
*/
251-
public Belief proposeBlock(AKeyPair kp, SignedData<Block> signedBlock) {
251+
@SuppressWarnings("unchecked")
252+
public Belief proposeBlock(AKeyPair kp, SignedData<Block>... signedBlocks) {
252253
AccountKey peerKey=kp.getAccountKey();
253254
Index<AccountKey, SignedData<Order>> orders = getOrders();
254255

255256
SignedData<Order> mySO=orders.get(peerKey);
256257
Order myOrder;
257258
if (mySO==null) {
258-
myOrder=Order.create();
259+
throw new IllegalStateException("Trying to propose block without a current ordering for peer "+peerKey);
259260
} else {
260261
myOrder=mySO.getValue();
261262
}
262263

263264
// Create new order with signed Block
264-
Order newOrder = myOrder.append(signedBlock);
265+
Order newOrder = myOrder;
266+
int n=signedBlocks.length;
267+
for (int i=0; i<n; i++) {
268+
newOrder=newOrder.append(signedBlocks[i]);
269+
}
265270
SignedData<Order> newSignedOrder = kp.signData(newOrder);
266271

267272
Index<AccountKey, SignedData<Order>> newOrders = orders.assoc(peerKey, newSignedOrder);

convex-core/src/main/java/convex/core/cpos/BeliefMerge.java

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,7 @@ private final AVector<SignedData<Block>> appendNewBlocks(AVector<SignedData<Bloc
428428
HashSet<SignedData<Block>> newBlocks = new HashSet<>();
429429
newBlocks.addAll(newBlocksOrdered);
430430

431-
// exclude new blocks already in the base Order
432-
// TODO: what about blocks already in consensus?
433-
// Probably need to check last block time from Peer
431+
// exclude new blocks already in the base consensus Order
434432
long scanStart=Math.min(blocks.count(), consensusPoint);
435433
Iterator<SignedData<Block>> it = blocks.listIterator(scanStart);
436434
while (it.hasNext()) {
@@ -483,7 +481,8 @@ public Long apply(Order c) {
483481
// in order to sort by length of matched proposals
484482
long blockMatch = proposedBlocks.commonPrefixLength(c.getBlocks());
485483

486-
long minPrevious = Math.min(winnningOrder.getConsensusPoint(level-1), c.getConsensusPoint(level-1));
484+
int prevLevel=level-1;
485+
long minPrevious = Math.min(winnningOrder.getConsensusPoint(prevLevel), c.getConsensusPoint(prevLevel));
487486

488487
// Match length is how many blocks agree with winning order at previous consensus level
489488
long match = Math.min(blockMatch, minPrevious);
@@ -561,22 +560,19 @@ public static boolean compareOrders(Order oldOrder, Order newOrder) {
561560
// new Order is more recent, so switch to this
562561
return true;
563562
} else {
563+
// timestamps are the same
564+
564565
// Don't replace if equal
565566
if (oldOrder.equals(newOrder)) return false;
566567

567568
// This probably shouldn't happen if peers are sticking to timestamps
568569
// But we compare anyway
569-
// Prefer advanced consensus
570-
for (int level=CPoSConstants.CONSENSUS_LEVELS-1; level>=1; level--) {
570+
// Prefer more blocks / advanced consensus
571+
for (int level=0; level<CPoSConstants.CONSENSUS_LEVELS; level++) {
571572
if (newOrder.getConsensusPoint(level)>oldOrder.getConsensusPoint(level)) return true;
572573
}
573-
574-
// Finally prefer more blocks
575-
AVector<SignedData<Block>> abs=oldOrder.getBlocks();
576-
AVector<SignedData<Block>> bbs=newOrder.getBlocks();
577-
if(abs.count()<bbs.count()) return true;
574+
return false;
578575
}
579-
return false;
580576
}
581577

582578
/**

convex-core/src/main/java/convex/core/cpos/Block.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.Comparator;
44
import java.util.List;
55

6+
import convex.core.Constants;
67
import convex.core.cvm.ARecordGeneric;
78
import convex.core.cvm.CVMTag;
89
import convex.core.cvm.Keywords;
@@ -41,14 +42,22 @@ public final class Block extends ARecordGeneric {
4142

4243
private final long timestamp;
4344
private AVector<SignedData<ATransaction>> transactions;
45+
46+
private static final int IX_TIMESTAMP= 0;
47+
private static final int IX_TRANSACTIONS = 1;
48+
49+
private static final long NUM_FIELDS = FORMAT.count();
4450

4551
/**
4652
* Comparator to sort blocks by timestamp
4753
*/
4854
static final Comparator<SignedData<Block>> TIMESTAMP_COMPARATOR = new Comparator<>() {
4955
@Override
5056
public int compare(SignedData<Block> a, SignedData<Block> b) {
51-
int sig = Long.compare(a.getValue().getTimeStamp(), b.getValue().getTimeStamp());
57+
Block ba=a.getValue();
58+
Block bb=b.getValue();
59+
60+
int sig = Long.compare(ba.getTimeStamp(), bb.getTimeStamp());
5261
return sig;
5362
}
5463
};
@@ -59,15 +68,16 @@ private Block(long timestamp, AVector<SignedData<ATransaction>> transactions) {
5968
this.transactions = transactions;
6069
}
6170

62-
public Block(AVector<ACell> values) {
71+
private Block(AVector<ACell> values) {
6372
super(CVMTag.BLOCK,FORMAT,values);
64-
this.timestamp=RT.ensureLong(values.get(0)).longValue();
73+
this.timestamp=RT.ensureLong(values.get(IX_TIMESTAMP)).longValue();
74+
6575
}
6676

6777
@Override
6878
public ACell get(Keyword k) {
69-
if (Keywords.TIMESTAMP.equals(k)) return CVMLong.create(timestamp);
70-
if (Keywords.TRANSACTIONS.equals(k)) return transactions;
79+
if (Keywords.TIMESTAMP.equals(k)) return values.get(IX_TIMESTAMP);
80+
if (Keywords.TRANSACTIONS.equals(k)) return getTransactions();
7181
return null;
7282
}
7383

@@ -151,7 +161,7 @@ public static Block read(Blob b, int pos) throws BadFormatException {
151161
* @return Vector of transactions
152162
*/
153163
public AVector<SignedData<ATransaction>> getTransactions() {
154-
if (transactions==null) transactions=RT.ensureVector(values.get(1));
164+
if (transactions==null) transactions=RT.ensureVector(values.get(IX_TRANSACTIONS));
155165
return transactions;
156166
}
157167

@@ -162,7 +172,18 @@ public boolean isCanonical() {
162172

163173
@Override
164174
public void validateCell() throws InvalidDataException {
165-
// nothing to do
175+
if (values.count()!=NUM_FIELDS) throw new InvalidDataException("Wrong field count",this);
176+
}
177+
178+
@Override
179+
public void validateStructure() throws InvalidDataException {
180+
AVector<SignedData<ATransaction>> txs=getTransactions();
181+
if (txs==null) throw new InvalidDataException("No transactions",this);
182+
if (txs.count()>Constants.MAX_TRANSACTIONS_PER_BLOCK) {
183+
throw new InvalidDataException("Too many transactions: "+txs.count(),this);
184+
}
185+
// We don't validate individual transactions here
186+
// This gets enforced latter when transactions are applied
166187
}
167188

168189
@Override

convex-core/src/main/java/convex/core/cpos/CPoSConstants.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public class CPoSConstants {
5050
public static final long INITIAL_PEER_TIMESTAMP = -1L;
5151

5252
/**
53-
* Minimum stake for a Peer to be considered by other Peers in consensus
53+
* Minimum stake balance for a Peer to be considered by other Peers in consensus
5454
*/
5555
public static final long MINIMUM_EFFECTIVE_STAKE = Coin.GOLD * 1000;
5656
/**
@@ -69,8 +69,15 @@ public class CPoSConstants {
6969

7070
/**
7171
* Maximum allowed number of missing hashes in missing data request
72+
*
73+
* (2 header values short of 256, so that request vector is 2 levels at max size)
7274
*/
73-
public static final long MISSING_LIMIT = 256;
75+
public static final int MISSING_LIMIT = 254;
76+
77+
/**
78+
* Milliseconds time between blocks for a peer to collect maximum rewards (10 mins)
79+
*/
80+
public static final long MAX_REWARD_TIME = 10*60*1000;
7481

7582

7683
}

0 commit comments

Comments
 (0)