Skip to content

Commit

Permalink
Merge pull request #75 from oasisprotocol/CedarMist/reduce-metadata-size
Browse files Browse the repository at this point in the history
reduces metadata size
  • Loading branch information
csillag authored Oct 4, 2024
2 parents e99e92d + 9e569c6 commit 25596c5
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 152 deletions.
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

0 comments on commit 25596c5

Please sign in to comment.