Skip to content

Commit

Permalink
Refactoring for Protonet genesis State setup
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Apr 26, 2024
1 parent 89bbcec commit bfd5674
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 84 deletions.
14 changes: 10 additions & 4 deletions convex-core/src/main/cvx/convex/registry.cvx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

(def trust
^{:private true}
;; Address of the `convex.trust`, it is deployed right after this account, hence it is predictable.
;; Address of `convex.trust`, it is deployed right after this account, hence it is predictable.
(address (inc (long *address*))))

;;;;;;;;;; Address metadata registry
Expand Down Expand Up @@ -52,14 +52,20 @@
;; CNS root reference, i.e. this registry with an empty vector key
(def root [~*address* []])

;; Map of `node key` -> `segment symbol` -> `[path trust-monitor meta]`
;; Map of `node key` -> `segment symbol` -> `[value trust-monitor meta child]`
;; Where:
;; value = Target value for CNS resolution, usually an address or scoped address
;; trust-monitor = controller for this CNS entry
;; meta = metadata field
;; child = child CNS node, may be nil. Usually a scoped address defining an actor and a path key e.g. [#5675 "bob"]
;;
;; Node key is implementation defined in general, but for main registry uses:
;; Empty vector for CNS root
;; vector of segment strings for child paths
(def cns-database
^{:private? true}

{[] {"init" [#1 #1 nil]}})
{[] {"init" [#1 #1 nil nil]}})

;; Controllers for each CNS node managed under this actor
;; Default root is controlled by INIT account
Expand All @@ -71,7 +77,7 @@
{[] #1})

(defn read ^{
:doc {:description "Reads a CNS record as a [addr controller metadata] vector, or nil if record does not exist."
:doc {:description "Reads a CNS record as a [value controller metadata child] vector, or nil if record does not exist."
:examples [{:code "(*registry*/resolve 'my.actor.name)"}]
:signature [{:params [sym]}]}}
([sym]
Expand Down
3 changes: 3 additions & 0 deletions convex-core/src/main/cvx/convex/user.cvx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
;; CNS implementation and registry for `user.xxxx` names

'user
7 changes: 4 additions & 3 deletions convex-core/src/main/java/convex/core/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,18 @@ public class Constants {
public static final long INITIAL_MEMORY_POOL = 1000000L;

/**
* Initial memory price per byte
* Initial memory price per byte 0.001 Convex Gold
*/
public static final long INITIAL_MEMORY_PRICE = 1000000L;

/**
* Memory Pool of growth increment 1mn
* Memory Pool of growth increment 1mb
*/
public static final long MEMORY_POOL_GROWTH = 1000000L;

/**
* Memory Pool of growth interval (once per day)
* Memory Pool of growth interval (once per day).
* This means regular price drops in memory pool
*/
public static final long MEMORY_POOL_GROWTH_INTERVAL = 1000L*24*3600;

Expand Down
5 changes: 5 additions & 0 deletions convex-core/src/main/java/convex/core/data/AccountKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public class AccountKey extends AArrayBlob {

public static final int LENGTH_BITS = LENGTH * 8;

/**
* A null Account Key
*/
public static final AccountKey NULL = null;

private AccountKey(byte[] data, int offset, int length) {
super(data, offset, length);
this.memorySize=0;
Expand Down
12 changes: 1 addition & 11 deletions convex-core/src/main/java/convex/core/data/AccountStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ private AccountStatus(long sequence, AccountKey publicKey, long balance,
}

/**
* Create a regular account, with the specified balance and zero allowance
* Create a regular account, with the specified balance and zero memory allowance
*
* @param sequence Sequence number
* @param balance Convex Coin balance of Account
Expand All @@ -84,16 +84,6 @@ public static AccountStatus create(long sequence, long balance, AccountKey key)
return new AccountStatus(sequence, key, balance, 0L,null,null,null,null,null);
}

/**
* Create a governance account.
*
* @param balance Balance for governance account
* @return New governance AccountStatus
*/
public static AccountStatus createGovernance(long balance) {
return new AccountStatus(Constants.INITIAL_SEQUENCE, null, balance, 0L,null,null,null,null,null);
}

public static AccountStatus createActor() {
return new AccountStatus(Constants.INITIAL_SEQUENCE, null, 0L,0L,null,null,null,null,null);
}
Expand Down
162 changes: 99 additions & 63 deletions convex-core/src/main/java/convex/core/init/Init.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class Init {
// Controller for genesis peer address
public static final Address GENESIS_PEER_ADDRESS = Address.create(12);

// First user of Protonet
// First user of Protonet, i.e. @mikera
public static final Address FIRST_USER_ADDRESS = Address.create(13);

// Constants
Expand All @@ -68,68 +68,107 @@ public class Init {
* @return Base genesis state
*/
public static State createBaseState(List<AccountKey> genesisKeys) {
AccountKey genesisKey=genesisKeys.get(0);

// accumulators for initial state maps
Index<AccountKey, PeerStatus> peers = EMPTY_PEERS;
AVector<AccountStatus> accts = Vectors.empty();

long supply = Constants.MAX_SUPPLY;

// Initial accounts
accts = addGovernanceAccount(accts, NULL_ADDRESS, Coin.ZERO); // Null account
accts = addGovernanceAccount(accts, INIT_ADDRESS, Coin.ZERO); // Initialisation Account

// Foundation fund for startup
long foundation = 1*Coin.EMERALD;
accts = addGovernanceAccount(accts, FOUNDATION_ADDRESS, foundation); // 75% for investors
supply-=foundation;
// Null account, cannot ever be used by anyone
{
AccountStatus nullAccount=AccountStatus.create(Coin.ZERO,AccountKey.NULL);
accts=accts.conj(nullAccount);
}

// Foundation reserve fund (rest of foundation 25%)
long reserve = 248*Coin.EMERALD;
accts = addGovernanceAccount(accts, RESERVE_ADDRESS, reserve); // 24% Foundation
supply -= reserve;

// Reserve for distribution via release curve
long rootFund = 740 * Coin.EMERALD;
accts = addGovernanceAccount(accts, UNRELEASED_ADDRESS, rootFund);
supply -= rootFund;
// "init" Account, used only for network setup and update. Doesn't need coins because we run state updates directly
{
AccountStatus initAccount=AccountStatus.create(Coin.ZERO,AccountKey.NULL);
accts = addAccount(accts, INIT_ADDRESS, initAccount);
}

// Foundation fund for initial operations and fallback governance
{
long foundationFund = 1*Coin.EMERALD;
AccountStatus foundationAccount=AccountStatus.create(foundationFund,genesisKey);
accts = addAccount(accts, FOUNDATION_ADDRESS, foundationAccount);
supply-=foundationFund;
}

// Initial account for release curve distribution
long mainPool = 10 * Coin.EMERALD;
accts = addGovernanceAccount(accts, DISTRIBUTION_ADDRESS, mainPool);
supply -= mainPool;
// Foundation reserve fund (rest of foundation 25%, controlled by foundation account)
{
long reserve = 248*Coin.EMERALD;
AccountStatus reserveAccount=AccountStatus.create(reserve,AccountKey.NULL);
reserveAccount=reserveAccount.withController(FOUNDATION_ADDRESS);
accts = addAccount(accts, RESERVE_ADDRESS, reserveAccount); // 24% Foundation
supply -= reserve;
}

// Reserve for distribution via release curve - 74% for coin purchasers
{
long releaseCurveFund = 740 * Coin.EMERALD;
AccountStatus releaseCurveAccount=AccountStatus.create(releaseCurveFund,AccountKey.NULL);
releaseCurveAccount=releaseCurveAccount.withController(FOUNDATION_ADDRESS);
accts = addAccount(accts, UNRELEASED_ADDRESS, releaseCurveAccount);
supply -= releaseCurveFund;
}

// Initial account for release curve distribution - 1% for initial coin purchasers
{
long distributionFund = 10 * Coin.EMERALD;
AccountStatus releaseCurveAccount=AccountStatus.create(distributionFund,AccountKey.NULL);
releaseCurveAccount=releaseCurveAccount.withController(FOUNDATION_ADDRESS);
accts = addAccount(accts, DISTRIBUTION_ADDRESS, releaseCurveAccount);
supply -= distributionFund;
}

long govern = 1 * Coin.DIAMOND;
accts = addGovernanceAccount(accts, GOVERNANCE_ADDRESS, govern);
supply -= govern;
// Governance Address, used to manage key network operations e.g. CNS root changes
{
long governFund = 1 * Coin.DIAMOND;
AccountStatus governanceAccount=AccountStatus.create(governFund,AccountKey.NULL);
governanceAccount=governanceAccount.withController(FOUNDATION_ADDRESS);
accts = addAccount(accts, GOVERNANCE_ADDRESS, governanceAccount);
supply -= governFund;
}

long admin = 1 * Coin.DIAMOND;
accts = addGovernanceAccount(accts, ADMIN_ADDRESS, admin );
supply -= admin;
// Admin address, used for non-critical operations
{
long admin = 1 * Coin.DIAMOND;
AccountStatus governanceAccount=AccountStatus.create(admin,genesisKey);
governanceAccount=governanceAccount.withController(FOUNDATION_ADDRESS);
accts = addAccount(accts, ADMIN_ADDRESS, governanceAccount);
supply -= admin;
}

// Core library at static address: CORE_ADDRESS
accts = addCoreLibrary(accts);
// Core Account should now be fully initialised
// BASE_USER_ADDRESS = accts.size();


// Always have at least one user and one peer setup
int keyCount = genesisKeys.size();
assert(keyCount > 0);

// Core library at static address: CORE_ADDRESS
accts = addCoreLibrary(accts, CORE_ADDRESS);
// Core Account should now be fully initialised
// BASE_USER_ADDRESS = accts.size();

// Build globals
AVector<ACell> globals = Constants.INITIAL_GLOBALS;

// Create the initial state
// Create the initial state with static libraries and memory allowances
State s = State.create(accts, peers, globals, EMPTY_SCHEDULE);
supply-=s.getGlobalMemoryValue().longValue();

// There should be at least 100,000 Convex Gold for genesis to succeed, to be distributed to genesis account(s)
assert(supply>100000*Coin.GOLD);

// Add the static defined libraries at addresses: TRUST_ADDRESS, REGISTRY_ADDRESS
s = addStaticLibraries(s);

// Reload accounts with the libraries
accts = s.getAccounts();
{
supply-=s.getGlobalMemoryValue().longValue();

// There should be at least 100,000 Convex Gold for genesis to succeed, to be distributed to genesis account(s)
assert(supply>100000*Coin.GOLD);

// Add the static defined libraries at addresses: TRUST_ADDRESS, REGISTRY_ADDRESS
s = addStaticLibraries(s);

// Reload accounts with the libraries
accts = s.getAccounts();
}

// Set up initial user accounts, one for each genesis key.
assert(accts.count() == GENESIS_ADDRESS.longValue());
Expand Down Expand Up @@ -175,7 +214,6 @@ public static State createBaseState(List<AccountKey> genesisKeys) {
assert(peerFunds == 0L);
}


// Add the new accounts to the State
s = s.withAccounts(accts);
// Add peers to the State
Expand Down Expand Up @@ -266,25 +304,24 @@ private static State addStandardLibraries(State s) {
s = doActorDeploy(s, "convex/trust/whitelist.cvx");
s = doActorDeploy(s, "convex/trust/monitors.cvx");
s = doActorDeploy(s, "convex/governance.cvx");
// s = doActorDeploy(s, "convex/user.cvx");
return s;
}

private static State addCNSTree(State s) {
Context ctx=Context.createFake(s, INIT_ADDRESS);
ctx=ctx.eval(Reader.read("(do (*registry*/create 'user.init))"));
ctx.getResult();
//ctx=ctx.eval(Reader.read("(do (*registry*/create 'user.init))"));
//ctx.getResult();

// check we can get access to general trust monitors
//ctx=ctx.eval(Reader.read("(import convex.trust.monitors :as mon)"));
//ctx.getResult();

ctx=ctx.eval(Reader.read("(import convex.trust.monitors :as mon)"));
ctx.getResult();

ctx=ctx.eval(Reader.read("(def tmon (mon/permit-actions :create))"));
ctx.getResult();


ctx=ctx.eval(Reader.read("(do ("+TRUST_ADDRESS+"/change-control [*registry* [\"user\"]] tmon))"));
ctx.getResult();
//ctx=ctx.eval(Reader.read("(def tmon (mon/permit-actions :create))"));
//ctx.getResult();

//ctx=ctx.eval(Reader.read("(do ("+TRUST_ADDRESS+"/change-control [*registry* [\"user\"]] tmon))"));
//ctx.getResult();

s=ctx.getState();
return s;
Expand Down Expand Up @@ -375,17 +412,16 @@ private static Index<AccountKey, PeerStatus> addPeer(Index<AccountKey, PeerStatu
if (peers.containsKey(peerKey)) throw new IllegalArgumentException("Duplicate peer key");
return peers.assoc(peerKey, ps);
}

private static AVector<AccountStatus> addGovernanceAccount(AVector<AccountStatus> accts, Address a, long balance) {
long num=a.longValue();
if (accts.count() != num) throw new Error("Incorrect initialisation address: " + a);
AccountStatus as = AccountStatus.createGovernance(balance);
accts = accts.conj(as);

private static AVector<AccountStatus> addAccount(AVector<AccountStatus> accts, Address address, AccountStatus account) {
long num=address.longValue();
if (accts.count() != num) throw new Error("Incorrect initialisation address: " + address);
accts = accts.conj(account);
return accts;
}

private static AVector<AccountStatus> addCoreLibrary(AVector<AccountStatus> accts, Address a) {
if (accts.count() != a.longValue()) throw new Error("Incorrect core library address: " + a);
private static AVector<AccountStatus> addCoreLibrary(AVector<AccountStatus> accts) {
if (accts.count() != CORE_ADDRESS.longValue()) throw new Error("Incorrect core library address: " + accts.count());

AccountStatus as = AccountStatus.createActor();
as=as.withEnvironment(Core.ENVIRONMENT);
Expand Down
2 changes: 1 addition & 1 deletion convex-core/src/test/java/convex/lib/CNSTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class CNSTest extends ACVMTest {
Address init=eval("(*registry*/resolve 'init)");
assertEquals(Init.INIT_ADDRESS,init);

assertEquals(eval("[#1 #1 nil]"), eval("(*registry*/read 'init)"));
assertEquals(eval("[#1 #1 nil nil]"), eval("(*registry*/read 'init)"));
}

@Test public void testCreateNestedFromTop() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public AccountsPanel(Convex convex,StateModel<State> model) {
CellRenderer cr=new CellRenderer(JLabel.RIGHT);
cr.setToolTipText("Sequence number of the account. This is the total number of user transactions executed.");
table.getColumnModel().getColumn(2).setCellRenderer(cr);
table.getColumnModel().getColumn(2).setPreferredWidth(70);
table.getColumnModel().getColumn(2).setPreferredWidth(60);
}

{
Expand Down Expand Up @@ -132,7 +132,7 @@ public AccountsPanel(Convex convex,StateModel<State> model) {
{ // Account public key
AccountKeyRenderer cr=new AccountKeyRenderer();
cr.setToolTipText("Public key of the account. Used to validate transactions from users.");
table.getColumnModel().getColumn(7).setPreferredWidth(200);
table.getColumnModel().getColumn(7).setPreferredWidth(150);
table.getColumnModel().getColumn(7).setCellRenderer(cr);
}

Expand Down

0 comments on commit bfd5674

Please sign in to comment.