Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reduces metadata size #75

Merged
merged 4 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 9 additions & 16 deletions contracts/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,18 @@ export type AclOptionsAllowList = {

export type AclOptionsXchain = {
xchain: {
chainId: number;
blockHash: string;
address: string;
slot: number;
c: number; // chain Id
b: Uint8Array; // block hash
a: Uint8Array; // account / contract
s: number; // slot
};
};

export type AclOptions = {
address: string;
options: AclOptionsToken | AclOptionsAllowAll | AclOptionsAllowList | AclOptionsXchain;
};

export type Poll = {
creator: string;
name: string;
description: string;
choices: string[];
acl: AclOptions;
};
export type AclOptions =
| AclOptionsToken
| AclOptionsAllowAll
| AclOptionsAllowList
| AclOptionsXchain;

export type StorageProof = {
key: string;
Expand Down
4 changes: 2 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"@oasisprotocol/sapphire-ethers-v6": "^6.0.1",
"@oasisprotocol/sapphire-paratime": "^2.0.1",
"@phosphor-icons/core": "^2.0.8",
"cbor-web": "^9.0.2",
"cborg": "1.10.2",
"ethers": "6.10.0",
"framer-motion": "^11.5.4",
"lru-cache": "10.1.0",
Expand Down Expand Up @@ -56,7 +56,7 @@
"glob": "^10.3.10",
"prettier": "^3.3.3",
"rollup-plugin-visualizer": "^5.12.0",
"typescript": "^5.2.2",
"typescript": "^5.6.2",
"vite": "^5.1.4",
"vite-plugin-singlefile": "^1.0.0",
"vite-plugin-svgr": "^4.2.0"
Expand Down
11 changes: 4 additions & 7 deletions frontend/src/components/ACLs/allowAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { denyWithReason, useOneOfField } from '../InputFields'

export const allowAll = defineACL({
value: 'acl_allowAll',
address: VITE_CONTRACT_ACL_ALLOWALL,
label: 'Everybody',
costEstimation: 0.1,
useConfiguration: active => {
Expand All @@ -25,17 +26,13 @@ export const allowAll = defineACL({
values: undefined,
}
},

getAclOptions: () => ({
data: '0x', // Empty bytes is passed
options: {
address: VITE_CONTRACT_ACL_ALLOWALL,
options: {
allowAll: true,
},
},
options: { allowAll: true },
flags: 0n,
}),
isThisMine: options => 'allowAll' in options.options,
isThisMine: options => 'allowAll' in options,

checkPermission: async (pollACL, daoAddress, proposalId, userAddress) => {
const proof = new Uint8Array()
Expand Down
10 changes: 3 additions & 7 deletions frontend/src/components/ACLs/allowList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const splitAddresses = (addressSoup: string): string[] =>

export const allowList = defineACL({
value: 'acl_allowList',
address: VITE_CONTRACT_ACL_VOTERALLOWLIST,
label: 'Address Whitelist',
costEstimation: 0.1,
description: 'You can specify a list of addresses that are allowed to vote.',
Expand Down Expand Up @@ -72,17 +73,12 @@ export const allowList = defineACL({
if (!props.addresses) throw new Error('Internal errors: parameter mismatch, addresses missing.')
return {
data: abiEncode(['address[]'], [props.addresses]),
options: {
address: VITE_CONTRACT_ACL_VOTERALLOWLIST,
options: {
allowList: true,
},
},
options: { allowList: true },
flags: 0n,
}
},

isThisMine: options => 'allowList' in options.options,
isThisMine: options => 'allowList' in options,

checkPermission: async (pollACL, daoAddress, proposalId, userAddress) => {
const proof = new Uint8Array()
Expand Down
17 changes: 10 additions & 7 deletions frontend/src/components/ACLs/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export type StatusUpdater = (status: string | undefined) => void
/**
* This data structure describes an ACL
*/
export type ACL<Name, ConfigInputValues, Options extends AclOptions, Extra> = Choice<Name> & {
export type ACL<Name, ConfigInputValues, Options extends AclOptions> = Choice<Name> & {
/**
* Estimated cost per vote
*
Expand All @@ -20,6 +20,11 @@ export type ACL<Name, ConfigInputValues, Options extends AclOptions, Extra> = Ch
*/
useConfiguration: (selected: boolean) => { fields: FieldConfiguration; values: ConfigInputValues }

/**
* The address of the ACL contract to use
*/
address: string

/**
* Compose the ACL options when creating a poll
*/
Expand Down Expand Up @@ -51,13 +56,11 @@ export type ACL<Name, ConfigInputValues, Options extends AclOptions, Extra> = Ch
proposalId: string,
userAddress: string,
options: Options,
) => Promise<
{ canVote: DecisionWithReason; explanation?: ReactNode; proof: BytesLike; error?: string } & Extra
>
) => Promise<{ canVote: DecisionWithReason; explanation?: ReactNode; proof: BytesLike; error?: string }>
}

export function defineACL<Name, ConfigInputValues, Options extends AclOptions, Extra>(
acl: ACL<Name, ConfigInputValues, Options, Extra>,
): ACL<Name, ConfigInputValues, Options, Extra> {
export function defineACL<Name, ConfigInputValues, Options extends AclOptions>(
acl: ACL<Name, ConfigInputValues, Options>,
): ACL<Name, ConfigInputValues, Options> {
return acl
}
10 changes: 4 additions & 6 deletions frontend/src/components/ACLs/tokenHolder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { FLAG_WEIGHT_LOG10, FLAG_WEIGHT_ONE } from '../../types'

export const tokenHolder = defineACL({
value: 'acl_tokenHolder',
address: VITE_CONTRACT_ACL_TOKENHOLDER,
costEstimation: 0.2,
label: `Active Token or NFT balance on ${configuredNetworkName}`,
description:
Expand Down Expand Up @@ -115,18 +116,15 @@ export const tokenHolder = defineACL({
if (!props.tokenAddress) throw new Error('Internal errors: parameter mismatch, addresses missing.')
return {
data: abiEncode(['address'], [props.tokenAddress]),
options: {
address: VITE_CONTRACT_ACL_TOKENHOLDER,
options: { token: props.tokenAddress },
},
options: { token: props.tokenAddress },
flags: props.flags,
}
},

isThisMine: options => 'token' in options.options,
isThisMine: options => 'token' in options,

checkPermission: async (pollACL, daoAddress, proposalId, userAddress, options) => {
const tokenAddress = options.options.token
const tokenAddress = options.token
const tokenInfo = await getLocalContractDetails(tokenAddress)
const url = configuredExplorerUrl
? StringUtils.getTokenUrl(configuredExplorerUrl, tokenAddress)
Expand Down
33 changes: 16 additions & 17 deletions frontend/src/components/ACLs/xchain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ import {
import type { TokenInfo, NFTInfo } from '@oasisprotocol/blockvote-contracts'
import { designDecisions, VITE_CONTRACT_ACL_STORAGEPROOF } from '../../constants/config'
import classes from './index.module.css'
import { BytesLike, getUint } from 'ethers'
import { BytesLike, getBytes, getUint, hexlify } from 'ethers'
import { ReactNode, useMemo } from 'react'
import { StringUtils } from '../../utils/string.utils'
import { FLAG_WEIGHT_LOG10, FLAG_WEIGHT_ONE } from '../../types'

export const xchain = defineACL({
value: 'acl_xchain',
address: VITE_CONTRACT_ACL_STORAGEPROOF,
label: 'Token Snapshot voting',
costEstimation: 0.2,
description: 'take a snapshot of token or NFT balances from another chain',
Expand Down Expand Up @@ -289,6 +290,7 @@ export const xchain = defineACL({
},
}
},

getAclOptions: async ({ chainId, contractAddress, slotNumber, blockHash, flags }, updateStatus) => {
const showStatus = updateStatus ?? ((message?: string | undefined) => console.log(message))
const rpc = xchainRPC(chainId)
Expand All @@ -301,10 +303,10 @@ export const xchain = defineACL({

const options: AclOptionsXchain = {
xchain: {
chainId,
blockHash,
address: contractAddress,
slot: parseInt(slotNumber),
c: chainId,
b: getBytes(blockHash),
a: getBytes(contractAddress),
s: parseInt(slotNumber),
},
}

Expand All @@ -313,26 +315,25 @@ export const xchain = defineACL({
['tuple(tuple(bytes32,address,uint256),bytes,bytes)'],
[[[blockHash, contractAddress, slotNumber], headerRlpBytes, rlpAccountProof]],
),
options: {
address: VITE_CONTRACT_ACL_STORAGEPROOF,
options,
},
options,
flags,
}
},

isThisMine: options => 'xchain' in options.options,
isThisMine: options => 'xchain' in options,

checkPermission: async (pollACL, daoAddress, proposalId, userAddress, options) => {
const xChainOptions = options.options
const { xchain } = options
const chainId = xchain.c
const blockHash = hexlify(xchain.b)
const tokenAddress = hexlify(xchain.a)
const slot = xchain.s

let explanation: ReactNode = ''
let error = ''
let proof: BytesLike = ''
let tokenInfo: TokenInfo | NFTInfo | undefined
let canVote: DecisionWithReason = true
const {
xchain: { chainId, blockHash, address: tokenAddress, slot },
} = xChainOptions
const provider = xchainRPC(chainId)
const chainDefinition = getChainDefinition(chainId)

Expand All @@ -342,8 +343,6 @@ export const xchain = defineACL({
explanation: 'This poll is invalid, since it references and unknown chain.',
error,
proof,
tokenInfo,
xChainOptions,
}
}

Expand Down Expand Up @@ -407,6 +406,6 @@ export const xchain = defineACL({
console.error('proof:', proof)
canVote = denyWithReason(`there was a technical problem verifying your permissions`)
}
return { canVote, explanation, error, proof, tokenInfo, xChainOptions }
return { canVote, explanation, error, proof }
},
} as const)
4 changes: 0 additions & 4 deletions frontend/src/hooks/usePollPermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ const blackPermissions: PollPermissions = {
proof: '',
explanation: undefined,
canVote: denyWithReason(NOT_CHECKED),
tokenInfo: undefined,
xChainOptions: undefined,
canManage: false,
error: '',
}
Expand Down Expand Up @@ -49,8 +47,6 @@ export const usePollPermissions = (poll: ExtendedPoll | undefined, onDashboard:
proof: '',
explanation: '',
canVote: true,
tokenInfo: undefined,
xChainOptions: undefined,
canManage: false,
error: '',
})
Expand Down
1 change: 1 addition & 0 deletions frontend/src/pages/CreatePollPage/useCreatePollForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ export const useCreatePollForm = () => {
description: description.value,
answers: answers.value,
isHidden: hidden.value,
aclAddress: currentAcl.address,
aclData,
aclOptions,
pollFlags,
Expand Down
25 changes: 23 additions & 2 deletions frontend/src/types/poll.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { PollManager, Poll } from '@oasisprotocol/blockvote-contracts'
import type { PollManager, AclOptions } from '@oasisprotocol/blockvote-contracts'
export type {
Poll,
AclOptions,
PollManager,
GaslessVoting,
Expand All @@ -16,6 +15,28 @@ export type Proposal = {
params: PollManager.ProposalParamsStructOutput
}

// NOTE: this is stored on-chain, so it's essential to keep the encoded size
// as small as possible! Such as using Uint8Array instead of hex encoded
// addresses.
export type StoredPoll = {
c: Uint8Array // creator address
n: string // name
d: string // description
o: string[] // choices / options
a: AclOptions // ACL options
}

/**
* This is the decoded version of StoredPoll. More verbose and intuitive to use.
*/
export type Poll = {
creator: string
name: string
description: string
choices: string[]
acl: AclOptions
}

export type ExtendedPoll = {
id: string
proposal: Proposal
Expand Down
Loading