-
Notifications
You must be signed in to change notification settings - Fork 208
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
feat(cosmosStakingAccount): publish chain address to vstorage #9482
Conversation
|
||
// FIXME mock remoteAddress in ibc bridge | ||
const storagePath = | ||
'mockChainStorageRoot.stakeAtom.accounts.UNPARSABLE_CHAIN_ADDRESS'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might consider throwing if the address is unparsable, or falling back to a different identifier like Port Address + ControllerConnectionID: icacontroller-1-connection-0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure the solution but we definitely shouldn't write UNPARSABLE_CHAIN_ADDRESS
to vstorage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a FIXME to chainAccount.js
with a link to #9066
@@ -158,6 +158,7 @@ export const prepareCosmosOrchestrationAccountKit = ( | |||
// must be the fully synchronous maker because the kit is held in durable state | |||
// @ts-expect-error XXX Patterns | |||
const topicKit = makeRecorderKit(storageNode, PUBLIC_TOPICS.account[1]); | |||
void E(topicKit.recorder).write(harden({ sequence: 0n })); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've selected sequence
since it seems we need to create an initial write. I considered the ChainAddress
object but that didn't seem to make sense when we're keying by ChainAddress['address']
.
If folks think storing sequence
makes sense, we can increment this after each successful executeEncodedTx
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems useful but it does have a cost. Is it just helpful for diagnostics or is there a product use case to publish each sequence?
If we do include it, consider a more transparent property name like executedSequence
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed for now in favor of an empty string ''
. Will wait for use cases.
Deploying agoric-sdk with Cloudflare Pages
|
ca6d46a
to
b313ac8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is some experimentation within a contract in order to get experience with what should be pushed down into the platform.
Very well!
The approach delegates vstorage publishing responsibilities to guest contracts.
I agree that's appropriate at this point and expect we'll develop the abstractions for cleaner start functions after we've got most of the pieces working end to end.
I left some suggestions but no blockers. I did have some questions so I'm holding Approve for those.
const { accountsStorageNode } = await provideAll(baggage, { | ||
accountsStorageNode: () => E(storageNode).makeChildNode('accounts'), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I take it you say accountNode
below but StorageNode
here because it's going in baggage. Consider noting that rationale since this is an example contract.
const { accountsStorageNode } = await provideAll(baggage, { | ||
accountsStorageNode: () => E(storageNode).makeChildNode('accounts'), | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the thought behind the parent of orchestration being accounts
? It will need to put other info in there, won't it?
I won't block on this since the code is still experimental and we have #9066 ahead of us. But consider makeChildNode('orchestration')
since that's the scope it's being handed to.
const { accountsStorageNode } = await provideAll(baggage, { | |
accountsStorageNode: () => E(storageNode).makeChildNode('accounts'), | |
}); | |
const { orchestrationStorageNode } = await provideAll(baggage, { | |
orchestrationStorageNode: () => E(storageNode).makeChildNode('orchestration'), | |
}); |
We should try to be consistent across contracts so that we can have a helper that does all this setup in one call from start
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We make separate nodes for stakeAtom
and stakeOsmo
in the start-*.js
scripts, and each has an accounts
child node. Presumably other info or child nodes can be written to the stakeAtom
and stakeOsmo
paths.
This seems to be in line with "delegates vstorage publishing responsibilities to guest contracts" in the PR description.
Agree it may make sense to globally publish something for all accounts, unless explicitly opted out, and that's where I think an orchestration
node makes sense.
@@ -158,6 +158,7 @@ export const prepareCosmosOrchestrationAccountKit = ( | |||
// must be the fully synchronous maker because the kit is held in durable state | |||
// @ts-expect-error XXX Patterns | |||
const topicKit = makeRecorderKit(storageNode, PUBLIC_TOPICS.account[1]); | |||
void E(topicKit.recorder).write(harden({ sequence: 0n })); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems useful but it does have a cost. Is it just helpful for diagnostics or is there a product use case to publish each sequence?
If we do include it, consider a more transparent property name like executedSequence
@@ -363,6 +366,7 @@ export const prepareCosmosOrchestrationAccountKit = ( | |||
*/ | |||
async getBalance(denom) { | |||
const { chainAddress, icqConnection } = this.state; | |||
if (!icqConnection) throw Error('Queries not enabled.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This reads like something the developer could change.
if (!icqConnection) throw Error('Queries not enabled.'); | |
if (!icqConnection) throw Fail'Queries not enabled for chain ${chainAddress.chainId}`.`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, updated
const storageNode = await makeStorageNodeChild(chainStorage, VSTORAGE_PATH); | ||
const marshaller = await E(board).getPublishingMarshaller(); | ||
|
||
// TODO add osmo to bank |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when, why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Came to realize the contract is not using the issuerKeywordRecord (depositing will be done via an LCA). Removed from here and start-stakeAtom.js
// t.regex(address.address, /agoric1/); | ||
t.like(address, { chainId: 'cosmoshub-4', addressEncoding: 'bech32' }); | ||
const chainAddress = await E(account).getAddress(); | ||
// t.regex(address.address, /cosmos1/); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why disable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't seem to be a meaningful test, since the value is currently UNPARSABLE_CHAIN_ADDRESS
. Added a comment with FIXME mock remoteAddress in ibc bridge
to here as well.
t.log('inv', inv); | ||
|
||
const seat = await E(zoe).offer(inv); | ||
t.log('seat', seat); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logging values is useful when diagnosing a failure but noise when the tests are passing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Acknowledged and removed. My interpretation of @dckc's stance on this topic leads me to be believe there are differing views, so trying to strike a balance.
|
||
// FIXME mock remoteAddress in ibc bridge | ||
const storagePath = | ||
'mockChainStorageRoot.stakeAtom.accounts.UNPARSABLE_CHAIN_ADDRESS'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure the solution but we definitely shouldn't write UNPARSABLE_CHAIN_ADDRESS
to vstorage
// const { rootNode } = makeFakeStorageKit('mockChainStorageRoot'); | ||
|
||
const storageNode = Far('StorageNode', {}) as unknown as StorageNode; | ||
const { rootNode } = makeFakeStorageKit('mockChainStorageRoot', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider a unique value for easier string search
const { rootNode } = makeFakeStorageKit('mockChainStorageRoot', { | |
const { rootNode } = makeFakeStorageKit('stakingOpsTest', { |
const { makeRecorderKit, storageNode, zcf, icqConnection, zone } = s; | ||
const make = prepareCosmosOrchestrationAccountKit(zone, makeRecorderKit, zcf); | ||
|
||
// Higher fidelity tests below use invitationMakers. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
helpful comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not actually the case 😅 . The main motivation for adding the test here was the TODO: when we write to chainStorage, test it.
comment on L187.
I think this functionality is sufficiently tested elsewhere. There's a bit of overlap between staking-ops.test.ts
and stake-atom.test.ts
we might want to reduce at some point. My preference is to favor the former since it relies on fewer hand-rolled/localized mocks.
b313ac8
to
bec424d
Compare
@@ -160,6 +160,8 @@ export const prepareChainAccountKit = zone => | |||
this.state.remoteAddress = remoteAddr; | |||
this.state.localAddress = localAddr; | |||
this.state.chainAddress = harden({ | |||
// FIXME need a fallback value like icacontroller-1-connection-1 if this fails |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// FIXME need a fallback value like icacontroller-1-connection-1 if this fails | |
// FIXME need a fallback value like icacontroller-1-connection-1 if this fails | |
// Or, we should throw since a consumer can't do much w/o an address. |
4818f50
to
30bcdfa
Compare
@@ -151,7 +151,9 @@ export interface StakingAccountActions { | |||
* The unbonding time is padded by 10 minutes to account for clock skew. | |||
* @param delegations - the delegation to undelegate | |||
*/ | |||
undelegate: (delegations: Delegation[]) => Promise<void>; | |||
undelegate: ( | |||
delegations: Omit<Delegation, 'delegatorAddress'>[], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
before release we should name these different types and define them additively (instead of subtracting)
but I think this is appropriate for now before we we've nailed down all the cases
30bcdfa
to
f56928d
Compare
- given the ChainInfo type is inferred from KnownChains, ensure the icqEnabled key is present on all cosmos chains to facilitate TS types
- a better approach seems to be refactoring start-stakeAtom.js to start-stakeIca.js with parameters. buildProposal doesn't seem to accept options so punted for now - TODO: register OSMO in bank
f56928d
to
11aea65
Compare
refs: #9042
refs: #9193
refs: #9066
Description
Motivation: wallet clients need a way to view their address so they can send funds to it
Updates
stakeAtom.contract.js
to create a vstorage entry for newly created accounts, keyed byChainAccount['address']
(e.g.cosmos1testing1234
)UNPARSABLE_ADDRESS
in parseAddress we should throw, or use a fallback valueWrites an empty string to provided storageNode in
exos/cosmosOrchestrationAccount.js
Drive-by fixes:
AmountArg
consistently in/exos/cosmosOrchestrationAccount.js
delegatorAddress
fromundelegate(Delegations[])
interface and implementationSecurity Considerations
Scaling Considerations
This is some experimentation within a contract in order to get experience with what should be pushed down into the platform.
The approach delegates vstorage publishing responsibilities to guest contracts. We might consider posting information for all accounts to a shared global namespace.
Documentation Considerations
Testing Considerations
Tests, including ones for
swapExample.contract.js
andfacade.js
, were updated to accommodate these changes. Mocking facilities for.getAddress()
are light - including in boostrap tests - so usingChainAddress['address']
might lead to unexpected behavior (accounts overwriting each other in storage) in a testing environment.Upgrade Considerations