Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion examples/src/main/java/org/bitcoinj/examples/FetchBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@
import org.bitcoinj.store.BlockStore;
import org.bitcoinj.store.MemoryBlockStore;
import org.bitcoinj.utils.BriefLogFormatter;
import org.jspecify.annotations.Nullable;
import picocli.CommandLine;

import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

Expand All @@ -44,7 +46,7 @@
@CommandLine.Command(usageHelpAutoWidth = true, sortOptions = false)
public class FetchBlock implements Callable<Integer> {
@CommandLine.Parameters(index = "0", description = "The hash of the block to download.")
private String blockHashParam;
private @Nullable String blockHashParam;
@CommandLine.Option(names = "--localhost", description = "Connect to the localhost node. Default: ${DEFAULT-VALUE}")
private boolean localhost = true;
@CommandLine.Option(names = "--help", usageHelp = true, description = "Displays program options.")
Expand All @@ -59,6 +61,7 @@ public static void main(String[] args) throws Exception {
@Override
public Integer call() throws Exception {
// Connect to testnet and find a peer
Objects.requireNonNull(blockHashParam);
System.out.println("Connecting to node");
final Network network = BitcoinNetwork.TESTNET;
final NetworkParameters params = NetworkParameters.of(network);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.bitcoinj.wallet.SendRequest;
import org.bitcoinj.wallet.Wallet;
import org.bitcoinj.wallet.listeners.WalletCoinsReceivedEventListener;
import org.jspecify.annotations.Nullable;

import java.io.Closeable;
import java.io.File;
Expand All @@ -46,7 +47,7 @@ public class ForwardingService implements Closeable {
static final int MAX_CONNECTIONS = 4;
private final BitcoinNetwork network;
private final Address forwardingAddress;
private volatile WalletAppKit kit;
private volatile @Nullable WalletAppKit kit;
/* We need to save the listener object (created by a method reference) so we can remove it later */
private final WalletCoinsReceivedEventListener coinsReceivedListener = this::coinForwardingListener;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.bitcoinj.signers.TransactionSigner.ProposedTransaction;
import org.bitcoinj.wallet.KeyBag;
import org.bitcoinj.wallet.RedeemData;
import org.jspecify.annotations.Nullable;

import java.io.IOException;
import java.math.BigInteger;
Expand Down Expand Up @@ -75,6 +76,7 @@ public ECKey findKeyFromPubKey(byte[] pubKey) {
}

@Override
@Nullable
public RedeemData findRedeemDataFromScriptHash(byte[] scriptHash) {
return null;
}
Expand Down
45 changes: 25 additions & 20 deletions examples/src/main/java/org/bitcoinj/examples/PrintPeers.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.bitcoinj.base.BitcoinNetwork;
import org.bitcoinj.base.Network;
import org.bitcoinj.core.Context;
import org.bitcoinj.core.NetworkParameters;
import org.bitcoinj.core.Peer;
import org.bitcoinj.core.PeerAddress;
Expand All @@ -33,55 +34,55 @@
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;

/**
* Prints a list of IP addresses obtained from DNS.
*/
public class PrintPeers {
private static List<InetSocketAddress> dnsPeers;
record PeerDnsResult(List<InetSocketAddress> dnsPeers, Duration duration) {}

private static void printElapsed(long start) {
long now = System.currentTimeMillis();
System.out.println(String.format("Took %.2f seconds", (now - start) / 1000.0));
}

private static void printPeers(List<InetSocketAddress> addresses) {
for (InetSocketAddress address : addresses) {
private static void printPeers(PeerDnsResult result) {
for (InetSocketAddress address : result.dnsPeers()) {
String hostAddress = address.getAddress().getHostAddress();
System.out.println(String.format("%s:%d", hostAddress, address.getPort()));
}
System.out.println(String.format("DNS query took %.2f seconds", result.duration().toMillis() / 1000.0));
}

private static void printDNS(Network network) throws PeerDiscoveryException {
private static PeerDnsResult getPeers(Network network) throws PeerDiscoveryException {
long start = System.currentTimeMillis();
DnsDiscovery dns = new DnsDiscovery(network);
dnsPeers = dns.getPeers(0, Duration.ofSeconds(10));
printPeers(dnsPeers);
printElapsed(start);
List<InetSocketAddress> dnsPeers = dns.getPeers(0, Duration.ofSeconds(10));
var duration = Duration.ofMillis(System.currentTimeMillis() - start);
return new PeerDnsResult(dnsPeers, duration);
}

public static void main(String[] args) throws Exception {
BriefLogFormatter.init();
BriefLogFormatter.init(Level.WARNING);
Context.propagate(new Context());
final Network network = BitcoinNetwork.MAINNET;
final NetworkParameters params = NetworkParameters.of(network);
System.out.println("=== DNS ===");
printDNS(network);
PeerDnsResult result = getPeers(network);
printPeers(result);
System.out.println("=== Version/chain heights ===");

ArrayList<InetAddress> addrs = new ArrayList<>();
for (InetSocketAddress peer : dnsPeers) addrs.add(peer.getAddress());
for (InetSocketAddress peer : result.dnsPeers()) addrs.add(peer.getAddress());
System.out.println("Scanning " + addrs.size() + " peers:");

final Object lock = new Object();
final long[] bestHeight = new long[1];

List<CompletableFuture<Void>> futures = new ArrayList<>();
List<CompletableFuture<Boolean>> futures = new ArrayList<>();
NioClientManager clientManager = new NioClientManager();
clientManager.start().join();
for (final InetAddress addr : addrs) {
InetSocketAddress address = new InetSocketAddress(addr, params.getPort());
final Peer peer = new Peer(params, new VersionMessage(params, 0),
PeerAddress.simple(address), null);
final CompletableFuture<Void> future = new CompletableFuture<>();
final CompletableFuture<Boolean> future = new CompletableFuture<>();
// Once the connection has completed version handshaking ...
peer.addConnectedEventListener((p, peerCount) -> {
// Check the chain height it claims to have.
Expand All @@ -100,18 +101,22 @@ public static void main(String[] args) throws Exception {
}
}
// Now finish the future and close the connection
future.complete(null);
future.complete(true);
peer.close();
});
peer.addDisconnectedEventListener((p, peerCount) -> {
if (!future.isDone())
if (!future.isDone()) {
System.out.println("Failed to talk to " + addr);
future.complete(null);
future.complete(false);
}
});
clientManager.openConnection(address, peer);
futures.add(future);
}
// Wait for every tried connection to finish.
CompletableFuture.allOf(futures.toArray( new CompletableFuture[0])).join();
int successful = futures.stream().mapToInt(f -> f.join() ? 1 : 0).sum();
int total = futures.size();
System.out.printf("Successfully talked to %d of %d nodes.\n", successful, total);
}
}
25 changes: 25 additions & 0 deletions examples/src/main/java/org/bitcoinj/examples/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright by the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* <b>bitcoinj<b> example applications including {@link org.bitcoinj.examples.ForwardingService} which
* is featured in the <b>Getting Started</b> tutorial.
* @see <a href="https://bitcoinj.org/getting-started-java">Getting Started</a>
*/
@NullMarked
package org.bitcoinj.examples;

import org.jspecify.annotations.NullMarked;
Loading