store address data on wallet nodes

This commit is contained in:
Craig Raw 2022-07-18 16:11:59 +02:00
parent 9ae1f68dc4
commit 5de3abd362
9 changed files with 41 additions and 64 deletions

View file

@ -43,9 +43,13 @@ public abstract class Address {
public abstract ScriptType getScriptType();
public abstract Script getOutputScript();
public Script getOutputScript() {
return getScriptType().getOutputScript(data);
}
public abstract byte[] getOutputScriptData();
public byte[] getOutputScriptData() {
return data;
}
public abstract String getOutputScriptDataType();

View file

@ -24,15 +24,6 @@ public class P2PKAddress extends Address {
return ScriptType.P2PK;
}
public Script getOutputScript() {
return getScriptType().getOutputScript(data);
}
@Override
public byte[] getOutputScriptData() {
return data;
}
@Override
public String getOutputScriptDataType() {
return "Public Key";

View file

@ -19,16 +19,6 @@ public class P2PKHAddress extends Address {
return ScriptType.P2PKH;
}
@Override
public Script getOutputScript() {
return getScriptType().getOutputScript(data);
}
@Override
public byte[] getOutputScriptData() {
return data;
}
@Override
public String getOutputScriptDataType() {
return "Public Key Hash";

View file

@ -20,16 +20,6 @@ public class P2SHAddress extends Address {
return ScriptType.P2SH;
}
@Override
public Script getOutputScript() {
return getScriptType().getOutputScript(data);
}
@Override
public byte[] getOutputScriptData() {
return data;
}
@Override
public String getOutputScriptDataType() {
return "Script Hash";

View file

@ -25,16 +25,6 @@ public class P2TRAddress extends Address {
return ScriptType.P2TR;
}
@Override
public Script getOutputScript() {
return getScriptType().getOutputScript(data);
}
@Override
public byte[] getOutputScriptData() {
return data;
}
@Override
public String getOutputScriptDataType() {
return "Taproot";

View file

@ -25,16 +25,6 @@ public class P2WPKHAddress extends Address {
return ScriptType.P2WPKH;
}
@Override
public Script getOutputScript() {
return getScriptType().getOutputScript(data);
}
@Override
public byte[] getOutputScriptData() {
return data;
}
@Override
public String getOutputScriptDataType() {
return "Witness Public Key Hash";

View file

@ -23,16 +23,6 @@ public class P2WSHAddress extends Address {
return ScriptType.P2WSH;
}
@Override
public Script getOutputScript() {
return getScriptType().getOutputScript(data);
}
@Override
public byte[] getOutputScriptData() {
return data;
}
@Override
public String getOutputScriptDataType() {
return "Witness Script Hash";

View file

@ -31,7 +31,10 @@ public class Keystore extends Persistable {
private DeterministicSeed seed;
//For BIP47 keystores - not persisted but must be unencrypted to generate keys
private ExtendedKey bip47ExtendedPrivateKey;
private transient ExtendedKey bip47ExtendedPrivateKey;
//Avoid performing repeated expensive seed derivation checks
private transient boolean extendedPublicKeyChecked;
public Keystore() {
this(DEFAULT_LABEL);
@ -83,6 +86,7 @@ public class Keystore extends Persistable {
public void setExtendedPublicKey(ExtendedKey extendedPublicKey) {
this.extendedPublicKey = extendedPublicKey;
this.extendedPublicKeyChecked = false;
}
public PaymentCode getExternalPaymentCode() {
@ -125,6 +129,14 @@ public class Keystore extends Persistable {
return hasMasterPrivateKey() || (source == KeystoreSource.SW_PAYMENT_CODE && bip47ExtendedPrivateKey != null);
}
public boolean needsPassphrase() {
if(seed != null) {
return seed.needsPassphrase();
}
return false;
}
public PaymentCode getPaymentCode() {
DeterministicKey bip47Key = bip47ExtendedPrivateKey.getKey();
return new PaymentCode(bip47Key.getPubKey(), bip47Key.getChainCode());
@ -278,7 +290,7 @@ public class Keystore extends Persistable {
throw new InvalidKeystoreException("Source of " + source + " but no seed or master private key is present");
}
if((seed != null && !seed.isEncrypted()) || (masterPrivateExtendedKey != null && !masterPrivateExtendedKey.isEncrypted())) {
if(!extendedPublicKeyChecked && ((seed != null && !seed.isEncrypted()) || (masterPrivateExtendedKey != null && !masterPrivateExtendedKey.isEncrypted()))) {
try {
List<ChildNumber> derivation = getKeyDerivation().getDerivation();
DeterministicKey derivedKey = getExtendedMasterPrivateKey().getKey(derivation);
@ -287,6 +299,7 @@ public class Keystore extends Persistable {
if(!xpub.equals(getExtendedPublicKey())) {
throw new InvalidKeystoreException("Specified extended public key does not match public key derived from seed");
}
extendedPublicKeyChecked = true;
} catch(MnemonicException e) {
throw new InvalidKeystoreException("Invalid mnemonic specified for seed", e);
}

View file

@ -13,6 +13,7 @@ import java.util.stream.Collectors;
public class WalletNode extends Persistable implements Comparable<WalletNode> {
private final String derivationPath;
private String label;
private Address address;
private TreeSet<WalletNode> children = new TreeSet<>();
private TreeSet<BlockTransactionHashIndex> transactionOutputs = new TreeSet<>();
@ -267,11 +268,28 @@ public class WalletNode extends Persistable implements Comparable<WalletNode> {
}
public Address getAddress() {
if(address != null) {
return address;
}
if(wallet.getKeystores().stream().noneMatch(Keystore::needsPassphrase)) {
address = wallet.getAddress(this);
return address;
}
return wallet.getAddress(this);
}
public byte[] getAddressData() {
return address == null ? null : address.getData();
}
public void setAddress(Address address) {
this.address = address;
}
public Script getOutputScript() {
return wallet.getOutputScript(this);
return getAddress().getOutputScript();
}
public String getOutputDescriptor() {
@ -324,6 +342,7 @@ public class WalletNode extends Persistable implements Comparable<WalletNode> {
WalletNode copy = new WalletNode(walletCopy, derivationPath);
copy.setId(getId());
copy.setLabel(label);
copy.setAddress(address);
for(WalletNode child : getChildren()) {
copy.children.add(child.copy(walletCopy));