add mempool.bisq.services as a broadcaster, broadcast tx twice if possible on mainnet, handle different network broadcaster network capabilities

This commit is contained in:
Craig Raw 2021-05-21 11:48:13 +02:00
parent dd146210ba
commit c1cf5be616
2 changed files with 52 additions and 3 deletions

View file

@ -15,6 +15,7 @@ import java.net.Proxy;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.List;
public enum BroadcastSource {
BLOCKSTREAM_INFO("blockstream.info", "https://blockstream.info", "http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion") {
@ -24,6 +25,11 @@ public enum BroadcastSource {
return postTransactionData(data);
}
@Override
public List<Network> getSupportedNetworks() {
return List.of(Network.MAINNET, Network.TESTNET);
}
protected URL getURL(Proxy proxy) throws MalformedURLException {
if(Network.get() == Network.MAINNET) {
return new URL(getBaseUrl(proxy) + "/api/tx");
@ -40,6 +46,11 @@ public enum BroadcastSource {
return postTransactionData(data);
}
@Override
public List<Network> getSupportedNetworks() {
return List.of(Network.MAINNET, Network.TESTNET, Network.SIGNET);
}
protected URL getURL(Proxy proxy) throws MalformedURLException {
if(Network.get() == Network.MAINNET) {
return new URL(getBaseUrl(proxy) + "/api/tx");
@ -56,6 +67,32 @@ public enum BroadcastSource {
return postTransactionData(data);
}
@Override
public List<Network> getSupportedNetworks() {
return List.of(Network.MAINNET);
}
protected URL getURL(Proxy proxy) throws MalformedURLException {
if(Network.get() == Network.MAINNET) {
return new URL(getBaseUrl(proxy) + "/api/tx");
} else if(Network.get() == Network.TESTNET) {
return new URL(getBaseUrl(proxy) + "/testnet/api/tx");
} else {
throw new IllegalStateException("Cannot broadcast transaction to " + getName() + " on network " + Network.get());
}
}
},
MEMPOOL_BISQ_SERVICES("mempool.bisq.services", "https://mempool.bisq.services", "http://mempoolcutehjtynu4k4rd746acmssvj2vz4jbz4setb72clbpx2dfqd.onion") {
public Sha256Hash broadcastTransaction(Transaction transaction) throws BroadcastException {
String data = Utils.bytesToHex(transaction.bitcoinSerialize());
return postTransactionData(data);
}
@Override
public List<Network> getSupportedNetworks() {
return List.of(Network.MAINNET);
}
protected URL getURL(Proxy proxy) throws MalformedURLException {
if(Network.get() == Network.MAINNET) {
return new URL(getBaseUrl(proxy) + "/api/tx");
@ -98,6 +135,8 @@ public enum BroadcastSource {
public abstract Sha256Hash broadcastTransaction(Transaction transaction) throws BroadcastException;
public abstract List<Network> getSupportedNetworks();
protected abstract URL getURL(Proxy proxy) throws MalformedURLException;
public Sha256Hash postTransactionData(String data) throws BroadcastException {

View file

@ -37,6 +37,8 @@ public class ElectrumServer {
private static final String[] SUPPORTED_VERSIONS = new String[]{"1.3", "1.4.2"};
private static final int MINIMUM_BROADCASTS = 2;
public static final BlockTransaction UNFETCHABLE_BLOCK_TRANSACTION = new BlockTransaction(Sha256Hash.ZERO_HASH, 0, null, null, null);
private static Transport transport;
@ -1295,15 +1297,23 @@ public class ElectrumServer {
protected Sha256Hash call() throws ServerException {
//If Tor proxy is configured, try all external broadcast sources in random order before falling back to connected Electrum server
if(AppServices.getProxy() != null) {
List<BroadcastSource> broadcastSources = new ArrayList<>(Arrays.asList(BroadcastSource.values()));
while(!broadcastSources.isEmpty()) {
List<BroadcastSource> broadcastSources = Arrays.stream(BroadcastSource.values()).filter(src -> src.getSupportedNetworks().contains(Network.get())).collect(Collectors.toList());
Sha256Hash txid = null;
for(int i = 1; !broadcastSources.isEmpty(); i++) {
try {
BroadcastSource broadcastSource = broadcastSources.remove(new Random().nextInt(broadcastSources.size()));
return broadcastSource.broadcastTransaction(transaction);
txid = broadcastSource.broadcastTransaction(transaction);
if(Network.get() != Network.MAINNET || i >= MINIMUM_BROADCASTS || broadcastSources.isEmpty()) {
return txid;
}
} catch(BroadcastSource.BroadcastException e) {
//ignore, already logged
}
}
if(txid != null) {
return txid;
}
}
ElectrumServer electrumServer = new ElectrumServer();