Browse Source

Another rework of null seed wallets, to allow them to be saved and loaded.

A full sync is unavoidable for P2SH redeem/refund, so we need to be able to save our progress. Creating a new null seed wallet each time isn't an option because it relies on having a recent checkpoint to avoid having to sync large amounts of blocks every time (sync is per wallet, not per node).
pirate-chain
CalDescent 2 years ago
parent
commit
85a26ae052
  1. 28
      src/main/java/org/qortal/controller/PirateChainWalletController.java
  2. 22
      src/main/java/org/qortal/crosschain/PirateChain.java
  3. 21
      src/main/java/org/qortal/crosschain/PirateWallet.java

28
src/main/java/org/qortal/controller/PirateChainWalletController.java

@ -87,7 +87,15 @@ public class PirateChainWalletController extends Thread {
}
public boolean initWithEntropy58(String entropy58) throws ForeignBlockchainException {
public boolean initWithEntropy58(String entropy58) {
return this.initWithEntropy58(entropy58, false);
}
public boolean initNullSeedWallet() {
return this.initWithEntropy58(Base58.encode(new byte[32]), true);
}
private boolean initWithEntropy58(String entropy58, boolean isNullSeedWallet) {
byte[] entropyBytes = Base58.decode(entropy58);
if (entropyBytes == null || entropyBytes.length != 32) {
@ -107,9 +115,9 @@ public class PirateChainWalletController extends Thread {
}
try {
this.currentWallet = new PirateWallet(entropyBytes, false);
if (!this.currentWallet.isReady() || this.currentWallet.hasNullSeed()) {
// Don't persist wallets that aren't ready or are null seed
this.currentWallet = new PirateWallet(entropyBytes, isNullSeedWallet);
if (!this.currentWallet.isReady()) {
// Don't persist wallets that aren't ready
this.currentWallet = null;
}
return true;
@ -120,16 +128,6 @@ public class PirateChainWalletController extends Thread {
return false;
}
public PirateWallet switchToNullWallet() {
try {
this.currentWallet = null;
return new PirateWallet(null, true);
} catch (IOException e) {
return null;
}
}
private void saveCurrentWallet() {
if (this.currentWallet == null) {
// Nothing to do
@ -164,7 +162,7 @@ public class PirateChainWalletController extends Thread {
public void ensureNotNullSeed() throws ForeignBlockchainException {
// Safety check to make sure funds aren't sent to a null seed wallet
if (this.currentWallet == null || this.currentWallet.hasNullSeed()) {
if (this.currentWallet == null || this.currentWallet.isNullSeedWallet()) {
throw new ForeignBlockchainException("Invalid wallet");
}
}

22
src/main/java/org/qortal/crosschain/PirateChain.java

@ -434,10 +434,13 @@ public class PirateChain extends Bitcoiny {
public String redeemP2sh(String p2shAddress, String receivingAddress, long amount, String redeemScript58,
String fundingTxid58, String secret58, String privateKey58) throws ForeignBlockchainException {
PirateWallet wallet = PirateChainWalletController.getInstance().switchToNullWallet();
if (wallet == null) {
throw new ForeignBlockchainException("Unable to initialize null seed Pirate Chain wallet");
}
// Use null seed wallet since we may not have the entropy bytes for a real wallet's seed
PirateChainWalletController walletController = PirateChainWalletController.getInstance();
walletController.initNullSeedWallet();
walletController.ensureInitialized();
walletController.ensureSynchronized();
walletController.getCurrentWallet().unlock();
// Build spend
JSONObject txn = new JSONObject();
@ -483,10 +486,13 @@ public class PirateChain extends Bitcoiny {
public String refundP2sh(String p2shAddress, String receivingAddress, long amount, String redeemScript58,
String fundingTxid58, int lockTime, String privateKey58) throws ForeignBlockchainException {
PirateWallet wallet = PirateChainWalletController.getInstance().switchToNullWallet();
if (wallet == null) {
throw new ForeignBlockchainException("Unable to initialize null seed Pirate Chain wallet");
}
// Use null seed wallet since we may not have the entropy bytes for a real wallet's seed
PirateChainWalletController walletController = PirateChainWalletController.getInstance();
walletController.initNullSeedWallet();
walletController.ensureInitialized();
walletController.ensureSynchronized();
walletController.getCurrentWallet().unlock();
// Build spend
JSONObject txn = new JSONObject();

21
src/main/java/org/qortal/crosschain/PirateWallet.java

@ -65,14 +65,7 @@ public class PirateWallet {
LiteWalletJni.initlogging();
if (this.entropyBytes == null) {
if (this.isNullSeedWallet) {
// Use null seed
this.entropyBytes = new byte[32];
}
else {
// Need entropy bytes for a non-null seed wallet
return false;
}
return false;
}
// Pirate library uses base64 encoding
@ -93,7 +86,7 @@ public class PirateWallet {
int birthday = DEFAULT_BIRTHDAY;
if (this.isNullSeedWallet) {
try {
// Attempt to set birthday to the current block for null wallets
// Attempt to set birthday to the current block for null seed wallets
birthday = PirateChain.getInstance().blockchainProvider.getCurrentHeight();
}
catch (ForeignBlockchainException e) {
@ -197,10 +190,6 @@ public class PirateWallet {
LOGGER.info("Error: can't save wallet, because no wallet it initialized");
return false;
}
if (this.isNullSeedWallet) {
LOGGER.info("Error: can't save null wallet");
return false;
}
// Encrypt first (will do nothing if already encrypted)
this.encrypt();
@ -229,10 +218,6 @@ public class PirateWallet {
}
public String load() throws IOException {
if (this.isNullSeedWallet) {
// Can't load null seed wallets
return null;
}
Path walletPath = this.getCurrentWalletPath();
if (!Files.exists(walletPath)) {
return null;
@ -321,7 +306,7 @@ public class PirateWallet {
return null;
}
public boolean hasNullSeed() {
public boolean isNullSeedWallet() {
return this.isNullSeedWallet;
}

Loading…
Cancel
Save