Skip to content

Commit

Permalink
Add logging for token transfers
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Dec 20, 2024
1 parent 62e14be commit 2d42120
Show file tree
Hide file tree
Showing 19 changed files with 290 additions and 73 deletions.
26 changes: 20 additions & 6 deletions convex-core/src/main/cvx/convex/asset/fungible.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,12 @@
(cond (> amount bal) (fail :FUNDS "Burn amount not available" ))

;; do updates to balance and supply
(set-holding *caller* (- bal amount))
(set! supply (- supply amount))))
(let [new-supply (- supply amount)]
(log "MINT" *caller* (- amount) new-supply)
(set-holding *caller* (- bal amount))
(set! supply new-supply)
)
))

(defn mint
^{:callable true}
Expand All @@ -57,8 +61,11 @@
;; New supply must be in valid range.
~(if max-supply `(when-not (<= 0 new-supply max-supply) (fail :STATE "Mint exceeds max supply")))

(log "MINT" *caller* amount new-supply)
(set-holding *caller* new-bal)
(set! supply new-supply))))))
(set! supply new-supply)

)))))

(defn build-token
^{:doc {:description ["Creates deployable code for a new fungible token which follows the interface described in `convex.asset`."
Expand Down Expand Up @@ -164,10 +171,17 @@
(cond (> amount bal) (fail :FUNDS "insufficent token balance"))

;; Need this in case of self-transfers.
(when (= *caller* addr) (return amount))
(when (= *caller* addr)
(log "TR" *caller* addr amount bal bal data)
(return amount))


(set-holding *caller* (- bal amount))
(set-holding addr (+ tbal amount))))
(let [nsb (- bal amount)
nrb (+ tbal amount)]
(log "TR" *caller* addr amount nsb nrb data)
(set-holding *caller* nsb)
(set-holding addr nrb))
))

(defn get-offer
^{:callable true}
Expand Down
10 changes: 8 additions & 2 deletions convex-core/src/main/cvx/convex/asset/multi-token.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,15 @@
;; Need this check in case of self-transfers.
(when (= *caller*
addr)
(log "TR" addr addr amount bal bal data)
(return amount))
(-set-balance *caller* id (- bal amount))
(-set-balance addr id (+ tbal amount))))

(let [nsb (- bal amount)
nrb (+ tbal amount)]
(log "TR" *caller* addr amount nsb nrb data)
(-set-balance *caller* id nsb)
(-set-balance addr id nrb))
))

(defn balance
^{:callable true}
Expand Down
9 changes: 6 additions & 3 deletions convex-core/src/main/cvx/convex/asset/share.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,14 @@
;; Need this check in case of self-transfers.
(when (= *caller*
addr)
(log "TR" addr addr amount bal bal data)
(return amount))

;; TODO: need to transfer unclaimed quantity
(-set-balance *caller* id (- bal amount))
(-set-balance addr id (+ tbal amount))
(let [nsb (- bal amount)
nrb (+ tbal amount)]
(log "TR" *caller* addr amount nsb nrb data)
(-set-balance *caller* id nsb)
(-set-balance addr id nrb))
amount))

(defn balance
Expand Down
17 changes: 12 additions & 5 deletions convex-core/src/main/cvx/convex/asset/wrap/convex.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,17 @@
(cond (< amount 0) (fail :ARGUMENT "negative transfer"))
(cond (> amount bal) (fail :FUNDS "insufficent token balance"))

;; Need this check in case of self-transfers.
(when (= *caller* addr)
(return amount))
(-set-balance *caller* (- bal amount))
(-set-balance addr (+ tbal amount))))
;; Need this in case of self-transfers.
(when (= *caller* addr)
(log "TR" *caller* addr amount bal bal data)
(return amount))

(let [nsb (- bal amount)
nrb (+ tbal amount)]
(log "TR" *caller* addr amount nsb nrb data)
(-set-balance *caller* (- bal amount))
(-set-balance addr (+ tbal amount)))
))


;;;;; Wrap and unwrap
Expand Down Expand Up @@ -139,6 +145,7 @@
noff (- off quantity)
nos (cond (<= noff 0) (dissoc os receiver) (assoc os receiver noff))
nrec [nbal nos]]

;; Update offer and balance of sender
(set-holding sender nrec)
;; Add accepted quantity adeed to receiver
Expand Down
12 changes: 11 additions & 1 deletion convex-core/src/main/cvx/convex/core/core.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -729,4 +729,14 @@
supply 1000000000000000000]
(cond (>= i 8)
supply
(recur (inc i) (- supply (balance (address i))))))))
(recur (inc i) (- supply (balance (address i))))))))

(defn scope
^{:doc {:description "Gets the scope from a callable value, or nil if undefined"
:examples [{:code "(scope [#29 :foo])"}]
:signature [{:params [a]}]}}
[a]
(cond
(address? a) nil
(not (callable? a)) nil
(nth a 1)))
2 changes: 1 addition & 1 deletion convex-core/src/main/java/convex/core/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public class Constants {
public static final AVector<ACell> INITIAL_GLOBALS = Vectors.of(
Constants.INITIAL_TIMESTAMP, Constants.INITIAL_FEES,
Constants.INITIAL_JUICE_PRICE, Constants.INITIAL_MEMORY_POOL,
Constants.INITIAL_MEMORY_POOL * Constants.INITIAL_MEMORY_PRICE);
Constants.INITIAL_MEMORY_POOL * Constants.INITIAL_MEMORY_PRICE, -1L);

/**
* Maximum length of a symbolic name in bytes (keywords and symbols)
Expand Down
1 change: 1 addition & 0 deletions convex-core/src/main/java/convex/core/cvm/Address.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public boolean equals(ACell o) {
}

public final boolean equals(Address o) {
if (o==null) return false;
return value==o.value;
}

Expand Down
64 changes: 48 additions & 16 deletions convex-core/src/main/java/convex/core/cvm/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
import convex.core.lang.Core;
import convex.core.lang.RT;
import convex.core.lang.impl.CoreFn;
import convex.core.lang.impl.TransactionContext;
import convex.core.util.Economics;
import convex.core.util.ErrorMessages;
import convex.core.util.Utils;
Expand Down Expand Up @@ -104,7 +103,7 @@ public class Context {
private ChainState chainState;

/**
* Local log is an ordered [vector of [address caller scope location [values ...] ] entries
* Local log is an ordered [vector of [address scope location [values ...] ] entries
* See CAD33 for details
*/
private AVector<AVector<ACell>> log;
Expand Down Expand Up @@ -173,10 +172,10 @@ private ChainState(State state, TransactionContext transactionContext,Address ca
this.scope=scope;
}

public static ChainState create(State state, TransactionContext origin, Address caller, Address address, long offer, ACell scope) {
public static ChainState create(State state, TransactionContext tContext, Address caller, Address address, long offer, ACell scope) {
AccountStatus as=state.getAccount(address);
if (as==null) return null;
return new ChainState(state,origin,caller,address,as,offer,scope);
return new ChainState(state,tContext,caller,address,as,offer,scope);
}

public ChainState withStateOffer(State newState,long newOffer) {
Expand Down Expand Up @@ -238,7 +237,7 @@ public AccountStatus getAccount() {
}

public Address getOrigin() {
return txContext.origin;
return txContext.getOrigin();
}

public AccountStatus getOriginAccount() {
Expand All @@ -251,6 +250,15 @@ public AccountKey getPeer() {
return txContext.getPeer();
}

public ChainState withTransactionContext(TransactionContext tctx) {
if (txContext==tctx) return this;
return create(state,tctx,caller,address,offer,scope);
}

public TransactionContext getTransactionContext() {
return txContext;
}

}

protected Context(ChainState chainState, long juice, long juiceLimit, AVector<ACell> localBindings2,ACell result, int depth, AExceptional exception, AVector<AVector<ACell>> log, CompilerState comp) {
Expand All @@ -272,8 +280,7 @@ private static <T extends ACell> Context create(ChainState cs, long juice,long j
return ctx;
}

private static <T extends ACell> Context create(State state, long juice,long juiceLimit,AVector<ACell> localBindings, T result, int depth, Address origin,Address caller, Address address, long offer, AVector<AVector<ACell>> log, CompilerState comp) {
TransactionContext tctx=TransactionContext.createQuery(state, origin);
private static <T extends ACell> Context create(State state, TransactionContext tctx,long juice,long juiceLimit,AVector<ACell> localBindings, T result, int depth, Address origin,Address caller, Address address, long offer, AVector<AVector<ACell>> log, CompilerState comp) {
ChainState chainState=ChainState.create(state,tctx,caller,address,offer,NULL_SCOPE);
if (chainState==null) throw new Error("Attempting to create context with invalid Address");
return create(chainState,juice,juiceLimit,localBindings,result,depth,log,comp);
Expand Down Expand Up @@ -302,8 +309,7 @@ public static Context create(State state) {
* @return Fake context
*/
public static Context create(State state, Address origin) {
if (origin==null) throw new IllegalArgumentException("Null address!");
return create(state,0,Constants.MAX_TRANSACTION_JUICE,EMPTY_BINDINGS,NO_RESULT,ZERO_DEPTH,origin,null,origin, ZERO_OFFER, DEFAULT_LOG,null);
return create(state,origin,Constants.MAX_TRANSACTION_JUICE);
}

/**
Expand All @@ -318,13 +324,15 @@ public static Context create(State state, Address origin) {
* @return Initial execution context with reserved juice.
*/
public static Context create(State state, Address origin,long juiceLimit) {
if (origin==null) throw new IllegalArgumentException("Null address!");
TransactionContext tctx=TransactionContext.create(state);
tctx.origin=origin;
AccountStatus as=state.getAccount(origin);
if (as==null) {
// no account
return Context.create(state).withError(ErrorCodes.NOBODY);
}

return create(state,0,juiceLimit,EMPTY_BINDINGS,NO_RESULT,ZERO_DEPTH,origin,null,origin,INITIAL_JUICE,DEFAULT_LOG,null);
return create(state,tctx,0,juiceLimit,EMPTY_BINDINGS,NO_RESULT,ZERO_DEPTH,origin,null,origin,INITIAL_JUICE,DEFAULT_LOG,null);
}


Expand Down Expand Up @@ -1344,7 +1352,7 @@ public Context evalAs(Address target, ACell form) {
if (!canControl) return ctx.withError(ErrorCodes.TRUST,"Cannot control address: "+target);

// SECURITY: eval with a context switch
final Context exContext=Context.create(ctx.getState(), ctx.juice,juiceLimit, EMPTY_BINDINGS, NO_RESULT, depth+1, getOrigin(),caller, target,ZERO_OFFER,ctx.log,NO_COMPILER_STATE);
final Context exContext=Context.create(ctx.getState(),getTransactionContext(), ctx.juice,juiceLimit, EMPTY_BINDINGS, NO_RESULT, depth+1, getOrigin(),caller, target,ZERO_OFFER,ctx.log,NO_COMPILER_STATE);

final Context rContext=exContext.eval(form);
// SECURITY: must handle results as if returning from an actor call
Expand Down Expand Up @@ -1715,13 +1723,17 @@ public Context actorCall(ACell target, long offer, ACell functionName, ACell...
* @return
*/
private Context forkActorCall(State state, Address target, long offer, ACell scope) {
Context fctx=Context.create(state, juice, juiceLimit,EMPTY_BINDINGS, NO_RESULT, depth+1, getOrigin(),getAddress(), target,offer, log,NO_COMPILER_STATE);
Context fctx=Context.create(state, getTransactionContext(),juice, juiceLimit,EMPTY_BINDINGS, NO_RESULT, depth+1, getOrigin(),getAddress(), target,offer, log,NO_COMPILER_STATE);
if (scope!=null) {
fctx.chainState=fctx.chainState.withScope(scope);
}
return fctx;
}

private TransactionContext getTransactionContext() {
return chainState.getTransactionContext();
}

/**
* Handle results at the end of an execution boundary (actor call, transaction etc.)
* @param returnContext Context containing return from child transaction / call
Expand Down Expand Up @@ -1821,7 +1833,7 @@ public Context deploy(ACell... code) {
State stateSetup=initialState.addActor();

// Deployment execution context with forked context and incremented depth
Context ctx=Context.create(stateSetup, juice, juiceLimit,EMPTY_BINDINGS, NO_RESULT, depth+1, getOrigin(),getAddress(), address,ZERO_OFFER,log,NO_COMPILER_STATE);
Context ctx=Context.create(stateSetup, getTransactionContext(), juice, juiceLimit,EMPTY_BINDINGS, NO_RESULT, depth+1, getOrigin(),getAddress(), address,ZERO_OFFER,log,NO_COMPILER_STATE);
for (int i=0; i <n; i++) {
ctx=ctx.eval(code[i]);
if (ctx.isExceptional()) break;
Expand Down Expand Up @@ -2247,7 +2259,8 @@ public Context appendLog(AVector<ACell> values) {
if (log==null) {
log=Vectors.empty();
}
AVector<ACell> entry = Vectors.of(addr,scope,null,values);
AVector<CVMLong> location=getLocation();
AVector<ACell> entry = Vectors.of(addr,scope,location,values);
log=log.conj(entry);

this.log=log;
Expand Down Expand Up @@ -2361,10 +2374,29 @@ public AFn<ACell> lookupExpander(ACell form) {
* @return Peer key, or null if outside a peer created block
*/
public AccountKey getPeer() {
// TODO Auto-generated method stub
return chainState.getPeer();
}

/**
* Gets the most recent log entry, or null if not available.
* @return
*/
public AVector<ACell> lastLog() {
AVector<AVector<ACell>> log=getLog();
long n=log.count();
if (n==0) return null;
return log.get(n-1);
}

public Context withTransactionContext(TransactionContext tctx) {
return withChainState(chainState.withTransactionContext(tctx));
}

public AVector<CVMLong> getLocation() {

return chainState.txContext.getLocation();
}



}
3 changes: 2 additions & 1 deletion convex-core/src/main/java/convex/core/cvm/Peer.java
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ public ResultContext executeQuery(ACell form, Address address) {
* @return The Context containing the transaction results.
*/
public ResultContext executeDetached(ATransaction transaction) {
ResultContext ctx=getConsensusState().applyTransaction(transaction);
State s=getConsensusState();
ResultContext ctx=getConsensusState().applyTransaction(transaction,TransactionContext.create(s));
return ctx;
}

Expand Down
Loading

0 comments on commit 2d42120

Please sign in to comment.