Skip to content

Commit

Permalink
Tests and fix for set-peer-stake
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Oct 4, 2024
1 parent c9e256b commit 3288dab
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 14 deletions.
10 changes: 9 additions & 1 deletion convex-core/src/main/java/convex/core/cpos/CPoSConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,21 @@ public class CPoSConstants {
* Milliseconds before peer stake influence starts to decay (3 mins default)
*/
public static final double PEER_DECAY_DELAY = 3*60*1000;

/**
* Time for peer stake to decay by factor 1/e (5 mins default)
* Time for peer stake to decay by factor 1/e (30 mins default)
*/
public static final double PEER_DECAY_TIME = 5*60*1000;

/**
* Minimum proportion of stake that a peer can decay to
*/
public static final double PEER_DECAY_MINIMUM = 0.001;

/**
* Maximum time a block can be resurrected from the past (1 min)
*/
public static final long MAX_BLOCK_BACKDATE = 60*1000;


}
14 changes: 13 additions & 1 deletion convex-core/src/main/java/convex/core/cvm/State.java
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ private BlockResult applyTransactions(Block block) throws InvalidBlockException
State state = this;
int blockLength = block.length();
Result[] results = new Result[blockLength];
long fees=0L;

AVector<SignedData<ATransaction>> transactions = block.getTransactions();
for (int i = 0; i < blockLength; i++) {
Expand All @@ -501,6 +502,10 @@ private BlockResult applyTransactions(Block block) throws InvalidBlockException
// record results from result context
results[i] = Result.fromContext(CVMLong.create(i),rc);

// Get fees from ResultContext
// NOTE: Juice fees includes transaction overhead fees
fees+=rc.getJuiceFees();

// state update
state = rc.context.getState();
//} catch (Exception e) {
Expand All @@ -509,8 +514,15 @@ private BlockResult applyTransactions(Block block) throws InvalidBlockException
// log.error(msg,e);
//}
}

// maybe add used juice to peer fees
if (fees>0L) {
long oldFees=state.getGlobalFees().longValue();
long newFees=oldFees+fees;
state=state.withGlobalFees(CVMLong.create(newFees));
}

// TODO: changes for complete block?
// TODO: other things for complete block?
return BlockResult.create(state, results);
}

