mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-06-24 23:00:36 -04:00
153 lines
5.8 KiB
Java
153 lines
5.8 KiB
Java
package io.bitsquare.btc;
|
|
|
|
import com.google.bitcoin.core.*;
|
|
import com.google.bitcoin.kits.WalletAppKit;
|
|
import com.google.bitcoin.net.discovery.DnsDiscovery;
|
|
import com.google.bitcoin.store.BlockStoreException;
|
|
import com.google.bitcoin.store.SPVBlockStore;
|
|
import com.google.bitcoin.store.WalletProtobufSerializer;
|
|
import com.google.common.util.concurrent.FutureCallback;
|
|
import com.google.common.util.concurrent.Futures;
|
|
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
public class BitSquareWalletAppKit extends WalletAppKit
|
|
{
|
|
|
|
public BitSquareWalletAppKit(NetworkParameters params, File directory, String filePrefix)
|
|
{
|
|
super(params, directory, filePrefix);
|
|
}
|
|
|
|
@Override
|
|
protected void startUp() throws Exception
|
|
{
|
|
// Runs in a separate thread.
|
|
if (!directory.exists())
|
|
{
|
|
if (!directory.mkdir())
|
|
{
|
|
throw new IOException("Could not create named directory.");
|
|
}
|
|
}
|
|
FileInputStream walletStream = null;
|
|
try
|
|
{
|
|
File chainFile = new File(directory, filePrefix + ".spvchain");
|
|
boolean chainFileExists = chainFile.exists();
|
|
vWalletFile = new File(directory, filePrefix + ".wallet");
|
|
boolean shouldReplayWallet = vWalletFile.exists() && !chainFileExists;
|
|
|
|
vStore = new SPVBlockStore(params, chainFile);
|
|
if (!chainFileExists && checkpoints != null)
|
|
{
|
|
// Ugly hack! We have to create the wallet once here to learn the earliest key time, and then throw it
|
|
// away. The reason is that wallet extensions might need access to peergroups/chains/etc so we have to
|
|
// create the wallet later, but we need to know the time early here before we create the BlockChain
|
|
// object.
|
|
long time = Long.MAX_VALUE;
|
|
if (vWalletFile.exists())
|
|
{
|
|
Wallet wallet = new BitSquareWallet(params);
|
|
FileInputStream stream = new FileInputStream(vWalletFile);
|
|
new WalletProtobufSerializer().readWallet(WalletProtobufSerializer.parseToProto(stream), wallet);
|
|
time = wallet.getEarliestKeyCreationTime();
|
|
}
|
|
CheckpointManager.checkpoint(params, checkpoints, vStore, time);
|
|
}
|
|
vChain = new BlockChain(params, vStore);
|
|
vPeerGroup = createPeerGroup();
|
|
|
|
vPeerGroup.setBloomFilterFalsePositiveRate(0.001); // 0,1% instead of default 0,05%
|
|
|
|
if (this.userAgent != null)
|
|
vPeerGroup.setUserAgent(userAgent, version);
|
|
if (vWalletFile.exists())
|
|
{
|
|
walletStream = new FileInputStream(vWalletFile);
|
|
vWallet = new BitSquareWallet(params);
|
|
addWalletExtensions(); // All extensions must be present before we deserialize
|
|
new WalletProtobufSerializer().readWallet(WalletProtobufSerializer.parseToProto(walletStream), vWallet);
|
|
if (shouldReplayWallet)
|
|
vWallet.clearTransactions(0);
|
|
}
|
|
else
|
|
{
|
|
vWallet = new BitSquareWallet(params);
|
|
vWallet.addKey(new ECKey());
|
|
addWalletExtensions();
|
|
}
|
|
if (useAutoSave) vWallet.autosaveToFile(vWalletFile, 1, TimeUnit.SECONDS, null);
|
|
// Set up peer addresses or discovery first, so if wallet extensions try to broadcast a transaction
|
|
// before we're actually connected the broadcast waits for an appropriate number of connections.
|
|
if (peerAddresses != null)
|
|
{
|
|
for (PeerAddress addr : peerAddresses) vPeerGroup.addAddress(addr);
|
|
peerAddresses = null;
|
|
}
|
|
else
|
|
{
|
|
vPeerGroup.addPeerDiscovery(new DnsDiscovery(params));
|
|
}
|
|
vChain.addWallet(vWallet);
|
|
vPeerGroup.addWallet(vWallet);
|
|
onSetupCompleted();
|
|
|
|
if (blockingStartup)
|
|
{
|
|
vPeerGroup.startAndWait();
|
|
// Make sure we shut down cleanly.
|
|
installShutdownHook();
|
|
// TODO: Be able to use the provided download listener when doing a blocking startup.
|
|
final DownloadListener listener = new DownloadListener();
|
|
vPeerGroup.startBlockChainDownload(listener);
|
|
listener.await();
|
|
}
|
|
else
|
|
{
|
|
Futures.addCallback(vPeerGroup.start(), new FutureCallback<State>()
|
|
{
|
|
@Override
|
|
public void onSuccess(State result)
|
|
{
|
|
final PeerEventListener l = downloadListener == null ? new DownloadListener() : downloadListener;
|
|
vPeerGroup.startBlockChainDownload(l);
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(Throwable t)
|
|
{
|
|
throw new RuntimeException(t);
|
|
}
|
|
});
|
|
}
|
|
} catch (BlockStoreException e)
|
|
{
|
|
throw new IOException(e);
|
|
} finally
|
|
{
|
|
if (walletStream != null) walletStream.close();
|
|
}
|
|
}
|
|
|
|
private void installShutdownHook()
|
|
{
|
|
if (autoStop) Runtime.getRuntime().addShutdownHook(new Thread()
|
|
{
|
|
@Override
|
|
public void run()
|
|
{
|
|
try
|
|
{
|
|
BitSquareWalletAppKit.this.stopAndWait();
|
|
} catch (Exception e)
|
|
{
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|