+ if (use_chan_manager_constructor) {
+ byte[][] monitors = {orig.monitors.values().stream().iterator().next().write()};
+ byte[] serialized = orig.chan_manager.write();
+ byte[] serialized_graph = orig.net_graph.write();
+ byte[] serialized_scorer = orig.constructor.scorer.write();
+ try {
+ Filter filter_nullable = null;
+ if (this.filter instanceof Option_FilterZ.Some) {
+ filter_nullable = ((Option_FilterZ.Some) this.filter).some;
+ }
+ this.constructor = new ChannelManagerConstructor(serialized, monitors, get_config(),
+ this.explicit_keys_manager, this.fee_estimator, this.chain_monitor, filter_nullable,
+ serialized_graph, ProbabilisticScoringParameters.with_default(), serialized_scorer, null,
+ this.tx_broadcaster, this.logger);
+ try {
+ // Test that ChannelManagerConstructor correctly rejects duplicate ChannelMonitors
+ byte[][] monitors_dupd = new byte[2][];
+ monitors_dupd[0] = monitors[0];
+ monitors_dupd[1] = monitors[0];
+ ChannelManagerConstructor constr = new ChannelManagerConstructor(serialized, monitors_dupd, get_config(),
+ this.explicit_keys_manager, this.fee_estimator, this.chain_monitor, filter_nullable,
+ serialized_graph, ProbabilisticScoringParameters.with_default(), serialized_scorer, null,
+ this.tx_broadcaster, this.logger);
+ assert false;
+ } catch (ChannelManagerConstructor.InvalidSerializedDataException e) {}
+ this.net_graph = this.constructor.net_graph;
+ setup_route_handler();
+ constructor.chain_sync_completed(new ChannelManagerConstructor.EventHandler() {
+ @Override public void handle_event(Event event) {
+ synchronized (pending_manager_events) {
+ pending_manager_events.add(event);
+ pending_manager_events.notifyAll();
+ }
+ }
+ @Override public void persist_manager(byte[] channel_manager_bytes) { assert channel_manager_bytes.length > 1; }
+ @Override public void persist_network_graph(byte[] graph_bytes) { assert graph_bytes.length > 1; }
+ @Override public void persist_scorer(byte[] scorer_bytes) { assert scorer_bytes.length > 1; }
+ }, !use_ignore_handler);
+ this.chan_manager = constructor.channel_manager;
+ this.peer_manager = constructor.peer_manager;
+ must_free_objs.add(new WeakReference<>(this.chan_manager));
+ // If we are using a ChannelManagerConstructor, we may have pending events waiting on the old peer
+ // which have been removed from the ChannelManager but which we still need to handle.
+ this.pending_manager_events.addAll(orig.pending_manager_events);
+ if (!this.pending_manager_events.isEmpty()) {
+ // However, this implies cross_reload_ref_pollution
+ cross_reload_ref_pollution = true;
+ }
+ } catch (ChannelManagerConstructor.InvalidSerializedDataException e) {
+ assert false;
+ }
+ } else {
+ this.net_graph = NetworkGraph.of(Network.LDKNetwork_Bitcoin, this.logger);
+ Router router = Router.new_impl(new Router.RouterInterface() {
+ @Override
+ public Result_RouteLightningErrorZ find_route_with_id(byte[] payer, RouteParameters route_params, ChannelDetails[] first_hops, InFlightHtlcs inflight_htlcs, byte[] _payment_hash, byte[] _payment_id) {
+ return find_route(payer, route_params, first_hops, inflight_htlcs);
+ }
+
+ @Override
+ public Result_RouteLightningErrorZ find_route(byte[] payer, RouteParameters params, ChannelDetails[] first_hops, InFlightHtlcs inflight_htlcs) {
+ while (true) {
+ try (ReadOnlyNetworkGraph graph = net_graph.read_only()) {
+ assert graph.channel(424242) == null;
+ long[] channels = graph.list_channels();
+ if (channels.length != 1) {
+ // If we're using a NioPeerHandler, the handling of announcement signatures and
+ // channel broadcasting may be done async, so just wait until the channel shows up.
+ assert use_nio_peer_handler;
+ continue;
+ }
+ ChannelInfo chan = graph.channel(channels[0]);
+ assert Arrays.equals(chan.get_node_one().as_slice(), chan.get_node_one().write());
+ assert Arrays.equals(chan.get_node_one().as_slice(), chan_manager.get_our_node_id()) ||
+ Arrays.equals(chan.get_node_two().as_slice(), chan_manager.get_our_node_id());
+ break;
+ }
+ }
+ return UtilMethods.find_route(payer, params, net_graph, first_hops, logger, Score.new_impl(new Score.ScoreInterface() {
+ @Override public void payment_path_failed(RouteHop[] path, long scid) {}
+ @Override public long channel_penalty_msat(long short_channel_id, NodeId source, NodeId target, ChannelUsage usage) { return 0; }
+ @Override public void payment_path_successful(RouteHop[] path) {}
+ @Override public void probe_failed(RouteHop[] path, long short_channel_id) { assert false; }
+ @Override public void probe_successful(RouteHop[] path) { assert false; }
+ @Override public byte[] write() { assert false; return null; }
+ }), new byte[32]);
+ }
+ });
+ this.setup_route_handler();