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

feat: redelegate, undelegate on StakingAccountKit #9331

Merged
merged 5 commits into from
May 14, 2024
Merged

Conversation

dckc
Copy link
Member

@dckc dckc commented May 7, 2024

closes #9069
closes #9070

Description

on StakingAccountHolder, add Redelegate, Undelegate on invitatationMakers and redelegate(), undelegate() on holder.

refactor to get the holder facet to be checked against the orch API:

  • factor StakingAccountActions out of BaseOrchestrationAccount

was DRAFT until:

Security Considerations

adds a TimerService capabilty to each staking account kit.

Scaling Considerations

E(timer).wakeAt() consumes resources in the timer vat for the ~21 day unbonding period.

Documentation Considerations

orch API change, already discussed with product:

  • chore: narrow return type for redelegate to Promise<void> (or: widen, depending on how you look at it)

Testing Considerations

unit test coverage is reasonable.

I'd like to do more end-to-end testing; should closing #9069 wait for that?

Upgrade Considerations

doesn't use vows. Do we have plans to do that later? Which issue?

@dckc dckc changed the title Dc dist helper feat: delegate, redelegate on StakingAccountKit May 7, 2024
Copy link

cloudflare-pages bot commented May 7, 2024

Deploying agoric-sdk with  Cloudflare Pages  Cloudflare Pages

Latest commit: 67211a0
Status: ✅  Deploy successful!
Preview URL: https://9d924dd5.agoric-sdk.pages.dev
Branch Preview URL: https://dc-dist-helper.agoric-sdk.pages.dev

View logs

Comment on lines 292 to 302
const response = tryDecodeResponse(
result,
MsgDelegateResponse.fromProtoMsg,
);
mustMatch(harden(response), harden({})); // TODO: ignore response??
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we're not returning anything, is decoding the response worthwhile?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think so. if it does start returning something this code can continue to ignore it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @turadg, but have wondered if it makes sense to make some of these (empty) response values constants for a quick sanity check - we know that the result string will always be Ei0KKy9jb3Ntb3Muc3Rha2luZy52MWJldGExLk1zZ0RlbGVnYXRlUmVzcG9uc2U= in the happy path.

Comment on lines 325 to 332
trace('MsgBeginRedelegateResponse', response);
// TODO? return completionTime?
Copy link
Member Author

@dckc dckc May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec says to return void. Do we really want to throw away completionTime?

product question

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a Cosmos staking kit, I think we can return the Cosmos type. The higher level APIs can be more abstract. They might want to return void or a TimeRecord.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh. based on discussion above, I just re-worked it to ignore the return value altogether.
I hope that's ok.

Comment on lines 411 to 436
/** check holder facet against StakingAccountActions interface. FIXME: unused */
const typeCheck = () => {
/** @import {Guarded, Methods} from '@endo/exo'; */
/** @type {any} */
const arg = null;
/** @satisfies { StakingAccountActions } */
const kit = makeStakingAccountKit(arg, arg, arg, arg, arg).holder;
};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@turadg do you have any better idea than to keep this and silence the unused warnings?

@@ -18,3 +20,9 @@ export const Proto3Shape = {
};

export const CoinShape = { value: M.bigint(), denom: M.string() };
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait... Coin.value is a bigint? I see strings in a lot of places.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the AnyJson version of Coin, bigints are cast to strings. It seems this can be removed as we are now returning ChainAmount. The interface guard for getBalance should return ChainAmountShape.

@dckc dckc force-pushed the dc-dist-helper branch 4 times, most recently from fbe2f1f to db56eca Compare May 10, 2024 21:14
@dckc dckc marked this pull request as ready for review May 10, 2024 21:31
@dckc dckc requested review from 0xpatrickdev and turadg May 10, 2024 21:31
@dckc dckc changed the title feat: delegate, redelegate on StakingAccountKit feat: redelegate, undelegate on StakingAccountKit May 10, 2024
@dckc
Copy link
Member Author

dckc commented May 10, 2024

#9069 says:

This API should make use of the faux notification capability to return a promise that resolves when the redelegate (sic) is complete.

Since undelegate returns a completionTime, I didn't need any polling, so I didn't need anything special such as #9067.

