-
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(undelegate): use Timestamp instead of Date #9646
Conversation
@@ -87,7 +88,9 @@ export const prepareLocalOrchestrationAccountKit = ( | |||
{ | |||
holder: HolderI, | |||
undelegateWatcher: M.interface('undelegateWatcher', { | |||
onFulfilled: M.call([M.splitRecord({ completionTime: M.string() })]) | |||
onFulfilled: M.call([ | |||
M.splitRecord({ completionTime: TimestampProtoShape }), |
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.
Using splitRecord
here to make this forward compatible (cosmos v0.50 adds amount: Coin
to the response: https://buf.build/cosmos/cosmos-sdk/docs/main:cosmos.staking.v1beta1#cosmos.staking.v1beta1.MsgUndelegateResponse)
Are there other places we might need to consider this approach? Should we be guarding watcher's more loosely?
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 guess the local-orch-account is less likely to get an unexpected upgrade to v0.50, more the cosmos-orch-account. We do not have something similar in those interface guards since the value is still a base64 byte string at that point.
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.
Good question tho. Thanks for raising and resolving.
608499d
to
f77dc70
Compare
Deploying agoric-sdk with Cloudflare Pages
|
ba3e74e
to
433ded2
Compare
const responseJson: JsonSafe<typeof response> = null as any; | ||
expectType<string>(responseJson.completionTime); | ||
// FIXME: should be a string. UNTIL: github.com/cosmology-tech/telescope/pull/632 | ||
expectType<bigint>(responseJson.completionTime.seconds); |
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.
FYI. didn't seem worth checking in a patch, but happy to make one
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.
Thanks for the clearly described separate commits.
Only minor issues. Approving assuming they'll be addressed before merge.
}); | ||
t.is(delegation, undefined, 'delegation returns void'); | ||
|
||
// TODO, fixme! |
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 was reviewing by commit so I drafted a comment asking when, then I saw the fix in a subsequent PR.
I support this style of queuing up work for other commits in the PR. Consider being more specific for the reader, e.g. FIXME in this PR
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 for the future
}, | ||
); | ||
|
||
const redelgation = await E(account).redelegate( |
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.
typo
...validatorAddr, | ||
address: 'cosmosvaloper2test', |
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.
our composite "address" object reads so weirdly. I hope we can come up with a better name.
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.
cc @mitdralla
@@ -87,7 +88,9 @@ export const prepareLocalOrchestrationAccountKit = ( | |||
{ | |||
holder: HolderI, | |||
undelegateWatcher: M.interface('undelegateWatcher', { | |||
onFulfilled: M.call([M.splitRecord({ completionTime: M.string() })]) | |||
onFulfilled: M.call([ | |||
M.splitRecord({ completionTime: TimestampProtoShape }), |
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.
Good question tho. Thanks for raising and resolving.
* for google/protobuf/timestamp.proto, not to be confused with TimestampShape | ||
* from `@agoric/time` |
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.
excellent comment
* @param {Date} date | ||
* @returns {bigint} | ||
*/ | ||
export const dateInSeconds = date => BigInt(Math.floor(date.getTime() / 1000)); |
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.
reduction in code affirms your idea to switch to Timestamp
/** | ||
* returns Timestamp record 5 seconds from unix epoch. | ||
*/ | ||
const getCompletionTime = (): Timestamp => { | ||
return { | ||
seconds: UNBOND_PERIOD_SECONDS, | ||
nanos: 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.
it's only five because of UNBOND_PERIOD_SECONDS
. if someone changes that they won't know to change this comment.
the 0+ is thoughtful, but I don't think the "since unix epoch" is relevant to the test
please simplify and make more explicit what it gets
/** | |
* returns Timestamp record 5 seconds from unix epoch. | |
*/ | |
const getCompletionTime = (): Timestamp => { | |
return { | |
seconds: UNBOND_PERIOD_SECONDS, | |
nanos: 0, | |
}; | |
}; | |
const getUnbondingTime = () => new Date(Number(UNBOND_PERIOD_SECONDS * MILLISECONDS_PER_SECOND)); |
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.
Simplified but kept the return type a Timestamp
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.
oh good. I made the suggestion on an earlier commit and when I pulled it to the PR level I forgot to adjust the return type
@@ -212,6 +212,13 @@ export type LiquidStakingMethods = { | |||
liquidStake: (amount: AmountArg) => Promise<void>; | |||
}; | |||
|
|||
export type LocalAccountMethods = { | |||
/** deposit payment from zoe to the account */ |
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.
/** deposit payment from zoe to the account */ | |
/** deposit payment (from zoe, for example) to the account */ |
Zoe isn't the only source of payments.
@@ -68,6 +68,8 @@ const sendItFn = async ( | |||
const { chainId } = info; | |||
assert(typeof chainId === 'string', 'bad chainId'); | |||
const { [kw]: pmtP } = await withdrawFromSeat(zcf, seat, give); | |||
// #9212 types for chain account helpers | |||
// @ts-expect-error LCA should have .deposit() method |
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.
👏
* deposit payment from zoe to the account. For remote accounts, | ||
* an IBC Transfer will be executed to transfer funds there. | ||
*/ | ||
deposit: (payment: Payment<'nat'>) => Promise<void>; |
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.
cc @dtribble - change to orchestration-api.ts
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.
cc @mitdralla too
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.
Similar story to: #9591 (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.
lgtm
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.
very nicely done!
@@ -92,7 +99,7 @@ const makeScenario = () => { | |||
|
|||
'/cosmos.staking.v1beta1.MsgBeginRedelegate': _m => { | |||
const response = MsgBeginRedelegateResponse.fromPartial({ | |||
completionTime: new Date('2025-12-17T03:24:00Z'), | |||
completionTime: dateToTimestamp(new Date('2025-12-17T03:24:00Z')), |
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.
here's hoping we manage to completely replace the mock stuff here with using ibc-mocks
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. It seems there's parity here with stake-ica.test.ts
minus the wallet offers.
Will +1 that we should be able to use a macro and test LocalOrchestrationAccount in the same flow. Currently there are two small blockers to that:
- LOA
delegate
andundelegate
should accept a ChainAddress obj instead of a string - LOA
undelegate
should accept an array of delegations
// TODO clean up date handling once we have real data | ||
dateInSeconds(new Date(completionTime)) + maxClockSkew, | ||
// ignore nanoseconds and just use seconds from Timestamp | ||
BigInt(completionTime.seconds) + maxClockSkew, |
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.
👏 good to see the TODOs getting to-done.
@@ -155,17 +159,23 @@ test('delegate, undelegate, redelegate, withdrawReward', async t => { | |||
}); | |||
t.is(delegation, undefined, 'delegation returns void'); | |||
|
|||
// TODO, fixme! |
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.
👏
t.is( | ||
await undelegateP, | ||
undefined, | ||
'undelegate returns void after completion_time', |
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.
you can test that it actually waited that long by racing with timer.wakeAt(expectedFullfillment - 1n)
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.
Updated to include, ty. Also realized I don't need to provide a brand to the zone manual timer.
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.
oops; some comments pending from another window
433ded2
to
c6ca8a8
Compare
- test cosmos-orchestration-account.js via stakeIca.contract.js using mocked messages
- updates typingsFormat.timestamp to 'timestamp' instead of 'date' for better SES compatability - this Timestamp is from google/protobuf/timestamp.proto and looks like { seconds: bigint; nanos: number }
- removes dateInSeconds, as cosmic-proto now returns { seconds: bigint; nanos: number } - nanoseconds are ignored for the wakeAt() calculation, as these seem immaterial - adds undelegate() tests for LOA and COA that advance timer service to verify behavior - updates LOA to return undefined instead of a TimestampRecord on .delegate()
c6ca8a8
to
3d4ab30
Compare
refs: #9042
Description
This PR primarily improves unit testing around the
.undelegate()
flow and was motivated by a failure (inability to decodecompletionTime
) discovered in E2E testing.Timestamp
(from google/protobuf/timestamp.proto) instead ofDate
for@agoric/cosmic-proto
codegen for better endo compatibilityundelegate()
to use Timestamp forwakeAt()
calculationTesting Considerations
This PR includes additional tests for cosmos-orchestration-account flows.
Upgrade Considerations
This is a breaking change for
@agoric/cosmic-proto
, but not for theagoric
namespace.