o1js
Version:
TypeScript framework for zk-SNARKs and zkApps
129 lines (113 loc) • 3.49 kB
text/typescript
// Views into chain-state (ledger and best block)
import { Account, AccountId, AccountIdMap } from './account.js';
import { Field } from '../../provable/field.js';
import { UInt32, UInt64 } from '../../provable/int.js';
import { MinaAmount } from './currency.js';
export { ChainView, EpochData, EpochLedgerData, LedgerView, LocalChain, LocalLedger };
interface ChainView {
snarkedLedgerHash: Field;
blockchainLength: UInt32;
minWindowDensity: UInt32;
totalCurrency: MinaAmount;
globalSlotSinceGenesis: UInt32;
stakingEpochData: EpochData;
nextEpochData: EpochData;
}
interface EpochData {
ledger: EpochLedgerData;
seed: Field;
startCheckpoint: Field;
lockCheckpoint: Field;
epochLength: UInt32;
}
interface EpochLedgerData {
hash: Field;
totalCurrency: MinaAmount;
}
interface LedgerView {
hasAccount(accountId: AccountId): boolean;
getAccount(accountId: AccountId): Account | null;
setAccount(account: Account): void;
updateAccount(accountId: AccountId, f: (account: Account) => Account): void;
}
class LocalChain implements ChainView {
snarkedLedgerHash: Field;
blockchainLength: UInt32;
minWindowDensity: UInt32;
totalCurrency: UInt64;
globalSlotSinceGenesis: UInt32;
stakingEpochData: EpochData;
nextEpochData: EpochData;
constructor(
snarkedLedgerHash: Field,
blockchainLength: UInt32,
minWindowDensity: UInt32,
totalCurrency: UInt64,
globalSlotSinceGenesis: UInt32,
stakingEpochData: EpochData,
nextEpochData: EpochData
) {
this.snarkedLedgerHash = snarkedLedgerHash;
this.blockchainLength = blockchainLength;
this.minWindowDensity = minWindowDensity;
this.totalCurrency = totalCurrency;
this.globalSlotSinceGenesis = globalSlotSinceGenesis;
this.stakingEpochData = stakingEpochData;
this.nextEpochData = nextEpochData;
}
static initial(): LocalChain {
return new LocalChain(
Field.empty(),
UInt32.from(0),
UInt32.from(0),
UInt64.from(0),
UInt32.from(0),
{
ledger: {
hash: Field.empty(),
totalCurrency: UInt64.from(0),
},
seed: Field.empty(),
startCheckpoint: Field.empty(),
lockCheckpoint: Field.empty(),
epochLength: UInt32.from(0),
},
{
ledger: {
hash: Field.empty(),
totalCurrency: UInt64.from(0),
},
seed: Field.empty(),
startCheckpoint: Field.empty(),
lockCheckpoint: Field.empty(),
epochLength: UInt32.from(0),
}
);
}
}
class LocalLedger implements LedgerView {
private accounts: AccountIdMap<Account>;
constructor(accounts: Account[]) {
this.accounts = new AccountIdMap();
for (const account of accounts) {
this.setAccount(account);
}
}
hasAccount(accountId: AccountId): boolean {
return this.accounts.has(accountId);
}
getAccount(accountId: AccountId): Account | null {
return this.accounts.get(accountId);
}
setAccount(account: Account): void {
return this.accounts.set(account.accountId, account);
}
updateAccount(accountId: AccountId, f: (account: Account) => Account): void {
return this.accounts.update(accountId, (possibleAccount) => {
const account = possibleAccount ?? Account.empty(accountId);
const updatedAccount = f(account);
// TODO: if(!updatedAccount.accountId.equals(accountId).toBoolean()) throw new Error('...')
return updatedAccount;
});
}
}