Expand Down
9 changes: 1 addition & 8 deletions convex-core/src/main/java/convex/core/lang/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -411,13 +411,6 @@ public Context completeTransaction(State initialState, ResultContext rc) {
// update Account
state=state.putAccount(address,account);

// maybe add used juice to peer fees
if (juiceFees>0L) {
long oldFees=state.getGlobalFees().longValue();
long newFees=oldFees+juiceFees;
state=state.withGlobalFees(CVMLong.create(newFees));
}

// final state update and result reporting
Context rctx=this.withState(state);
if (juiceFailure) {
Expand Down Expand Up @@ -2007,7 +2000,7 @@ public Context setDelegatedStake(AccountKey peerKey, Address staker, long newSta
* @return Updated Context
*/
public Context setPeerStake(AccountKey peerKey, long newStake) {
return setPeerStake(peerKey,newStake);
return setPeerStake(peerKey,getAddress(),newStake);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion convex-core/src/main/java/convex/core/util/Economics.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ public static long swapPrice(long delta,long a, long b) {
}

public static double stakeDecay(long time, long peerTime) {
if (peerTime<0) return CPoSConstants.PEER_DECAY_MINIMUM;
if (peerTime>=time) return 1.0;
double delay=time-peerTime;
delay-=CPoSConstants.PEER_DECAY_DELAY;
if (delay<0) return 1.0;

return Math.max(0.001, Math.exp(-delay/CPoSConstants.PEER_DECAY_TIME));
return Math.max(CPoSConstants.PEER_DECAY_MINIMUM, Math.exp(-delay/CPoSConstants.PEER_DECAY_TIME));
}
}
2 changes: 1 addition & 1 deletion convex-core/src/test/java/convex/core/TokenomicsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public void testTransferFail() {

protected void checkFinalState(ResultContext rc, boolean memUsed) {
// Nothing should have gone wrong with total coin supply
assertEquals(Coin.MAX_SUPPLY,rc.getState().computeTotalBalance());
assertEquals(Coin.MAX_SUPPLY-rc.getJuiceFees(),rc.getState().computeTotalBalance());

if (memUsed) {
// we expect total memory to have fallen because of memory used
Expand Down
5 changes: 3 additions & 2 deletions convex-core/src/test/java/convex/core/TransactionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ public void testTransfer() {

long memSize=Cells.storageSize(t1);

State s=apply(t1);
ResultContext rc=state().applyTransaction(t1);
State s=rc.context.getState();
long expectedFees=(Juice.TRANSACTION+Juice.TRANSFER+Juice.TRANSACTION_PER_BYTE*memSize)*JP;
assertEquals(expectedFees,s.getGlobalFees().longValue());
assertEquals(expectedFees,rc.getJuiceFees());

long NBAL=s.getAccount(HERO).getBalance();
long balanceDrop=IBAL-NBAL;
Expand Down
51 changes: 51 additions & 0 deletions convex-core/src/test/java/convex/core/lang/CoreTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.util.HashMap;

import org.junit.jupiter.api.Test;

Expand All @@ -36,6 +37,7 @@
import convex.core.ErrorCodes;
import convex.core.cpos.Block;
import convex.core.cpos.BlockResult;
import convex.core.cpos.CPoSConstants;
import convex.core.crypto.AKeyPair;
import convex.core.cvm.State;
import convex.core.data.ABlob;
Expand All @@ -57,6 +59,7 @@
import convex.core.data.Lists;
import convex.core.data.MapEntry;
import convex.core.data.Maps;
import convex.core.data.PeerStatus;
import convex.core.data.Sets;
import convex.core.data.SignedData;
import convex.core.data.Strings;
Expand Down Expand Up @@ -3380,6 +3383,54 @@ public void testStake() {
assertArityError(step(ctx,"(stake my-peer 1000 :foo)"));
}

@Test
public void testSetPeerStake() {
// Not a real peer key, but we don't care because not actually running one....
AccountKey KEY=AccountKey.fromHex("1234567812345678123456781234567812345678123456781234567812345678");
long STK=1000000;
Context ctx=context();


assertNull(ctx.getState().getPeer(KEY));
assertStateError(step(ctx,"(set-peer-stake "+KEY+" "+STK+")"));

// create peer with initial stake
ctx=exec(ctx,"(create-peer "+KEY+" "+STK+")");

// Check stake has been established
PeerStatus ps=ctx.getState().getPeer(KEY);
assertEquals(ps, eval(ctx,"(get-in *state* [:peers "+KEY+"])"));
assertEquals(STK,ps.getPeerStake());
assertEquals(STK,ps.getTotalStake());
assertEquals(STK,ps.getBalance());

// Effective stake should be decayed to minimum, since no blocks for this peer yet
HashMap<AccountKey,Double> stks=ctx.getState().computeStakes();
assertEquals(STK*CPoSConstants.PEER_DECAY_MINIMUM,stks.get(KEY));

// Increase stake
ctx=exec(ctx,"(set-peer-stake "+KEY+" "+STK*3+")");
ps=ctx.getState().getPeer(KEY);
assertEquals(STK*3,ps.getPeerStake());
assertEquals(STK*3,ps.getTotalStake());
assertEquals(STK*3,ps.getBalance());


assertFundsError(step(ctx,"(set-peer-stake "+KEY+" 999999999999999999)"));
assertEquals(Coin.MAX_SUPPLY,ctx.getState().computeTotalBalance());

// Finally remove all stake
ctx=exec(ctx,"(set-peer-stake "+KEY+" 0)");
ps=ctx.getState().getPeer(KEY);
assertEquals(0,ps.getPeerStake());
assertEquals(0,ps.getTotalStake());
assertEquals(0,ps.getBalance());

assertArityError(step(ctx,"(set-peer-stake)"));
assertArityError(step(ctx,"(set-peer-stake "+KEY+")"));
assertArityError(step(ctx,"(set-peer-stake "+KEY+" :foo :bar)"));
}

@Test
public void testSetPeerData() {
String newHostname = "new_hostname:1234";
Expand Down

0 comments on commit 3288dab

Please sign in to comment.