Skip to content

Commit

Permalink
Merge pull request #276 from zallo-labs/Z-314-impr-account-creation
Browse files Browse the repository at this point in the history
Z 314 impr account creation
  • Loading branch information
hbriese authored Jul 28, 2024
2 parents b29798f + 8363533 commit 9c9bee2
Show file tree
Hide file tree
Showing 40 changed files with 765 additions and 693 deletions.
Binary file not shown.
2 changes: 1 addition & 1 deletion api/dbschema/bootstrap.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ configure instance set query_work_mem := <cfg::memory>"8MiB";
configure instance set shared_buffers := <cfg::memory>"2GiB";

# Total memory available to the database for caching - 75%
configure instance set effective_cache_size := <cfg::memory>"3GiB";
configure instance set effective_cache_size := <cfg::memory>"6GiB";
142 changes: 71 additions & 71 deletions api/dbschema/edgeql-js/__spec__.ts

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions api/dbschema/edgeql-js/modules/cfg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export type $AbstractConfigλShape = $.typeutil.flatten<$ConfigObjectλShape & {
"default_statistics_target": $.PropertyDesc<_std.$int64, $.Cardinality.AtMostOne, false, false, false, false>;
"force_database_error": $.PropertyDesc<_std.$str, $.Cardinality.AtMostOne, false, false, false, true>;
"_pg_prepared_statement_cache_size": $.PropertyDesc<_std.$int16, $.Cardinality.One, false, false, false, true>;
"auto_rebuild_query_cache_timeout": $.PropertyDesc<_std.$duration, $.Cardinality.AtMostOne, false, false, false, true>;
"<cfg[is cfg::ExtensionConfig]": $.LinkDesc<$ExtensionConfig, $.Cardinality.AtMostOne, {}, true, false, false, false>;
"<cfg": $.LinkDesc<$.ObjectType, $.Cardinality.Many, {}, false, false, false, false>;
}>;
Expand Down
150 changes: 75 additions & 75 deletions api/dbschema/edgeql-js/modules/default.ts

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion api/dbschema/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export namespace cfg {
"default_statistics_target"?: number | null;
"force_database_error"?: string | null;
"_pg_prepared_statement_cache_size": number;
"auto_rebuild_query_cache_timeout"?: edgedb.Duration | null;
}
export type AllowBareDDL = "AlwaysAllow" | "NeverAllow";
export interface Auth extends ConfigObject {
Expand Down Expand Up @@ -215,9 +216,9 @@ export namespace $default {
"proposal"?: Transaction | null;
"initState": boolean;
"isActive": boolean;
"isDraft": boolean;
"latest"?: PolicyState | null;
"isLatest": boolean;
"isDraft": boolean;
}
export interface Policy extends PolicyState {
"approvers": Approver[];
Expand Down
9 changes: 9 additions & 0 deletions api/dbschema/migrations/00002-m1ob6ar.edgeql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CREATE MIGRATION m1ob6arfwyamzcpgk2hgzhby3iwv3moewthqacorsw2mtyjkopdoaq
ONTO m13qxppnkqofigih7dxkipm2lh6k3ahrqerachqhdzihw76nb6i3aa
{
ALTER TYPE default::PolicyState {
ALTER PROPERTY isDraft {
USING ((__source__ ?= .draft));
};
};
};
4 changes: 2 additions & 2 deletions api/dbschema/policy.esdl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module default {
required initState := .activationBlock ?= 0;
required hasBeenActive := exists .activationBlock;
required isActive := .isLatest and .hasBeenActive;
required isDraft := exists .draft;
required isDraft := (__source__ ?= .draft);
latest := (__source__ if .isLatest else latestPolicy(.account, .key));
draft := assert_single((
with account := __source__.account, key := __source__.key
Expand Down Expand Up @@ -94,9 +94,9 @@ module default {
}

type TransfersConfig {
multi limits: TransferLimit { constraint exclusive; }
required defaultAllow: bool { default := true; };
required budget: uint32;
multi limits: TransferLimit { constraint exclusive; }
}

type TransferLimit {
Expand Down
2 changes: 1 addition & 1 deletion api/edgedb.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[edgedb]
server-version = "5.4"
server-version = "5.6"
47 changes: 11 additions & 36 deletions api/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -207,22 +207,6 @@ input CreateAccountInput {
salt: Bytes32
}

input CreatePolicyInput {
account: UAddress!
actions: [ActionInput!]
allowMessages: Boolean
approvers: [Address!]

"""seconds"""
delay: Float
key: PolicyKey
name: String
threshold: Float
transfers: TransfersConfigInput
}

union CreatePolicyResponse = NameTaken | Policy

interface CustomNode {
id: ID!
}
Expand Down Expand Up @@ -342,12 +326,12 @@ type Mutation {
approveMessage(input: ApproveInput!): Message!
approveTransaction(input: ApproveInput!): Transaction!
createAccount(input: CreateAccountInput!): Account!
createPolicy(input: CreatePolicyInput!): CreatePolicyResponse!
deleteContact(address: UAddress!): ID
execute(input: ExecuteTransactionInput!): Transaction
link(input: LinkInput!): User!
proposeCancelScheduledTransaction(input: ProposeCancelScheduledTransactionInput!): Transaction!
proposeMessage(input: ProposeMessageInput!): Message!
proposePolicies(input: ProposePoliciesInput!): [Policy!]!
proposeTransaction(input: ProposeTransactionInput!): Transaction!
rejectProposal(input: UniqueProposalInput!): Proposal!
removeMessage(input: UniqueProposalInput!): ID!
Expand All @@ -357,8 +341,7 @@ type Mutation {
requestTokens(input: RequestTokensInput!): [Address!]!
updateAccount(input: UpdateAccountInput!): Account!
updateApprover(input: UpdateApproverInput!): Approver!
updatePolicies(input: UpdatePoliciesInput!): [Policy!]!
updatePolicy(input: UpdatePolicyInput!): UpdatePolicyResponse!
updatePolicyDetails(input: UpdatePolicyDetailsInput!): UpdatePolicyDetailsResponse
updateProposal(input: UpdateProposalInput!): Proposal!
updateTransaction(input: UpdateTransactionInput!): Transaction!
updateUser(input: UpdateUserInput!): User!
Expand Down Expand Up @@ -575,6 +558,11 @@ input ProposeMessageInput {
typedData: TypedData
}

input ProposePoliciesInput {
account: UAddress!
policies: [PolicyInput!]!
}

input ProposeTransactionInput {
account: UAddress!
dapp: DappMetadataInput
Expand Down Expand Up @@ -1053,24 +1041,13 @@ input UpdateApproverInput {
pushToken: String
}

input UpdatePoliciesInput {
input UpdatePolicyDetailsInput {
account: UAddress!
policies: [UpdatePolicyInput!]!
key: PolicyKey!
name: String!
}

input UpdatePolicyInput {
account: UAddress!
actions: [ActionInput!]
allowMessages: Boolean
approvers: [Address!]

"""seconds"""
delay: Float
key: PolicyKey
name: String
threshold: Float
transfers: TransfersConfigInput
}
union UpdatePolicyDetailsResponse = NameTaken | Policy

type UpdatePolicyOp {
_args: [JSON!]!
Expand All @@ -1081,8 +1058,6 @@ type UpdatePolicyOp {
threshold: Float!
}

union UpdatePolicyResponse = NameTaken | Policy

input UpdateProposalInput {
id: ID!
policy: PolicyKey
Expand Down
12 changes: 6 additions & 6 deletions api/src/core/database/database.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ export class DatabaseService implements OnModuleInit {
return reqCtx.db;
}

private async run<R>(p: Promise<R>, name = 'inline'): Promise<R> {
private async run<R>(f: () => Promise<R>, name = 'inline'): Promise<R> {
return Sentry.startSpan({ op: 'db.query', name }, async () => {
try {
return await p;
return await f();
} catch (e) {
if (e instanceof EdgeDBError && e['_query']) Sentry.setExtra('EdgeQL', e['_query']);
throw e;
Expand All @@ -63,7 +63,7 @@ export class DatabaseService implements OnModuleInit {
}

async query<Expr extends Expression>(expression: Expr): Promise<$infer<Expr>> {
return this.run(expression.run(this.client));
return this.run(() => expression.run(this.client));
}

async queryWith<
Expand All @@ -75,7 +75,7 @@ export class DatabaseService implements OnModuleInit {
params: paramsToParamArgs<Params>,
) {
const expression = e.params(paramsDef, getExpr as any);
return this.run(expression.run(this.client, params as any)) as Promise<$infer<Expr>>;
return this.run(() => expression.run(this.client, params as any)) as Promise<$infer<Expr>>;
}

async queryWith2<
Expand All @@ -87,14 +87,14 @@ export class DatabaseService implements OnModuleInit {
getExpr: (params: paramsToParamExprs<Params>) => Expr,
) {
const expression = e.params(paramsDef, getExpr as any);
return this.run(expression.run(this.client, params as any)) as Promise<$infer<Expr>>;
return this.run(() => expression.run(this.client, params as any)) as Promise<$infer<Expr>>;
}

async exec<F extends (client: Executor, args: any) => Promise<any>>(
f: F,
args: Parameters<F>[1],
): Promise<Awaited<ReturnType<F>>> {
return this.run(f(this.client, args), f.name);
return this.run(() => f(this.client, args), f.name);
}

async transaction<T>(action: (transaction: Transaction) => Promise<T>): Promise<T> {
Expand Down
2 changes: 1 addition & 1 deletion api/src/core/networks/networks.worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class NetworkWorker extends Worker<NetworkQueue> {
if (runningJobs.find((j) => j.data.chain === network.chain.key)) continue;

const chain = network.chain.key;
this.queue.add(chain, { chain }, { repeat: { every: 30_000 /* ms */ }, ...NON_RETRYING_JOB });
this.queue.add(chain, { chain }, { repeat: { every: 2_000 /* ms */ }, ...NON_RETRYING_JOB });
}
}
}
46 changes: 32 additions & 14 deletions api/src/feat/accounts/accounts.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ACCOUNT_IMPLEMENTATION,
DEPLOYER,
asUAddress,
PLACEHOLDER_ACCOUNT_ADDRESS,
} from 'lib';
import { ShapeFunc } from '~/core/database';
import {
Expand All @@ -30,6 +31,7 @@ import { AccountsCacheService } from '../auth/accounts.cache.service';
import { v4 as uuid } from 'uuid';
import { selectAccount2 } from './accounts.util';
import { AccountEvent } from './accounts.model';
import { PolicyInput } from '../policies/policies.input';

const accountTrigger = (account: UAddress) => `account.updated:${account}`;
const accountApproverTrigger = (approver: Address) => `account.updated:approver:${approver}`;
Expand Down Expand Up @@ -105,7 +107,7 @@ export class AccountsService {
throw new UserInputError('Duplicate policy keys');

const implementation = ACCOUNT_IMPLEMENTATION.address[chain];
const account = asUAddress(
const address = asUAddress(
getProxyAddress({
deployer: DEPLOYER.address[chain],
implementation,
Expand All @@ -119,35 +121,51 @@ export class AccountsService {
const id = uuid();
await this.accountsCache.addCachedAccount({
approver: getApprover(),
account: { id, address: account },
account: { id, address },
});

// Replace self address with account address
const selfRefPolicies = policies.map(
(p) =>
({
...p,
actions: p.actions?.map((a) => ({
...a,
functions: a.functions.map((f) => ({
...f,
contract:
f.contract === PLACEHOLDER_ACCOUNT_ADDRESS ? asAddress(address) : f.contract,
})),
})),
}) satisfies PolicyInput,
);

await this.db.transaction(async () => {
await this.db.query(
e.insert(e.Account, {
id,
address: account,
address,
name,
implementation,
salt,
}),
);

for (const policy of policyInputs) {
await this.policies.create({
account,
initState: true,
...policy,
});
}
await this.policies.propose(
{
account: address,
isInitialization: true,
},
...selfRefPolicies,
);
});

this.contracts.addAccountAsVerified(asAddress(account));
this.faucet.requestTokens(account);
this.event({ account, event: AccountEvent.created });
this.contracts.addAccountAsVerified(asAddress(address));
this.faucet.requestTokens(address);
this.event({ account: address, event: AccountEvent.created });
this.setAsPrimaryAccountIfNotConfigured(id);

return { id, address: account };
return { id, address: address };
}

async updateAccount({ account, name, photo }: UpdateAccountInput) {
Expand Down
29 changes: 29 additions & 0 deletions api/src/feat/policies/existing-policies.edgeql
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
with account := (select Account filter .address = <UAddress>$account),
keys := array_unpack(<array<uint16>>$policyKeys)
select Policy {
key,
approvers: { address },
threshold,
actions: {
label,
functions: {
contract,
selector,
abi,
},
allow,
description,
},
transfers: {
limits: {
token,
amount,
duration
},
defaultAllow,
budget
},
allowMessages,
delay,
} filter .account = account and .key in keys and
(.isDraft if exists .draft else .isLatest)
Loading

0 comments on commit 9c9bee2

Please sign in to comment.