I presume "redelegate" should be "undelegate" there.

Copy link
Member

@turadg turadg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff. @0xpatrickdev and I made some of the same API changes in #9356. Let's consider how to align them.

packages/orchestration/src/types.d.ts Show resolved Hide resolved
storageNode,
icqConnection,
// @ts-expect-error only for undelegate, which we do not use
timer: harden({}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it be optional then?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems worthwhile to include ChainTimerService in start-stakeAtom.js? makeAccount in StakeAtom returns a StakingAccountKit, so it does seem to be used.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops... missed this one; tending to it now...

* @param {AmountArg} amount
* @returns {Coin}
*/
amountToCoin(amount) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good enough for now

* @param {CosmosValidatorAddress} dstValidator
* @param {AmountArg} amount
*/
Redelegate(srcValidator, dstValidator, amount) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since all these makers just map the methods from the holder, I wonder if we should have some method on the holder to create invitation makers given a zcf

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not clear on what you're suggesting.

Making another exoKit seems awkward.

Comment on lines 292 to 302
const response = tryDecodeResponse(
result,
MsgDelegateResponse.fromProtoMsg,
);
mustMatch(harden(response), harden({})); // TODO: ignore response??
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think so. if it does start returning something this code can continue to ignore it

Comment on lines 325 to 332
trace('MsgBeginRedelegateResponse', response);
// TODO? return completionTime?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a Cosmos staking kit, I think we can return the Cosmos type. The higher level APIs can be more abstract. They might want to return void or a TimeRecord.

Copy link
Member

@0xpatrickdev 0xpatrickdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, as @turadg mentioned we might want to land #9356 first


const result = await E(account).executeEncodedTx([
const result = await E(helper.owned()).executeEncodedTx([
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Comment on lines 292 to 302
const response = tryDecodeResponse(
result,
MsgDelegateResponse.fromProtoMsg,
);
mustMatch(harden(response), harden({})); // TODO: ignore response??
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @turadg, but have wondered if it makes sense to make some of these (empty) response values constants for a quick sanity check - we know that the result string will always be Ei0KKy9jb3Ntb3Muc3Rha2luZy52MWJldGExLk1zZ0RlbGVnYXRlUmVzcG9uc2U= in the happy path.

);
trace('undelegate response', response);
const { completionTime } = response;
const endTime = BigInt(completionTime.valueOf() / 1000);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is completionTime a Date object? Came here to see if there was any nuance in handling this in Jessie

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is completionTime a Date object?

yes. I suppose getTime() would be more clear than valueOf().

Came here to see if there was any nuance in handling this in Jessie

only in constructing them, which our code doesn't do.

storageNode,
icqConnection,
// @ts-expect-error only for undelegate, which we do not use
timer: harden({}),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems worthwhile to include ChainTimerService in start-stakeAtom.js? makeAccount in StakeAtom returns a StakingAccountKit, so it does seem to be used.

packages/orchestration/src/exos/stakingAccountKit.js Outdated Show resolved Hide resolved
@dckc dckc requested review from turadg and 0xpatrickdev May 13, 2024 22:30

const expect = (actual, expected, message) => {
if (actual !== expected) {
console.log(message, { actual, expected });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not throw an error here?

dckc added 2 commits May 13, 2024 17:57
 - stakingAccountKit:
   - undelegate waits for unbonding time
    - max clock skew: 10min
   - factor out helper.amountToCoin
   - uniform idiom for state, facets
   - sync types, guards with spec
   - disable unused-vars on code only for typechecking
   - avoid decoding discarded responses
 - staking-ops.test.js: rename from withdraw...
   - refine test config constant names
   - WithdrawReward test doesn't depend on Delegate
@dckc dckc added automerge:rebase Automatically rebase updates, then merge and removed automerge:rebase Automatically rebase updates, then merge labels May 13, 2024
@dckc dckc added the automerge:rebase Automatically rebase updates, then merge label May 13, 2024
@mergify mergify bot merged commit 9553675 into master May 14, 2024
71 checks passed
@mergify mergify bot deleted the dc-dist-helper branch May 14, 2024 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:rebase Automatically rebase updates, then merge
Projects
None yet
3 participants