-
Notifications
You must be signed in to change notification settings - Fork 13
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
Support fiber multiple hops payment in cross chain transaction #511
base: develop
Are you sure you want to change the base?
Support fiber multiple hops payment in cross chain transaction #511
Conversation
3f98938
to
21a1d8c
Compare
a63dc44
to
21a1d8c
Compare
21a1d8c
to
ee59e1f
Compare
…er-multiple-hops-payment-in-cross-chain-transaction
1ed77fd
to
969f732
Compare
@@ -23,7 +23,8 @@ rpc: | |||
|
|||
cch: | |||
ignore_startup_failure: true | |||
wrapped_btc_type_script_args: "0x32e555f3ff8e135cece1351a6a2971518392c1e30375c1e006ad0ce8eac07947" | |||
# will be generated by udt-init | |||
wrapped_btc_type_script: 0x55000000100000003000000031000000e1e354d6d643ad42724d40967e334984534e0367405c5ae42a9d7d63d77df419022000000032e555f3ff8e135cece1351a6a2971518392c1e30375c1e006ad0ce8eac07947 |
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.
we may use ckb json type Script
here, it's easy to read than a hex string:
wrapped_btc_type_script: 0x55000000100000003000000031000000e1e354d6d643ad42724d40967e334984534e0367405c5ae42a9d7d63d77df419022000000032e555f3ff8e135cece1351a6a2971518392c1e30375c1e006ad0ce8eac07947 | |
wrapped_btc_type_script: | |
code_hash: 0xe1e354d6d643ad42724d40967e334984534e0367405c5ae42a9d7d63d77df419 | |
hash_type: Data1 | |
args: 0x.... |
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.
wrapped_btc_type_script can also be specified with environment variable CCH_WRAPPED_BTC_TYPE_SCRIPT
. It is not very easy to write nested structures with environment variable. Can we both do a hex decoding and a ckb_json_types::Script
decoding? That makes both 0x55000000100000003000000031000000e1e354d6d643ad42724d40967e334984534e0367405c5ae42a9d7d63d77df419022000000032e555f3ff8e135cece1351a6a2971518392c1e30375c1e006ad0ce8eac07947
and code_hash: 0xe1e354d6d643ad42724d40967e334984534e0367405c5ae42a9d7d63d77df419 hash_type: Data1 args: 0x....
legitimate.
#[derive(Clone, Debug)] | ||
pub struct Store { | ||
pub struct GenericStore<IH: InvoiceUpdateHook, PH: PaymentUpdateHook> { |
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's no need to make a GenericStore
abstraction of the store here, it violates the principle of composition over inheritance, you can just use a store + hook struct wherever you need a store callback.
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 mean that the hooks can be passed to every one that needs them (instead of bundling them with the store)? There are many places in current code base which alters the status of an invoice, for example, https://github.com/contrun/fiber/blob/c53f6dfebba73ae7f9b3b75622abd7e8132eb3b6/src/rpc/invoice.rs#L340-L348 https://github.com/contrun/fiber/blob/c53f6dfebba73ae7f9b3b75622abd7e8132eb3b6/src/fiber/channel.rs#L1058-L1062 https://github.com/contrun/fiber/blob/c53f6dfebba73ae7f9b3b75622abd7e8132eb3b6/src/store/store.rs#L444-L447 , all the code listed above must have a reference to the InvoiceUpdateHook
. So it seems to me define a
Struct StoreWithHook<IH: InvoiceUpdateHook> {
store: Store,
hook: IH,
}
and pass this StoreWithHook
to above code would make life easier. That is essentially GenericStore<IH: InvoiceUpdateHook>
.
The thing is that Hook and Store can't really work work independently. Hook (calling it StoreUpdateHook is better) should be part of Store because the hooks run when store is updated. We can't compose these two inter-dependent component.
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.
keep the original store implementation unchanged:
impl InvoiceStore for Store {
fn insert_invoice(...) {
...
}
}
and add a compsited store implementation:
struct InvoiceStoreWithHook {
store: Store,
invoice_hook: ConcreteInvoiceHook,
}
impl InvoiceStore for InvoiceStoreWithHook {
fn insert_invoice(...) {
self.store.insert_invoice(...);
self.invoice_hook.on_invoice_updated(...);
}
}
no need to introduce GenericStore struct and InvoiceUpdateHook trait
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.
In https://github.com/contrun/fiber/tree/support-fiber-multiple-hops-payment-in-cross-chain-transaction-pass-hooks, I tried to use this approach (as I understood it). Can you confirm this align well with the approach you described? My code in that branch is very complicated, I don't know if that is the simplest way to accomplish what's on your mind. The complexity of my implementation is due to the following points:
- Hooks has to be initialized in the main function (we need to have a singleton to receive all the updates and push them to the subscribers).
- There are many modules which use
InvoiceStore
, so all of they have to callInvoiceStoreWithHooks::new
, which is a function to initialize aInvoiceStore
with a hook. This means we have to pass the invoice hooks created in the main function down to many modules. - Channel actors use
ChannelActorStateStore
along withInvoiceStore
. So we have to implementChannelActorStateStore
for theInvoiceStoreWithHooks
. - The same thing needs to be done for
NetworkGraphStateStore
(yeah, confusingly, this trait updates payment session), because we need to inject hooks for payments.
I didn't have a complete implementation yet. If my current code is what's on your mind. I can finish injecting payment hooks and removing the GenericStore
.
0a2be2d
to
548259b
Compare
@@ -272,6 +345,120 @@ impl NetworkNodeConfigBuilder { | |||
} | |||
} | |||
|
|||
#[allow(clippy::too_many_arguments)] | |||
pub(crate) async fn establish_udt_channel_between_nodes( | |||
node_a: &mut NetworkNode, |
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.
can we merge this with establish_channel_between_nodes
? seems only have a extra udt_script
.
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 do this because there are some many places in the code base calling establish_channel_between_nodes
. This PR is so large that we may encounter a few conflicts when this PR is ready to merge (this happened to the function create_n_nodes_and_channels_with_index_amounts
). When this PR is ready to merge, I will do what you said.
|| status == CkbInvoiceStatus::Received; | ||
let is_settled = | ||
self.store.get_invoice_preimage(&payment_hash).is_some(); | ||
if is_active && !is_settled { |
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 is_settled
could be removed, since if is_some
return true the code will goto Some(preimage)
branch and will never reach here.
// TLCs in the list applied_add_tlcs wouldn't be processed again. | ||
// For the unsettled active hold invoice TLCs, we should process them indefinitely | ||
// until they expire or are settled. | ||
state.tlc_state.applied_add_tlcs.remove(&add_tlc.tlc_id); |
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.
applied_add_tlcs
is introduced to resolve some concurrency issue, I'm not sure is it ok to remove it from here.
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 so. Because we are actually adding and removing the tlc from exactly the same function apply_add_tlc_operation_with_peeled_onion_packet
.
.insert_payment_preimage(payment_hash, preimage) | ||
.map_err(|_| { | ||
ProcessingChannelError::InternalError("insert preimage failed".to_string()) | ||
})?; |
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.
seems ProcessingChannelError::FinalIncorrectPaymentHash
does not return to caller. we should return the error at line 1019?
)) | ||
}; | ||
|
||
match call_t!(network_actor, message, RPC_TIMEOUT_MS).map_err(|ractor_error| { |
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 can reuse macro handle_actor_call like rpc/channel.rs.
No description provided.