-
Notifications
You must be signed in to change notification settings - Fork 75
feat: Implement _initiateRelayerRefund and begin Optimism-specific SpokePool #20
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
Conversation
…art-contracts-v2 into npai/relay-refund-spoke-pool
|
@mrice32 @chrismaree not sure why but I the |
mrice32
left a 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.
Looks good! Only minor questions/comments
| * INTERNAL FUNCTIONS * | ||
| **************************************/ | ||
|
|
||
| function _setCrossDomainAdmin(address newCrossDomainAdmin) internal { |
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 there any way to call this function after construction? Is this something we'd like to be able to change? (genuine question, not suggesting a 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.
there is a setCrossDomainAdmin that can call this after construction enabling us to change it. I think we'd want to change it in the event something broke within the L1<->L2 logic. one problem, though, that I can see with this pattern is it assumes that the cross domain owner implements sufficient methods to call setCrossDomainAdmin over the bridge. this should be doable as this is going to be sitting within the "Adapter" logic that I've created for the L1->L2 calls. We can create a base contract (CrossDomainAdminBase) or something equivalent that these adapters will inherit from. can think more on this in the next few PRs.
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.
Yeah i added in this function without telling you. We should allow this to be changed from L1
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'm a little confused. Are there two functions that allow you to setCrossDomainAdmin? If so, can we consolidate them into a single function?
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.
No there's only one, implemented in this contract. setCrossDomainAdmin is included in the SpokePoolInterface
contracts/Optimism_SpokePool.sol
Outdated
| } | ||
|
|
||
| // TODO: | ||
| function setDepositQuoteTimeBuffer(uint64 buffer) public onlyFromCrossDomainAccount(crossDomainAdmin) { |
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 there any interface or anything that ensures that these functions match across all SpokePool implementations?
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.
Great point I'll add an interface
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.
do you think all L2 spoke pools will immplement the notion of a crossDomainAdmin? @chrismaree
test/constants.ts
Outdated
|
|
||
| export const zeroRawValue = { rawValue: "0" }; | ||
|
|
||
| export const spokePoolRelayerRefundRoot = createRandomBytes32(); |
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 have a const for this in my other PR called mockDestinationDistributionRoot.
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.
Will merge that in
|
|
||
| contract Optimism_SpokePool is CrossDomainEnabled, SpokePoolInterface, SpokePool { | ||
| // Address of the L1 contract that acts as the owner of this SpokePool. | ||
| address public override crossDomainAdmin; |
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.
@chrismaree @mrice32 should crossDomainAdmin be in the SpokePool or do you think this notion of a cross domain admin will be different for each. L2?
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 is the cross-domain admin? The optimism bridge address on L2? Or is it the BridgeAdmin address on L1?
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.
Its the contract that calls relayMessage on the canonical bridge, so its either the BridgeAdmin or the HubPool
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.
for now HubPool me thinks. we might want to change this later but I think lets leave it there optimistically at the moment.
mrice32
left a 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!
|
|
||
| contract Optimism_SpokePool is CrossDomainEnabled, SpokePoolInterface, SpokePool { | ||
| // Address of the L1 contract that acts as the owner of this SpokePool. | ||
| address public override crossDomainAdmin; |
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 is the cross-domain admin? The optimism bridge address on L2? Or is it the BridgeAdmin address on L1?
|
|
||
| struct RelayerRefund { | ||
| // Merkle root of relayer refunds. | ||
| bytes32 distributionRoot; |
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 interesting tradeoff about doing claims via merkle proofs one-by-one is that this will result in increased calldata costs on L2 over passing in all the leaves and storing (or maybe even executing) in a single call. This is because you will have to submit each leaf individually with another bytes32 element for each layer in the tree. This means that your overall calldata might be significantly larger than just passing in the leaves alone. I'm not sure how significant this would end up being, but I wonder how hard it would be for us to take in all the leaves and generate the proofs internally on-chain to show that they roll up into the root.
Not suggesting a change, just wanted to mention this.
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.
Hm so you think this could work by the HubPool relaying all leafs to the SpokePool here and storing them on-chain, as opposed to just relaying the root. @chrismaree wdyt?
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 dont think @mrice32 is proposing the HubPool passing the leafs; it cant do that in a efficient way. I think @mrice32 is proposing a technique where you can execute multiple leafs at once in a compressed structure and prove they are within the provided root. @mrice32 what you describe would fit into the execution stage of the process, right?
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.
How do you imagine we improve on just making the contract multicall and assuming distributeRelayerRefund is called multiple times in one batched txn?
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 wanna be super clear that I don't think we should do this now, and I think before we add this complexity, we should try to better understand the amount of calldata/gas savings we'd see from something like this with different tree sizes.
Agree @chrismaree. I'm not suggesting the HubPool do anything different since any added data anywhere on mainnet is going to be expensive.
If you did multicall, you would effectively be passing:
[{distributionStruct1, proofArray1}, {distributionStruct2, proofArray2}...]
What I'm suggesting is an additional method that allows you to pass all leaves this way:
[{distriubtionStruct1}, {distributionStruct2}, ...]
If we get the logic right in the contract, the leaf data could be used to generate the proofs so you wouldn't need to pass them in, thereby reducing calldata.
Co-authored-by: Matt Rice <matthewcrice32@gmail.com>
chrismaree
left a 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 looks great to me! keen to get the next bit of functionality in with the proofs.
No description provided.