-
Notifications
You must be signed in to change notification settings - Fork 212
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
refactor!: new reallocate API to assist with reviewing conservation of rights #3184
Conversation
3dbb551
to
fce73b9
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.
Review so far. Not finished yet.
I am very encouraged by the overall line shrinkage of this PR!
packages/treasury/src/vault.js
Outdated
if (proposal.want.Collateral) { | ||
vaultSeat.decrementBy( | ||
seat.incrementBy({ Collateral: proposal.want.Collateral }), | ||
); | ||
} else if (proposal.give.Collateral) { |
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.
Is it possible that a proposal has both a want.Collateral
and a give.Collateral
?
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 is possible that a proposal has both, and from I can tell, the code prior to this PR does not prevent it or account for it.
6bd2a98
to
cc83838
Compare
@erights, this is now ready for review! |
@Chris-Hibbert, could you review the changes to |
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 would be better for
transferReward()
to returnfeeSeat
, so there is a singlereallocate()
call.
The refactoring in swap.js
looks clean to me. Thanks!
- I would drop the new TODOs in
swap.js
, but I won't insist on it if my reasoning isn't persuasive.
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
All suggested changes are about error messages, comments, and one renaming.
* @returns {void} | ||
*/ | ||
const commitStagedAllocation = zcfSeat => { | ||
assertActive(zcfSeat); |
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 assert
happens after the commit point. If it fails it throws. If it throws, it might throw after some allocations have been committed. This is an excellent example of an assert that should immediately shut down at lease the contract. We already have a zcf.assert
for this purpose. However, this is not the assert severity you want for normal uses of assertActive
, so you'd end up with an annoying duplication of code.
Any check failure that might fail must happen before the commit point. If the failure here is already obviously impossible, or once it is, then a comment here is fine. Impossible cases can become possible under maintenance mistakes. If the impossible happens and zcfSeat
is not active then you're guaranteed a low level failure on line 61 below. When I put in atomic actions, I will need to ensure that any such "cannot happen" throws cause vat termination anyway.
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 point. I moved this check earlier and removed it from this function, as I don't think it was being adequately checked before.
const commitStagedAllocation = zcfSeat => { | ||
assertActive(zcfSeat); | ||
activeZCFSeats.set(zcfSeat, zcfSeat.getStagedAllocation()); | ||
zcfSeatToStagedAllocations.delete(zcfSeat); |
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 delete
on line 62 seems exactly the same as the set
on line 61. It should be impossible to get here if zcfSeat
is not in zcfSeatToStagedAllocations
. If that is not already obviously impossible, it must be made obviously impossible. If it happens anyway we reliable get a low level failure from the delete
, which throws within the atomic action. Once I use the atomic action API to ensure that such failures cause immediate vat failure, we're safe even against these specific cannot-happen conditions.
When I will ask you to review the PR that protects such atomic actions, please keep these "impossible" cases in mind.
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 sounds good. I'll add a comment about this.
import { E } from '@agoric/eventual-send'; | ||
import { AmountMath } from '@agoric/ertp'; | ||
import { Far } from '@agoric/marshal'; | ||
|
||
import { isOfferSafe } from './offerSafety'; | ||
import { assertRightsConserved } from './rightsConservation'; | ||
import { addToAllocation, subtractFromAllocation } from './allocationMath'; | ||
|
||
/** @type {CreateSeatManager} */ | ||
export const createSeatManager = (zoeInstanceAdmin, getAssetKindByBrand) => { |
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 is no type SeatManager
or SeatKit
. But from the comment on CreateSeatManager
I would guess that the record returned at the bottom is the SeatManager. If so, then per our previous discussion, I do not understand why this is createSeatManager
rather than makeSeatManager
.
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 unchanged in this PR, so I won't address it here, but I think this is fine, since seatManager is an abstract concept only used internally. Since there is no seatManager
reified as an object, I think create
is fine as well.
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.
One missed duplicated edit, one question. Looking good.
// TODO: this should be transferred directly from the user such | ||
// that there's no way to accidentally take more than expected | ||
// from 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.
Sorry, I didn't mark this copy of the TODO. I think it should also be dropped.
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.
Ah, I left it in purposefully. In this case, it is central to secondary, so we can take the protocolFee directly from the user's give
7c1d537
to
5165993
Compare
…ng the `zcfSeat` and `reallocate` API
5165993
to
a60e41b
Compare
This PR makes a breaking change to
ZCFSeats
,zoe.reallocate
, and thetrade
,swap
, andswapExact
helpers.SeatStagings
andzcfSeat.stage
no longer exist. Instead, amountKeywordRecords can be added or subtracted to a seat's allocation by calling methods directly on thezcfSeat
:{(amountKeywordRecord: AmountKeywordRecord) => AmountKeywordRecord} incrementBy
- the amountKeywordRecord to be added to the seat's staged allocation{(amountKeywordRecord: AmountKeywordRecord) => AmountKeywordRecord} decrementBy
- the amountKeywordRecord to be subtracted from the seat's staged allocation{() => void} clear
- delete the staged allocation, if any{() => Allocation} getStagedAllocation
- get the stagedAllocation, the allocation that will be committed if the seat is reallocated over, if offer safety holds and rights are conserved{() => boolean} hasStagedAllocation
- whether there is a staged allocation, i.e. whetherincrementBy
ordecrementBy
has been called andclear
has not.Once a seat has a staged allocation, it can be reallocated over by calling
zcf.reallocate(zcfSeat1, zcfSeat2, ....)
. This commits the staged allocation, such it is now the current allocation for that seat.The
trade
helper no longer exists, and theswap
andswapExact
helpers no longer accept errorMsg arguments.Example usage:
Closes #3215
#dapp-otc-branch: 3184-reallocate-api