forked from Qortal/qortal
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).
This commit is contained in:
parent
c30b1145a1
commit
85a26ae052
@ -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);
|
byte[] entropyBytes = Base58.decode(entropy58);
|
||||||
|
|
||||||
if (entropyBytes == null || entropyBytes.length != 32) {
|
if (entropyBytes == null || entropyBytes.length != 32) {
|
||||||
@ -107,9 +115,9 @@ public class PirateChainWalletController extends Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.currentWallet = new PirateWallet(entropyBytes, false);
|
this.currentWallet = new PirateWallet(entropyBytes, isNullSeedWallet);
|
||||||
if (!this.currentWallet.isReady() || this.currentWallet.hasNullSeed()) {
|
if (!this.currentWallet.isReady()) {
|
||||||
// Don't persist wallets that aren't ready or are null seed
|
// Don't persist wallets that aren't ready
|
||||||
this.currentWallet = null;
|
this.currentWallet = null;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -120,16 +128,6 @@ public class PirateChainWalletController extends Thread {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PirateWallet switchToNullWallet() {
|
|
||||||
try {
|
|
||||||
this.currentWallet = null;
|
|
||||||
return new PirateWallet(null, true);
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveCurrentWallet() {
|
private void saveCurrentWallet() {
|
||||||
if (this.currentWallet == null) {
|
if (this.currentWallet == null) {
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
@ -164,7 +162,7 @@ public class PirateChainWalletController extends Thread {
|
|||||||
|
|
||||||
public void ensureNotNullSeed() throws ForeignBlockchainException {
|
public void ensureNotNullSeed() throws ForeignBlockchainException {
|
||||||
// Safety check to make sure funds aren't sent to a null seed wallet
|
// 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");
|
throw new ForeignBlockchainException("Invalid wallet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -434,10 +434,13 @@ public class PirateChain extends Bitcoiny {
|
|||||||
public String redeemP2sh(String p2shAddress, String receivingAddress, long amount, String redeemScript58,
|
public String redeemP2sh(String p2shAddress, String receivingAddress, long amount, String redeemScript58,
|
||||||
String fundingTxid58, String secret58, String privateKey58) throws ForeignBlockchainException {
|
String fundingTxid58, String secret58, String privateKey58) throws ForeignBlockchainException {
|
||||||
|
|
||||||
PirateWallet wallet = PirateChainWalletController.getInstance().switchToNullWallet();
|
// Use null seed wallet since we may not have the entropy bytes for a real wallet's seed
|
||||||
if (wallet == null) {
|
PirateChainWalletController walletController = PirateChainWalletController.getInstance();
|
||||||
throw new ForeignBlockchainException("Unable to initialize null seed Pirate Chain wallet");
|
walletController.initNullSeedWallet();
|
||||||
}
|
walletController.ensureInitialized();
|
||||||
|
walletController.ensureSynchronized();
|
||||||
|
|
||||||
|
walletController.getCurrentWallet().unlock();
|
||||||
|
|
||||||
// Build spend
|
// Build spend
|
||||||
JSONObject txn = new JSONObject();
|
JSONObject txn = new JSONObject();
|
||||||
@ -483,10 +486,13 @@ public class PirateChain extends Bitcoiny {
|
|||||||
public String refundP2sh(String p2shAddress, String receivingAddress, long amount, String redeemScript58,
|
public String refundP2sh(String p2shAddress, String receivingAddress, long amount, String redeemScript58,
|
||||||
String fundingTxid58, int lockTime, String privateKey58) throws ForeignBlockchainException {
|
String fundingTxid58, int lockTime, String privateKey58) throws ForeignBlockchainException {
|
||||||
|
|
||||||
PirateWallet wallet = PirateChainWalletController.getInstance().switchToNullWallet();
|
// Use null seed wallet since we may not have the entropy bytes for a real wallet's seed
|
||||||
if (wallet == null) {
|
PirateChainWalletController walletController = PirateChainWalletController.getInstance();
|
||||||
throw new ForeignBlockchainException("Unable to initialize null seed Pirate Chain wallet");
|
walletController.initNullSeedWallet();
|
||||||
}
|
walletController.ensureInitialized();
|
||||||
|
walletController.ensureSynchronized();
|
||||||
|
|
||||||
|
walletController.getCurrentWallet().unlock();
|
||||||
|
|
||||||
// Build spend
|
// Build spend
|
||||||
JSONObject txn = new JSONObject();
|
JSONObject txn = new JSONObject();
|
||||||
|
@ -65,14 +65,7 @@ public class PirateWallet {
|
|||||||
LiteWalletJni.initlogging();
|
LiteWalletJni.initlogging();
|
||||||
|
|
||||||
if (this.entropyBytes == null) {
|
if (this.entropyBytes == null) {
|
||||||
if (this.isNullSeedWallet) {
|
return false;
|
||||||
// Use null seed
|
|
||||||
this.entropyBytes = new byte[32];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Need entropy bytes for a non-null seed wallet
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pirate library uses base64 encoding
|
// Pirate library uses base64 encoding
|
||||||
@ -93,7 +86,7 @@ public class PirateWallet {
|
|||||||
int birthday = DEFAULT_BIRTHDAY;
|
int birthday = DEFAULT_BIRTHDAY;
|
||||||
if (this.isNullSeedWallet) {
|
if (this.isNullSeedWallet) {
|
||||||
try {
|
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();
|
birthday = PirateChain.getInstance().blockchainProvider.getCurrentHeight();
|
||||||
}
|
}
|
||||||
catch (ForeignBlockchainException e) {
|
catch (ForeignBlockchainException e) {
|
||||||
@ -197,10 +190,6 @@ public class PirateWallet {
|
|||||||
LOGGER.info("Error: can't save wallet, because no wallet it initialized");
|
LOGGER.info("Error: can't save wallet, because no wallet it initialized");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (this.isNullSeedWallet) {
|
|
||||||
LOGGER.info("Error: can't save null wallet");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encrypt first (will do nothing if already encrypted)
|
// Encrypt first (will do nothing if already encrypted)
|
||||||
this.encrypt();
|
this.encrypt();
|
||||||
@ -229,10 +218,6 @@ public class PirateWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String load() throws IOException {
|
public String load() throws IOException {
|
||||||
if (this.isNullSeedWallet) {
|
|
||||||
// Can't load null seed wallets
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Path walletPath = this.getCurrentWalletPath();
|
Path walletPath = this.getCurrentWalletPath();
|
||||||
if (!Files.exists(walletPath)) {
|
if (!Files.exists(walletPath)) {
|
||||||
return null;
|
return null;
|
||||||
@ -321,7 +306,7 @@ public class PirateWallet {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNullSeed() {
|
public boolean isNullSeedWallet() {
|
||||||
return this.isNullSeedWallet;
|
return this.isNullSeedWallet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user