-
Notifications
You must be signed in to change notification settings - Fork 229
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
Internal JSDoc for fastUSDC and state transition diagram #11061
base: master
Are you sure you want to change the base?
Conversation
Deploying agoric-sdk with
|
Latest commit: |
287ea01
|
Status: | ✅ Deploy successful! |
Preview URL: | https://c8b50fb2.agoric-sdk.pages.dev |
Branch Preview URL: | https://cth-fastusdc-doc.agoric-sdk.pages.dev |
82c6605
to
1265dea
Compare
1265dea
to
90db359
Compare
@0xpatrickdev, would you mind giving me an initial review? Once you've made a pass over it, I'll ask the rest of the team to also look. |
@@ -17,6 +17,12 @@ import { | |||
} from '../type-guards.js'; | |||
import { makeFeeTools } from '../utils/fees.js'; | |||
|
|||
/** | |||
* @file Advancer subscribes (handleTransactionEvent) to events published by the |
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.
@file
docs don't tend to show up when navigating code in an IDE, generating docs, etc. How about putting this on prepareAdvancer
?
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.
a 1-line /** @file main export: @see {prepareAdvancer} */
at the top could help when looking at the file itself.
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 think this @file
comment is good but file-level comments should be at the top of the file
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.
done
* Add a new transaction with OBSERVED status | ||
* Add a new transaction with OBSERVED status. | ||
* | ||
* This message isn't currently being sent. |
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.
really? it's not?
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.
Please convince me I'm wrong. I couldn't find any instances of it.
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 only see it in tests.
I wonder if this is left-over from a design change.
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.
Changed in,
Let's remove the function since it's not used.
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.
done
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.
looks useful
packages/fast-usdc/README.md
Outdated
Advancing --> AdvanceFailed | ||
Forwarding --> ForwardFailed | ||
``` | ||
[*] --> AdvanceSkipped : Risks identified |
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.
Please retain the Observed
state as it is part of the sequence written to vstorage:
agoric-sdk/packages/fast-usdc/src/exos/status-manager.js
Lines 145 to 151 in 90db359
const publishEvidence = (hash, evidence) => { | |
// Don't await, just writing to vstorage. | |
void publishTxnRecord( | |
hash, | |
harden({ evidence, status: TxStatus.Observed }), | |
); | |
}; |
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.
done
packages/fast-usdc/README.md
Outdated
[*] --> Advancing : No risks, can advance | ||
[*] --> Forwarding* : No risks, Mint deposited before advance | ||
|
||
state Advancer { |
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 works visually but if someone knows this syntax, composite states, they might thing that these are composite states.
It's all states of the Transaction and not a composite. The boxes indicate what exo can set transition to that state.
I'm not sure that's useful but if you want to keep it please clarify in a comment on this sytnax.
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 thought it was clarifying to separate advancer actions from settler actions, but I can see how calling them composites would be confusing.
I also tried to find a way to use different colors for actions in Advancer and Settler, but I could only see how to color states, and that didn't carry the right meaning.
packages/fast-usdc/README.md
Outdated
``` | ||
[*] --> AdvanceSkipped : Risks identified | ||
[*] --> Advancing : No risks, can advance | ||
[*] --> Forwarding* : No risks, Mint deposited before advance |
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 don't think this is accurate. If there is no observation there is no transaction to have a state
agoric-sdk/packages/fast-usdc/src/exos/settler.js
Lines 241 to 245 in 90db359
log('⚠️ tap: minted before observed', nfa, amount); | |
// XXX consider capturing in vstorage | |
// we would need a new key, as this does not have a txHash | |
this.state.mintedEarly.add(makeMintedEarlyKey(nfa, amount)); | |
} |
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.
finessed.
packages/fast-usdc/README.md
Outdated
} | ||
|
||
Forwarding* --> Forwarded : settler.forward() succeeds | ||
Advancing --> Advanced : advancer's transferHandler detects success |
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.
while you're bringing in more sophisticated diagram features, consider using choice for success conditions
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. that's hepful
packages/fast-usdc/README.md
Outdated
Forwarding* --> ForwardFailed : settler.forward() fails | ||
``` | ||
|
||
* There is no actual state for **Forwarding**. It is used here to represent the |
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.
maybe better expressed within the diagram as a note
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 turned Forwarding
into a choice rather than a state, so I don't need the note. What do you think of this version?
It also let me get rid of the transition on "Mint deposited before Advance".
@@ -17,6 +17,12 @@ import { | |||
} from '../type-guards.js'; | |||
import { makeFeeTools } from '../utils/fees.js'; | |||
|
|||
/** | |||
* @file Advancer subscribes (handleTransactionEvent) to events published by the |
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 think this @file
comment is good but file-level comments should be at the top of the file
/** @param {ZCFSeat} lp */ | ||
async handle(lp) { | ||
/** @param {ZCFSeat} lpSeat */ | ||
async handle(lpSeat) { |
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 lightly oppose having the type in the name. I think the existing names were clear
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.
mint
was very confusing to me. "mint" is a kind in ERTP (the shareMint
is used nearby), a verb, a generic noun, and several other things. I don't know how it distinguishes the zcfSeat that hold lpShares that will be transferred to the liquidity provider.
mintedShares might be okay, but it's a seat holding shares, not the shares themselves, and it's certainly not a "mint".
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 reasons against mint
but not to retain Seat
. The union of our points yields: lp
and sharePayout
.
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.
done
@@ -14,6 +14,13 @@ import { | |||
makeNatAmountShape, | |||
} from '../type-guards.js'; | |||
|
|||
/** | |||
* @file Settler is responsible for monitoring (receiveUpcall) deposits to the |
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.
ditto about file at top
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.
Significant improvement! The choice fields really clarify things. I never tried them before.
Approving contingent on fixing AcvancingChoice
and the Shares
suffix
/** @param {ZCFSeat} lp */ | ||
async handle(lp) { | ||
/** @param {ZCFSeat} lpSeat */ | ||
async handle(lpSeat) { |
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 reasons against mint
but not to retain Seat
. The union of our points yields: lp
and sharePayout
.
packages/fast-usdc/README.md
Outdated
Advancing --> AdvanceFailed | ||
Forwarding --> ForwardFailed | ||
``` | ||
AcvancingChoice --> AdvanceFailed : advancer's transferHandler detects failure |
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, breaking the image.
but it's not really a choice. Please use AdvancingSuccess
or something that describes the range of values.
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’m also not crazy about AdvancingChoice - it seems like a TxStatus
.
We are waiting for a cross-chain call to settle here - specifically Success Ack
, Error Ack
, Timeout
from the IBC protocol. Maybe:
Advancing --> Advanced : IBC Success Ack
Advancing --> AdvanceFailed : IBC Error Ack or Timeout
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 didn't understand @turadg's suggestion, so this iteration follows @0xpatrickdev's version.
it's not really a choice.
Please say more. AIUI, choice describes a situation where the next state depends on some external input, which I think is what the IBC provides.
Please use AdvancingSuccess or something that describes the range of values.
Do you mean to add a state called AdvancingSuccess
? There's no such state recorded. Is patrick's pair of transitions clear enough about the possibilities?
packages/fast-usdc/README.md
Outdated
Advancing --> AdvanceFailed | ||
Forwarding --> ForwardFailed | ||
``` | ||
AcvancingChoice --> AdvanceFailed : advancer's transferHandler detects failure |
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’m also not crazy about AdvancingChoice - it seems like a TxStatus
.
We are waiting for a cross-chain call to settle here - specifically Success Ack
, Error Ack
, Timeout
from the IBC protocol. Maybe:
Advancing --> Advanced : IBC Success Ack
Advancing --> AdvanceFailed : IBC Error Ack or Timeout
Forwarding --> ForwardFailed | ||
``` | ||
AcvancingChoice --> AdvanceFailed : advancer's transferHandler detects failure | ||
Forwarding --> ForwardFailed : settler.forward() 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.
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.
[possible duplicate, I thought I wrote this already.]
The old Forwarding
node didn't represent a recorded state, so I was looking for a way to hide it. it's now hidden behind an unlabelled choice node. The code mostly doesn't check the prior state before deciding on a new state, so three states can lead to these transitions.
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.
choice nodes render just as the diamond, not with their label
|
||
```mermaid | ||
stateDiagram-v2 | ||
state Forwarding <<choice>> | ||
state AdvancingChoice <<choice>> | ||
|
||
Observed --> AdvanceSkipped : Risks identified | ||
Observed --> Advancing : No risks, can advance | ||
Observed --> Forwarding : No risks, Mint deposited before advance |
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.
Observed --> Forwarding : No risks, Mint deposited before advance
We should expand this more because it's no longer accurate. An invariant is that the contract never Forward
s without seeing evidence. When Settler.receiveUpcall
fires and there are no matches in StatusManager
's pendingTxs
, or the found match is Advancing
, it goes into the mintedEarly
store. Each time Advancer.handleTransactionEvent
is invoked, it will call Settler.notifier.checkMintedEarly()
and early return if true. checkMintedEarly
will clear the item from mintedEarly
and initiate a .forward()
. Settler.notifier.notifyAdvancingResult
, which is called at the end of the Advancing
state transition, also checks mintedEarly
.
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 agree that all that happens, and it complicates our process, but if it complicates the state transitions, it's not obvious to me how it should be represented. AFAICT, the state transitions are unaffected by all of this.
Should we represent those possibilities more explicitly in the states?
Perhaps I could add a note on the choice node listing the conditions that the code pays attention to to decide whether and when to attempt to forward.
@@ -103,6 +105,10 @@ export const stateShape = harden({ | |||
}); | |||
|
|||
/** | |||
* Advancer subscribes (using handleTransactionEvent) to events published by the | |||
* transaction feed. When notified of an appropriate opportunity, it is |
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.
nb: this could be helpful for navigation:
* transaction feed. When notified of an appropriate opportunity, it is | |
* {@link TransactionFeedKit}. When notified of an appropriate opportunity, it is |
With this up top:
* @import {TransactionFeedKit} from './transaction-feed.js';
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.
|
||
### Complete state diagram (starting from Transaction Feed into Advancer) | ||
The Settler is responsible for monitoring (via `receiveUpcall`) deposits to the | ||
settlementAccount. It either `disburse`s funds to the Pool (if funds were |
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.
The Settler is responsible for monitoring (via
receiveUpcall
) deposits to the
settlementAccount.
Is it worth mentioning how receiveUpcall
works? The Settler also needs to register a handler for the settlementAccount: OrchestrationAccount
- that's what sets up the events:
E(settlementAccount).monitorTransfers(settler.tap); // "tap" is any durable exo with a `receiveUpcall` handler
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 don't think that goes in the state diagram, but I can put it in the class comment.
* Settler is responsible for monitoring (using receiveUpcall) deposits to the | ||
* settlementAccount. It either "disburses" funds to the Pool (if funds were | ||
* "advance"d to the payee), or "forwards" funds to the payee (if pool funds | ||
* were not advanced). |
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 think it's worth mentioning:
- it needs to register it's
tap
facet (receiveUpcall
) via thesettlementAccount
so it gets events - something about the
mintedEarly
flow - we don't.forward()
untilnotifier.checkMinted
is called by theAdvancer
.
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 mentioned the registration.
In Settler, self.forward()
is called in
receiveUpcall
inObserved
,AdvanceSkipped
, andAdvanceFailed
notifyAdvancingResult()
ifmintedEarly
and no success, orcheckMintedEarly()
ifmintedEarly
has the tx.
The first of these doesn't seem to match what the second bullet says. Would you rephrase?
@@ -300,6 +307,9 @@ export const prepareSettler = ( | |||
}, | |||
self: { | |||
/** | |||
* The intended payee received an advance from the pool. When the funds | |||
* are minted disburse them to the pool. |
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.
* are minted disburse them to the pool. | |
* are minted disburse them to the pool and fee seats. |
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.
that's right. Thanks.
observe(evidence) { | ||
initPendingTx(evidence, PendingTxStatus.Observed); | ||
}, | ||
|
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. I think we also need some cleanup in status-manager.test.ts
. Some tests can be removed, and others should be updated to use .advanceSkipped
.
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.
@@ -103,6 +105,10 @@ export const stateShape = harden({ | |||
}); | |||
|
|||
/** | |||
* Advancer subscribes (using handleTransactionEvent) to events published by the | |||
* transaction feed. When notified of an appropriate opportunity, it is | |||
* responsible for advancing funds to fastUSDC payees. |
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.
fastUSDC payees
Might be worth working in EUD.
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.
done
@Chris-Hibbert P.S. i worked on these at one point, but they were never completed / checked in. It includes:
And this was an attempt to get everything into one diagram, but it didn't end being very readable. It was created with LLM-assistance and might contain mistakes, but i think the bulk of it is accurate: |
{ evidence: cctpTxEvidence, status: 'OBSERVED' }, | ||
{ evidence: cctpTxEvidence, status: undefined }, |
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'm surprised to see OBSERVED
replaced by undefined
.
It makes sense to see the .observed()
method go away, but not the state.
Description
Add some prose description about how
Advancer
andSettler
work together, and improve the state transition diagram.Security Considerations
None
Scaling Considerations
None
Documentation Considerations
Internal documentation only. No implications for user docs.
Testing Considerations
None
Upgrade Considerations
None