X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Ftest%2Fjava%2Forg%2Fldk%2FHumanObjectPeerTest.java;h=484f63b47350d0844c3dbc5d98ee967ab30a4644;hb=1347a5b4a7688ea4f3e69d6c10a08d57328fa344;hp=27ddc7c2a53e7f96f936651120ebc4cbc5f43737;hpb=3dcd430967b250ca9020d0f57a7fa5f8f5904aa9;p=ldk-java diff --git a/src/test/java/org/ldk/HumanObjectPeerTest.java b/src/test/java/org/ldk/HumanObjectPeerTest.java index 27ddc7c2..484f63b4 100644 --- a/src/test/java/org/ldk/HumanObjectPeerTest.java +++ b/src/test/java/org/ldk/HumanObjectPeerTest.java @@ -4,6 +4,7 @@ import org.bitcoinj.core.*; import org.bitcoinj.core.Transaction; import org.bitcoinj.script.Script; import org.junit.jupiter.api.Test; +import org.ldk.batteries.ChannelManagerConstructor; import org.ldk.batteries.NioPeerHandler; import org.ldk.enums.LDKNetwork; import org.ldk.impl.bindings; @@ -13,9 +14,7 @@ import org.ldk.util.TwoTuple; import java.io.IOException; import java.lang.ref.WeakReference; import java.net.InetSocketAddress; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedList; +import java.util.*; class HumanObjectPeerTestInstance { private final boolean nice_close; @@ -24,14 +23,16 @@ class HumanObjectPeerTestInstance { private final boolean reload_peers; private final boolean break_cross_peer_refs; private final boolean use_nio_peer_handler; + private final boolean use_filter; - HumanObjectPeerTestInstance(boolean nice_close, boolean use_km_wrapper, boolean use_manual_watch, boolean reload_peers, boolean break_cross_peer_refs, boolean use_nio_peer_handler) { + HumanObjectPeerTestInstance(boolean nice_close, boolean use_km_wrapper, boolean use_manual_watch, boolean reload_peers, boolean break_cross_peer_refs, boolean use_nio_peer_handler, boolean use_filter) { this.nice_close = nice_close; this.use_km_wrapper = use_km_wrapper; this.use_manual_watch = use_manual_watch; this.reload_peers = reload_peers; this.break_cross_peer_refs = break_cross_peer_refs; this.use_nio_peer_handler = use_nio_peer_handler; + this.use_filter = use_filter; } class Peer { @@ -42,9 +43,9 @@ class HumanObjectPeerTestInstance { @Override public byte[] get_shutdown_pubkey() { return underlying_if.get_shutdown_pubkey(); } @Override - public ChannelKeys get_channel_keys(boolean inbound, long channel_value_satoshis) { - ChannelKeys underlying_ck = underlying_if.get_channel_keys(inbound, channel_value_satoshis); - ChannelKeys.ChannelKeysInterface cki = new ChannelKeys.ChannelKeysInterface() { + public Sign get_channel_signer(boolean inbound, long channel_value_satoshis) { + Sign underlying_ck = underlying_if.get_channel_signer(inbound, channel_value_satoshis); + Sign.SignInterface si = new Sign.SignInterface() { @Override public byte[] get_per_commitment_point(long idx) { return underlying_ck.get_per_commitment_point(idx); @@ -56,8 +57,8 @@ class HumanObjectPeerTestInstance { } @Override - public TwoTuple key_derivation_params() { - return new TwoTuple((long)0, (long)1); + public byte[] channel_keys_id() { + return new byte[32]; } @Override @@ -100,8 +101,8 @@ class HumanObjectPeerTestInstance { return underlying_ck.write(); } }; - ChannelKeys resp = ChannelKeys.new_impl(cki, underlying_ck.get_pubkeys()); - must_free_objs.add(new WeakReference<>(cki)); + Sign resp = Sign.new_impl(si, underlying_ck.get_pubkeys()); + must_free_objs.add(new WeakReference<>(si)); must_free_objs.add(new WeakReference<>(resp)); must_free_objs.add(new WeakReference<>(underlying_ck)); return resp; @@ -113,7 +114,7 @@ class HumanObjectPeerTestInstance { } @Override - public Result_ChanKeySignerDecodeErrorZ read_chan_signer(byte[] reader) { + public Result_SignDecodeErrorZ read_chan_signer(byte[] reader) { return underlying_if.read_chan_signer(reader); } }); @@ -165,6 +166,8 @@ class HumanObjectPeerTestInstance { final ChainMonitor chain_monitor; final NetGraphMsgHandler router; final Watch chain_watch; + final HashSet filter_additions; + final Filter filter; ChannelManager chan_manager; EventsProvider chan_manager_events; PeerManager peer_manager; @@ -216,11 +219,26 @@ class HumanObjectPeerTestInstance { return new Result_NoneChannelMonitorUpdateErrZ.Result_NoneChannelMonitorUpdateErrZ_OK(); } }); + + filter_additions = new HashSet<>(); + if (use_filter) { + this.filter = Filter.new_impl(new Filter.FilterInterface() { + @Override public void register_tx(byte[] txid, byte[] script_pubkey) { + filter_additions.add(Arrays.toString(txid)); + } + @Override public void register_output(OutPoint outpoint, byte[] script_pubkey) { + filter_additions.add(Arrays.toString(outpoint.get_txid()) + ":" + outpoint.get_index()); + } + }); + } else { + this.filter = null; + } + if (use_manual_watch) { chain_watch = get_manual_watch(); chain_monitor = null; } else { - chain_monitor = ChainMonitor.constructor_new(null, tx_broadcaster, logger, fee_estimator, persister); + chain_monitor = ChainMonitor.constructor_new(filter, tx_broadcaster, logger, fee_estimator, persister); chain_watch = chain_monitor.as_Watch(); } @@ -228,7 +246,7 @@ class HumanObjectPeerTestInstance { for (byte i = 0; i < 32; i++) { key_seed[i] = (byte) (i ^ seed); } - KeysManager keys = KeysManager.constructor_new(key_seed, LDKNetwork.LDKNetwork_Bitcoin, System.currentTimeMillis() / 1000, (int) (System.currentTimeMillis() * 1000)); + KeysManager keys = KeysManager.constructor_new(key_seed, System.currentTimeMillis() / 1000, (int) (System.currentTimeMillis() * 1000)); if (use_km_wrapper) { this.keys_interface = manual_keysif(keys.as_KeysInterface()); } else { @@ -249,7 +267,7 @@ class HumanObjectPeerTestInstance { } Peer(byte seed) { this(null, seed); - this.chan_manager = ChannelManager.constructor_new(LDKNetwork.LDKNetwork_Bitcoin, FeeEstimator.new_impl(confirmation_target -> 0), chain_watch, tx_broadcaster, logger, this.keys_interface, UserConfig.constructor_default(), 1); + this.chan_manager = ChannelManager.constructor_new(FeeEstimator.new_impl(confirmation_target -> 0), chain_watch, tx_broadcaster, logger, this.keys_interface, UserConfig.constructor_default(), LDKNetwork.LDKNetwork_Bitcoin, new byte[32], 0); this.node_id = chan_manager.get_our_node_id(); this.chan_manager_events = chan_manager.as_EventsProvider(); @@ -264,28 +282,44 @@ class HumanObjectPeerTestInstance { Object ptr_to; Peer(Peer orig) { this(null, orig.seed); - ChannelMonitor[] monitors = new ChannelMonitor[1]; - synchronized (monitors) { - assert orig.monitors.size() == 1; - monitors[0] = orig.monitors.values().stream().iterator().next(); - if (break_cross_peer_refs) { - Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ res = UtilMethods.constructor_BlockHashChannelMonitorZ_read(monitors[0].write(), keys_interface); - assert res instanceof Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ.Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_OK; - monitors[0] = ((Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ.Result_C2Tuple_BlockHashChannelMonitorZDecodeErrorZ_OK) res).res.b; + if (!break_cross_peer_refs) { + ChannelMonitor[] monitors = new ChannelMonitor[1]; + synchronized (monitors) { + assert orig.monitors.size() == 1; + monitors[0] = orig.monitors.values().stream().iterator().next(); + } + byte[] serialized = orig.chan_manager.write(); + Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ read_res = + UtilMethods.constructor_BlockHashChannelManagerZ_read(serialized, this.keys_interface, this.fee_estimator, this.chain_watch, this.tx_broadcaster, this.logger, UserConfig.constructor_default(), monitors); + assert read_res instanceof Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ.Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ_OK; + this.chan_manager = ((Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ.Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ_OK) read_res).res.b; + this.chain_watch.watch_channel(monitors[0].get_funding_txo().a, monitors[0]); + } else { + final ArrayList channel_monitors = new ArrayList(); + synchronized (monitors) { + assert orig.monitors.size() == 1; + channel_monitors.add(orig.monitors.values().stream().iterator().next().write()); + } + byte[] serialized = orig.chan_manager.write(); + try { + ChannelManagerConstructor constructed = new ChannelManagerConstructor(serialized, channel_monitors.toArray(new byte[1][]), this.keys_interface, this.fee_estimator, this.chain_watch, this.filter, this.tx_broadcaster, this.logger); + this.chan_manager = constructed.channel_manager; + constructed.chain_sync_completed(); + if (use_filter && !use_manual_watch) { + // With a manual watch we don't actually use the filter object at all. + assert this.filter_additions.containsAll(orig.filter_additions) && + orig.filter_additions.containsAll(this.filter_additions); + } + } catch (ChannelManagerConstructor.InvalidSerializedDataException e) { + assert false; } } - byte[] serialized = orig.chan_manager.write(); - Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ read_res = - UtilMethods.constructor_BlockHashChannelManagerZ_read(serialized, this.keys_interface, this.fee_estimator, this.chain_watch, this.tx_broadcaster, this.logger, UserConfig.constructor_default(), monitors); if (!break_cross_peer_refs && (use_manual_watch || use_km_wrapper)) { // When we pass monitors[0] into chain_watch.watch_channel we create a reference from the new Peer to a // field in the old peer, preventing freeing of the original Peer until the new Peer is freed. Thus, we // shouldn't bother waiting for the original to be freed later on. cross_reload_ref_pollution = true; } - this.chain_watch.watch_channel(monitors[0].get_funding_txo().a, monitors[0]); - assert read_res instanceof Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ.Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ_OK; - this.chan_manager = ((Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ.Result_C2Tuple_BlockHashChannelManagerZDecodeErrorZ_OK) read_res).res.b; this.node_id = chan_manager.get_our_node_id(); this.chan_manager_events = chan_manager.as_EventsProvider(); @@ -317,7 +351,7 @@ class HumanObjectPeerTestInstance { txn = new TwoTuple[]{txp}; } else txn = new TwoTuple[0]; - chan_manager.block_connected(header, txn, height); + chan_manager.as_Listen().block_connected(b.bitcoinSerialize(), height); if (chain_monitor != null) { chain_monitor.block_connected(header, txn, height); } else { @@ -333,10 +367,24 @@ class HumanObjectPeerTestInstance { return null; } + Event[] get_monitor_events() { + if (chain_monitor != null) { + return chain_monitor.as_EventsProvider().get_and_clear_pending_events(); + } else { + synchronized (monitors) { + assert monitors.size() == 1; + for (ChannelMonitor mon : monitors.values()) { + return mon.get_and_clear_pending_events(); + } + return null; + } + } + } + Route get_route(byte[] dest_node, ChannelDetails[] our_chans) { try (LockedNetworkGraph netgraph = this.router.read_locked_graph()) { NetworkGraph graph = netgraph.graph(); - long res = bindings.get_route(this.node_id, graph._test_only_get_ptr(), dest_node, new long[]{our_chans[0]._test_only_get_ptr()}, + long res = bindings.get_route(this.node_id, graph._test_only_get_ptr(), dest_node, 0L, new long[]{our_chans[0]._test_only_get_ptr()}, new long[0], 1000, 42, this.logger._test_only_get_ptr()); assert bindings.LDKCResult_RouteLightningErrorZ_result_ok(res); byte[] serialized_route = bindings.Route_write(bindings.LDKCResult_RouteLightningErrorZ_get_ok(res)); @@ -379,7 +427,7 @@ class HumanObjectPeerTestInstance { if (use_nio_peer_handler) { peer1.nio_peer_handler.check_events(); peer2.nio_peer_handler.check_events(); - try { Thread.sleep(500); } catch (InterruptedException e) { assert false; } + try { Thread.sleep(400); } catch (InterruptedException e) { assert false; } } else { synchronized (runqueue) { ran = false; @@ -415,7 +463,7 @@ class HumanObjectPeerTestInstance { void connect_peers(final Peer peer1, final Peer peer2) { if (use_nio_peer_handler) { try { - peer1.nio_peer_handler.connect(peer2.chan_manager.get_our_node_id(), new InetSocketAddress("127.0.0.1", peer2.nio_port)); + peer1.nio_peer_handler.connect(peer2.chan_manager.get_our_node_id(), new InetSocketAddress("127.0.0.1", peer2.nio_port), 100); } catch (IOException e) { assert false; } } else { DescriptorHolder descriptor1 = new DescriptorHolder(); @@ -517,6 +565,18 @@ class HumanObjectPeerTestInstance { assert payment_res instanceof Result_NonePaymentSendFailureZ.Result_NonePaymentSendFailureZ_OK; wait_events_processed(peer1, peer2); + RouteHop[][] hops = new RouteHop[1][1]; + byte[] hop_pubkey = new byte[33]; + hop_pubkey[0] = 3; + hop_pubkey[1] = 42; + hops[0][0] = RouteHop.constructor_new(hop_pubkey, NodeFeatures.constructor_known(), 42, ChannelFeatures.constructor_known(), 100, 0); + Route r2 = Route.constructor_new(hops); + payment_res = peer1.chan_manager.send_payment(r2, payment_hash, new byte[32]); + assert payment_res instanceof Result_NonePaymentSendFailureZ.Result_NonePaymentSendFailureZ_Err; + + assert peer1.get_monitor_events().length == 0; + assert peer2.get_monitor_events().length == 0; + if (reload_peers) { if (use_nio_peer_handler) { peer1.nio_peer_handler.interrupt(); @@ -556,8 +616,8 @@ class HumanObjectPeerTestInstance { System.runFinalization(); } connect_peers(state.peer1, state.peer2); - wait_events_processed(state.peer1, state.peer2); } + wait_events_processed(state.peer1, state.peer2); Event[] events = state.peer2.chan_manager_events.get_and_clear_pending_events(); assert events.length == 1; @@ -596,7 +656,7 @@ class HumanObjectPeerTestInstance { Transaction tx = new Transaction(bitcoinj_net, state.peer1.broadcast_set.getFirst()); Block b = new Block(bitcoinj_net, 2, state.best_blockhash, Sha256Hash.ZERO_HASH, 42, 0, 0, Arrays.asList(new Transaction[]{tx})); - TwoTuple[]>[] watch_outputs = state.peer2.connect_block(b, 1, 1); + TwoTuple[]>[] watch_outputs = state.peer2.connect_block(b, 10, 1); if (watch_outputs != null) { // We only process watch_outputs manually when we use a manually-build Watch impl assert watch_outputs.length == 1; assert Arrays.equals(watch_outputs[0].a, tx.getTxId().getReversedBytes()); @@ -610,9 +670,16 @@ class HumanObjectPeerTestInstance { } if (use_nio_peer_handler) { + state.peer1.peer_manager.disconnect_by_node_id(state.peer2.chan_manager.get_our_node_id(), false); + wait_events_processed(state.peer1, state.peer2); + assert state.peer1.peer_manager.get_peer_node_ids().length == 0; + assert state.peer2.peer_manager.get_peer_node_ids().length == 0; state.peer1.nio_peer_handler.interrupt(); state.peer2.nio_peer_handler.interrupt(); } + + assert state.peer1.get_monitor_events().length == 0; + assert state.peer2.get_monitor_events().length == 0; } java.util.LinkedList> must_free_objs = new java.util.LinkedList(); @@ -627,7 +694,7 @@ class HumanObjectPeerTestInstance { } public class HumanObjectPeerTest { HumanObjectPeerTestInstance do_test_run(boolean nice_close, boolean use_km_wrapper, boolean use_manual_watch, boolean reload_peers, boolean break_cross_peer_refs, boolean nio_peer_handler) throws InterruptedException { - HumanObjectPeerTestInstance instance = new HumanObjectPeerTestInstance(nice_close, use_km_wrapper, use_manual_watch, reload_peers, break_cross_peer_refs, nio_peer_handler); + HumanObjectPeerTestInstance instance = new HumanObjectPeerTestInstance(nice_close, use_km_wrapper, use_manual_watch, reload_peers, break_cross_peer_refs, nio_peer_handler, !nio_peer_handler); HumanObjectPeerTestInstance.TestState state = instance.do_test_message_handler(); instance.do_test_message_handler_b(state); return instance;