Skip to content

Commit

Permalink
wip 14
Browse files Browse the repository at this point in the history
  • Loading branch information
egasimus committed Oct 28, 2023
1 parent 986dcb5 commit ce4038f
Show file tree
Hide file tree
Showing 13 changed files with 145 additions and 334 deletions.
109 changes: 3 additions & 106 deletions agent/agent-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ export class Coin implements ICoin {

/** Error kinds. */
class FadromaError extends BaseError {
/** Thrown when unsupported functionality is requested. */
static Unsupported: typeof FadromaError_Unsupported
/** Thrown when a required parameter is missing. */
static Missing: typeof FadromaError_Missing
/** Thrown when an invalid value or operation is at hand. */
Expand All @@ -108,15 +106,6 @@ class FadromaError extends BaseError {
})
}

class FadromaError_Unsupported extends FadromaError.define(
'Unsupported', (msg='unsupported feature') => msg as string
) {
/** When global Fetch API is not available, Fadroma must switch to node:fs API. */
static Fetch = this.define('Fetch', () => {
return 'global fetch is unavailable, use FSUploader instead of Uploader'
})
}

class FadromaError_Missing extends FadromaError.define(
'Missing', (msg='a required parameter was missing') => msg as string
) {
Expand Down Expand Up @@ -177,10 +166,9 @@ class FadromaError_Failed extends FadromaError.define(
}

export const Error = Object.assign(FadromaError, {
Unsupported: FadromaError_Unsupported,
Missing: FadromaError_Missing,
Invalid: FadromaError_Invalid,
Failed: FadromaError_Failed
Missing: FadromaError_Missing,
Invalid: FadromaError_Invalid,
Failed: FadromaError_Failed
})

class AgentConsole extends Console {
Expand All @@ -191,33 +179,6 @@ class AgentConsole extends Console {
emptyBatch () {
return this.warn('Tried to submit batch with no messages')
}
devnetIdOverride (a: any, b: any) {
return this.warn(`node.chainId "${a}" overrides chain.id "${b}"`)
}
devnetUrlOverride (a: any, b: any) {
return this.warn(`node.url "${a}" overrides chain.url "${b}"`)
}
devnetModeInvalid () {
return this.warn(`chain.devnet: only applicable in devnet chain mode`)
}
noAgent (name: string) {
return this.warn(`${name}: no agent; actions will fail until agent is set`)
}
noAddress (name: string) {
return this.warn(`${name}: no address; actions will fail until address is set`)
}
noCodeHash (name: string) {
return this.warn(`${name}: no codeHash; actions may be slow until code hash is set`)
}
fetchedCodeHash (address: string, realCodeHash: string) {
return this.warn(`code hash not provided for ${address}; fetched: ${realCodeHash}`)
}
codeHashMismatch (address: string, expected: string|undefined, fetched: string) {
return this.warn(`code hash mismatch for ${address}: expected ${expected}, fetched ${fetched}`)
}
confirmCodeHash (address: string, codeHash: string) {
return this.info(`Confirmed code hash of ${address}: ${codeHash}`)
}
waitingForBlock (height: number, elapsed?: number) {
return this.log(`Waiting for block > ${bold(String(height))}...`, elapsed ? `${elapsed}ms elapsed` : '')
}
Expand All @@ -231,70 +192,6 @@ class AgentConsole extends Console {
for (const msg of msgs??[]) this.info(' ', JSON.stringify(msg))
return this
}
foundDeployedContract (address: Address, name: Name) {
return this.sub(name).log('found at', bold(address))
}
//beforeDeploy (
//template: ContractInstance,
//label?: Label, codeId?: CodeId, codeHash?: CodeHash, crate?: string, revision?: string
//) {
//codeId ??= template?.codeId ? bold(String(template.codeId)) : colors.red('(no code id!)')
//codeHash ??= template?.codeHash ? bold(template.codeHash) : colors.red('(no code hash!)')
//label = label ? bold(label) : colors.red('(missing label!)')
//crate ??= template?.crate
//revision ??= template.revision ?? 'HEAD'
//let info = `${bold(label)} from code id ${bold(codeId)}`
//if (crate) info += ` (${bold(crate)} @ ${bold(revision)})`
//return this.log(`init: ${info}`)
//}
//deployFailed (e: Error, template: Partial<ContractInstance>, name: Label, msg: Message) {
//this.error(`deploy of ${bold(name)} failed:`)
//this.error(`${e?.message}`)
//this.deployFailedContract(template)
//return this.error(`init message:`, JSON.stringify(msg))
//}
//deployManyFailed (template: Partial<ContractInstance>, contracts: any[] = [], e: Error) {
//this.error(`Deploy of multiple contracts failed:`)
//this.error(bold(e?.message))
//this.deployFailedContract(template)
//for (const [name, init] of contracts) this.error(`${bold(name)}:`, JSON.stringify(init))
//return this
//}
//deployFailedContract (template?: Partial<ContractInstance>) {
//if (!template) return this.error(`No template was provided`)
//this.error(`Code hash:`, bold(template.codeHash||''))
//this.error(`Chain ID: `, bold(template.chainId ||''))
//return this.error(`Code ID: `, bold(template.codeId ||''))
//}
//afterDeploy (contract: Partial<ContractInstance>) {
//let { name, prefix, address, codeHash } = (contract || {}) as any
//name = name
//? bold(green(name))
//: bold(red('(no name)'))
//prefix = prefix
//? bold(green(prefix))
//: bold(red('(no deployment)'))
//address = address
//? bold(colors.green(address))
//: bold(red('(no address)'))
//this.info('addr:', address)
//this.info('hash:', contract?.codeHash?colors.green(contract.codeHash):colors.red('(n/a)'))
//this.info('added to', prefix)
//this.br()
//return this
//}
saveNoStore (name: string) {
return this.warn(`not saving: store not set`)
}
saveNoChain (name: string) {
return this.warn(`not saving: chain not set`)
}
notSavingMocknet (name: string) {
return this.warn(`not saving: mocknet is not stateful (yet)`)
}
saving (name: string, state: object) {
return this.log('saving')
}
deployment (deployment: Deployment, name = deployment?.name) {
if (!deployment) return this.info('(no deployment)')
const contracts = Object.fromEntries(deployment.entries())
Expand Down
79 changes: 21 additions & 58 deletions agent/agent-batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. **/
import { Error, Console, into } from './agent-base'
import type {
Class, Message, CodeId, Address, Name, Into, ICoin, Many, CodeHash
Class, Message, CodeId, Address, Name, Into, ICoin, Many, CodeHash,
} from './agent-base'
import type { Agent } from './agent-chain'
import { ContractInstance } from './agent-contract'
import {
ContractUpload,
ContractInstance,
ContractClient
} from './agent-contract'

/** A constructor for a Batch subclass. */
export interface BatchClass<B extends Batch> extends
Expand Down Expand Up @@ -51,7 +55,9 @@ export abstract class Batch implements BatchAgent {

get defaultDenom () { return this.agent.defaultDenom }

get getClient () { return this.agent.getClient.bind(this) }
getClient <C extends ContractClient> (...args: Parameters<Agent["getClient"]>): C {
return this.agent.getClient(...args) as C
}

/** Add a message to the batch. */
add (msg: Message) {
Expand Down Expand Up @@ -107,13 +113,9 @@ export abstract class Batch implements BatchAgent {
return this.msgs
}

/** Add an init message to the batch.
* @example
* await agent.instantiate(template.define({ label, initMsg })
* @returns
* the unmodified input. */
/** Add an init message to the batch. */
async instantiate (
contract: CodeId|Partial<ContractInstance>,
contract: CodeId|Partial<ContractUpload>,
options: {
label: Name,
initMsg: Into<Message>,
Expand All @@ -125,7 +127,7 @@ export abstract class Batch implements BatchAgent {
address: Address,
}> {
if (typeof contract === 'string') {
contract = new ContractInstance({ codeId: contract })
contract = new ContractUpload({ codeId: contract })
}
this.add({ init: {
codeId: contract.codeId,
Expand All @@ -144,47 +146,7 @@ export abstract class Batch implements BatchAgent {
initBy: this.address,
}) as ContractInstance & { address: Address }
}
/** Add multiple init messages to the batch.
* @example
* await agent.batch().wrap(async batch=>{
* await batch.instantiateMany(template.instances({
* One: { label, initMsg },
* Two: { label, initMsg },
* }))
* await agent.instantiateMany({
* One: template1.instance({ label, initMsg }),
* Two: template2.instance({ label, initMsg }),
* })
* })
* @returns
* the unmodified inputs. */
async instantiateMany <M extends Many<ContractInstance>> (
contracts: M,
options: {
initFee?: ICoin[]|'auto',
initSend?: ICoin[],
initMemo?: string,
} = {}
): Promise<M> {
if (!contracts) {
throw new Error('no contracts passed to instantiateMany')
}
const outputs: any = (contracts instanceof Array) ? [] : {}
await Promise.all(Object.entries(contracts).map(async ([key, contract]: [Name, ContractInstance])=>{
if (contract.address) {
outputs[key] = contract.address
} else {
outputs[key] = await this.instantiate(contract, {
label: contract.label!,
initMsg: contract.initMsg!,
initFee: contract.initFee || options.initFee,
initSend: contract.initSend || options.initSend,
initMemo: contract.initMemo || options.initMemo
})
}
}))
return outputs
}

/** Add an exec message to the batch. */
async execute (
contract: Address|{ address: Address, codeHash?: CodeHash },
Expand All @@ -210,6 +172,7 @@ export abstract class Batch implements BatchAgent {
})
return this
}

/** Queries are disallowed in the middle of a batch because
* even though the batch API is structured as multiple function calls,
* the batch is ultimately submitted as a single transaction and
Expand All @@ -220,21 +183,25 @@ export abstract class Batch implements BatchAgent {
): Promise<never> {
throw new Error.Invalid.Batching("query")
}

/** Uploads are disallowed in the middle of a batch because
* it's easy to go over the max request size, and
* difficult to know what that is in advance. */
async upload (data: unknown): Promise<never> {
throw new Error.Invalid.Batching("upload")
}

async doUpload (data: unknown): Promise<never> {
throw new Error.Invalid.Batching("upload")
}

/** Uploads are disallowed in the middle of a batch because
* it's easy to go over the max request size, and
* difficult to know what that is in advance. */
async uploadMany (uploadables: Many<unknown> = {}): Promise<never> {
throw new Error.Invalid.Batching("upload")
}

/** Disallowed in batch - do it beforehand or afterwards. */
get balance (): Promise<string> {
throw new Error.Invalid.Batching("query balance")
Expand All @@ -247,22 +214,18 @@ export abstract class Batch implements BatchAgent {
get nextBlock (): Promise<number> {
throw new Error.Invalid.Batching("wait for next block")
}
/** This doesnt change over time so it's allowed when building batches. */
/** This doesn't change over time so it's allowed when building batches. */
getCodeId (address: Address) {
return this.agent.getCodeId(address)
}
/** This doesnt change over time so it's allowed when building batches. */
/** This doesn't change over time so it's allowed when building batches. */
getLabel (address: Address) {
return this.agent.getLabel(address)
}
/** This doesnt change over time so it's allowed when building batches. */
/** This doesn't change over time so it's allowed when building batches. */
getHash (address: Address|number) {
return this.agent.getHash(address)
}
/** This doesnt change over time so it's allowed when building batches. */
checkHash (address: Address, codeHash?: CodeHash) {
return this.agent.checkHash(address, codeHash)
}
/** Disallowed in batch - do it beforehand or afterwards. */
async getBalance (denom: string): Promise<string> {
throw new Error.Invalid.Batching("query balance")
Expand Down
Loading

0 comments on commit ce4038f

Please sign in to comment.