mirror of
https://github.com/sparrowwallet/drongo.git
synced 2024-12-27 02:26:44 +00:00
refactor wallet node to non inner class
This commit is contained in:
parent
cc4f70002f
commit
60a0d450e0
2 changed files with 173 additions and 161 deletions
|
@ -1,9 +1,7 @@
|
||||||
package com.sparrowwallet.drongo.wallet;
|
package com.sparrowwallet.drongo.wallet;
|
||||||
|
|
||||||
import com.sparrowwallet.drongo.KeyDerivation;
|
|
||||||
import com.sparrowwallet.drongo.KeyPurpose;
|
import com.sparrowwallet.drongo.KeyPurpose;
|
||||||
import com.sparrowwallet.drongo.address.Address;
|
import com.sparrowwallet.drongo.address.Address;
|
||||||
import com.sparrowwallet.drongo.crypto.ChildNumber;
|
|
||||||
import com.sparrowwallet.drongo.crypto.DeterministicKey;
|
import com.sparrowwallet.drongo.crypto.DeterministicKey;
|
||||||
import com.sparrowwallet.drongo.crypto.ECKey;
|
import com.sparrowwallet.drongo.crypto.ECKey;
|
||||||
import com.sparrowwallet.drongo.crypto.Key;
|
import com.sparrowwallet.drongo.crypto.Key;
|
||||||
|
@ -24,7 +22,7 @@ public class Wallet {
|
||||||
private ScriptType scriptType;
|
private ScriptType scriptType;
|
||||||
private Policy defaultPolicy;
|
private Policy defaultPolicy;
|
||||||
private List<Keystore> keystores = new ArrayList<>();
|
private List<Keystore> keystores = new ArrayList<>();
|
||||||
private final Set<Node> purposeNodes = new TreeSet<>();
|
private final Set<WalletNode> purposeNodes = new TreeSet<>();
|
||||||
private final Map<String, Transaction> transactions = new HashMap<>();
|
private final Map<String, Transaction> transactions = new HashMap<>();
|
||||||
|
|
||||||
public Wallet() {
|
public Wallet() {
|
||||||
|
@ -82,7 +80,7 @@ public class Wallet {
|
||||||
this.keystores = keystores;
|
this.keystores = keystores;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Node> getPurposeNodes() {
|
private Set<WalletNode> getPurposeNodes() {
|
||||||
return purposeNodes;
|
return purposeNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,11 +88,11 @@ public class Wallet {
|
||||||
return transactions;
|
return transactions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getNode(KeyPurpose keyPurpose) {
|
public WalletNode getNode(KeyPurpose keyPurpose) {
|
||||||
Node purposeNode;
|
WalletNode purposeNode;
|
||||||
Optional<Node> optionalPurposeNode = purposeNodes.stream().filter(node -> node.getKeyPurpose().equals(keyPurpose)).findFirst();
|
Optional<WalletNode> optionalPurposeNode = purposeNodes.stream().filter(node -> node.getKeyPurpose().equals(keyPurpose)).findFirst();
|
||||||
if(optionalPurposeNode.isEmpty()) {
|
if(optionalPurposeNode.isEmpty()) {
|
||||||
purposeNode = new Node(keyPurpose);
|
purposeNode = new WalletNode(keyPurpose);
|
||||||
purposeNodes.add(purposeNode);
|
purposeNodes.add(purposeNode);
|
||||||
} else {
|
} else {
|
||||||
purposeNode = optionalPurposeNode.get();
|
purposeNode = optionalPurposeNode.get();
|
||||||
|
@ -104,7 +102,7 @@ public class Wallet {
|
||||||
return purposeNode;
|
return purposeNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLookAhead(Node node) {
|
public int getLookAhead(WalletNode node) {
|
||||||
//TODO: Calculate using seen transactions
|
//TODO: Calculate using seen transactions
|
||||||
int lookAhead = DEFAULT_LOOKAHEAD;
|
int lookAhead = DEFAULT_LOOKAHEAD;
|
||||||
Integer maxIndex = node.getHighestIndex();
|
Integer maxIndex = node.getHighestIndex();
|
||||||
|
@ -115,24 +113,24 @@ public class Wallet {
|
||||||
return lookAhead;
|
return lookAhead;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getFreshNode(KeyPurpose keyPurpose) {
|
public WalletNode getFreshNode(KeyPurpose keyPurpose) {
|
||||||
//TODO: Calculate using seen transactions
|
//TODO: Calculate using seen transactions
|
||||||
return getFreshNode(keyPurpose, null);
|
return getFreshNode(keyPurpose, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getFreshNode(KeyPurpose keyPurpose, Node current) {
|
public WalletNode getFreshNode(KeyPurpose keyPurpose, WalletNode current) {
|
||||||
//TODO: Calculate using seen transactions
|
//TODO: Calculate using seen transactions
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if(current != null) {
|
if(current != null) {
|
||||||
index = current.getIndex() + 1;
|
index = current.getIndex() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node node = getNode(keyPurpose);
|
WalletNode node = getNode(keyPurpose);
|
||||||
if(index >= node.getChildren().size()) {
|
if(index >= node.getChildren().size()) {
|
||||||
node.fillToIndex(index);
|
node.fillToIndex(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Node childNode : node.getChildren()) {
|
for(WalletNode childNode : node.getChildren()) {
|
||||||
if(childNode.getIndex() == index) {
|
if(childNode.getIndex() == index) {
|
||||||
return childNode;
|
return childNode;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +139,7 @@ public class Wallet {
|
||||||
throw new IllegalStateException("Could not fill nodes to index " + index);
|
throw new IllegalStateException("Could not fill nodes to index " + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Address getAddress(Node node) {
|
public Address getAddress(WalletNode node) {
|
||||||
return getAddress(node.getKeyPurpose(), node.getIndex());
|
return getAddress(node.getKeyPurpose(), node.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +157,7 @@ public class Wallet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Script getOutputScript(Node node) {
|
public Script getOutputScript(WalletNode node) {
|
||||||
return getOutputScript(node.getKeyPurpose(), node.getIndex());
|
return getOutputScript(node.getKeyPurpose(), node.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +175,7 @@ public class Wallet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOutputDescriptor(Node node) {
|
public String getOutputDescriptor(WalletNode node) {
|
||||||
return getOutputDescriptor(node.getKeyPurpose(), node.getIndex());
|
return getOutputDescriptor(node.getKeyPurpose(), node.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,22 +288,11 @@ public class Wallet {
|
||||||
for(Keystore keystore : keystores) {
|
for(Keystore keystore : keystores) {
|
||||||
copy.getKeystores().add(keystore.copy());
|
copy.getKeystores().add(keystore.copy());
|
||||||
}
|
}
|
||||||
for(Wallet.Node node : purposeNodes) {
|
for(WalletNode node : purposeNodes) {
|
||||||
Node nodeCopy = copy.copyNode(node);
|
copy.getPurposeNodes().add(node.copy());
|
||||||
copy.getPurposeNodes().add(nodeCopy);
|
|
||||||
}
|
}
|
||||||
return copy;
|
for(String transactionId : transactions.keySet()) {
|
||||||
}
|
copy.getTransactions().put(transactionId, transactions.get(transactionId));
|
||||||
|
|
||||||
private Node copyNode(Node node) {
|
|
||||||
Node copy = new Node(node.derivationPath);
|
|
||||||
copy.setLabel(node.label);
|
|
||||||
copy.setAmount(node.amount);
|
|
||||||
for(Node child : node.getChildren()) {
|
|
||||||
copy.getChildren().add(copyNode(child));
|
|
||||||
}
|
|
||||||
for(TransactionReference reference : node.getHistory()) {
|
|
||||||
copy.getHistory().add(reference.copy());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
|
@ -365,134 +352,4 @@ public class Wallet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Node implements Comparable<Node> {
|
|
||||||
private final String derivationPath;
|
|
||||||
private String label;
|
|
||||||
private Long amount;
|
|
||||||
private Set<Node> children = new TreeSet<>();
|
|
||||||
private Set<TransactionReference> history = new TreeSet<>();
|
|
||||||
|
|
||||||
private transient KeyPurpose keyPurpose;
|
|
||||||
private transient int index = -1;
|
|
||||||
private transient List<ChildNumber> derivation;
|
|
||||||
|
|
||||||
public Node(String derivationPath) {
|
|
||||||
this.derivationPath = derivationPath;
|
|
||||||
parseDerivation();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node(KeyPurpose keyPurpose) {
|
|
||||||
this.derivation = List.of(keyPurpose.getPathIndex());
|
|
||||||
this.derivationPath = KeyDerivation.writePath(derivation);
|
|
||||||
this.keyPurpose = keyPurpose;
|
|
||||||
this.index = keyPurpose.getPathIndex().num();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Node(KeyPurpose keyPurpose, int index) {
|
|
||||||
this.derivation = List.of(keyPurpose.getPathIndex(), new ChildNumber(index));
|
|
||||||
this.derivationPath = KeyDerivation.writePath(derivation);
|
|
||||||
this.keyPurpose = keyPurpose;
|
|
||||||
this.index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDerivationPath() {
|
|
||||||
return derivationPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void parseDerivation() {
|
|
||||||
this.derivation = KeyDerivation.parsePath(derivationPath);
|
|
||||||
this.keyPurpose = KeyPurpose.fromChildNumber(derivation.get(0));
|
|
||||||
this.index = derivation.get(derivation.size() - 1).num();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIndex() {
|
|
||||||
if(index < 0) {
|
|
||||||
parseDerivation();
|
|
||||||
}
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyPurpose getKeyPurpose() {
|
|
||||||
if(keyPurpose == null) {
|
|
||||||
parseDerivation();
|
|
||||||
}
|
|
||||||
|
|
||||||
return keyPurpose;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ChildNumber> getDerivation() {
|
|
||||||
if(derivation == null) {
|
|
||||||
parseDerivation();
|
|
||||||
}
|
|
||||||
|
|
||||||
return derivation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLabel() {
|
|
||||||
return label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLabel(String label) {
|
|
||||||
this.label = label;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getAmount() {
|
|
||||||
return amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAmount(Long amount) {
|
|
||||||
this.amount = amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Node> getChildren() {
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChildren(Set<Node> children) {
|
|
||||||
this.children = children;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<TransactionReference> getHistory() {
|
|
||||||
return history;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHistory(Set<TransactionReference> history) {
|
|
||||||
this.history = history;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fillToIndex(int index) {
|
|
||||||
for(int i = 0; i <= index; i++) {
|
|
||||||
Node node = new Node(getKeyPurpose(), i);
|
|
||||||
getChildren().add(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getHighestIndex() {
|
|
||||||
Node highestNode = null;
|
|
||||||
for(Node childNode : getChildren()) {
|
|
||||||
highestNode = childNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
return highestNode == null ? null : highestNode.index;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Node node = (Node) o;
|
|
||||||
return derivationPath.equals(node.derivationPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(derivationPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(Node node) {
|
|
||||||
return getIndex() - node.getIndex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
155
src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java
Normal file
155
src/main/java/com/sparrowwallet/drongo/wallet/WalletNode.java
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
package com.sparrowwallet.drongo.wallet;
|
||||||
|
|
||||||
|
import com.sparrowwallet.drongo.KeyDerivation;
|
||||||
|
import com.sparrowwallet.drongo.KeyPurpose;
|
||||||
|
import com.sparrowwallet.drongo.crypto.ChildNumber;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
public class WalletNode implements Comparable<WalletNode> {
|
||||||
|
private final String derivationPath;
|
||||||
|
private String label;
|
||||||
|
private Long amount;
|
||||||
|
private Set<WalletNode> children = new TreeSet<>();
|
||||||
|
private Set<TransactionReference> history = new TreeSet<>();
|
||||||
|
|
||||||
|
private transient KeyPurpose keyPurpose;
|
||||||
|
private transient int index = -1;
|
||||||
|
private transient List<ChildNumber> derivation;
|
||||||
|
|
||||||
|
public WalletNode(String derivationPath) {
|
||||||
|
this.derivationPath = derivationPath;
|
||||||
|
parseDerivation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WalletNode(KeyPurpose keyPurpose) {
|
||||||
|
this.derivation = List.of(keyPurpose.getPathIndex());
|
||||||
|
this.derivationPath = KeyDerivation.writePath(derivation);
|
||||||
|
this.keyPurpose = keyPurpose;
|
||||||
|
this.index = keyPurpose.getPathIndex().num();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WalletNode(KeyPurpose keyPurpose, int index) {
|
||||||
|
this.derivation = List.of(keyPurpose.getPathIndex(), new ChildNumber(index));
|
||||||
|
this.derivationPath = KeyDerivation.writePath(derivation);
|
||||||
|
this.keyPurpose = keyPurpose;
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDerivationPath() {
|
||||||
|
return derivationPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void parseDerivation() {
|
||||||
|
this.derivation = KeyDerivation.parsePath(derivationPath);
|
||||||
|
this.keyPurpose = KeyPurpose.fromChildNumber(derivation.get(0));
|
||||||
|
this.index = derivation.get(derivation.size() - 1).num();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
if(index < 0) {
|
||||||
|
parseDerivation();
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyPurpose getKeyPurpose() {
|
||||||
|
if(keyPurpose == null) {
|
||||||
|
parseDerivation();
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyPurpose;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ChildNumber> getDerivation() {
|
||||||
|
if(derivation == null) {
|
||||||
|
parseDerivation();
|
||||||
|
}
|
||||||
|
|
||||||
|
return derivation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLabel() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabel(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(Long amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<WalletNode> getChildren() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildren(Set<WalletNode> children) {
|
||||||
|
this.children = children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<TransactionReference> getHistory() {
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHistory(Set<TransactionReference> history) {
|
||||||
|
this.history = history;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fillToIndex(int index) {
|
||||||
|
for(int i = 0; i <= index; i++) {
|
||||||
|
WalletNode node = new WalletNode(getKeyPurpose(), i);
|
||||||
|
getChildren().add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getHighestIndex() {
|
||||||
|
WalletNode highestNode = null;
|
||||||
|
for(WalletNode childNode : getChildren()) {
|
||||||
|
highestNode = childNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return highestNode == null ? null : highestNode.index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
WalletNode node = (WalletNode) o;
|
||||||
|
return derivationPath.equals(node.derivationPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(derivationPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(WalletNode node) {
|
||||||
|
return getIndex() - node.getIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WalletNode copy() {
|
||||||
|
WalletNode copy = new WalletNode(derivationPath);
|
||||||
|
copy.setLabel(label);
|
||||||
|
copy.setAmount(amount);
|
||||||
|
for(WalletNode child : getChildren()) {
|
||||||
|
copy.getChildren().add(child.copy());
|
||||||
|
}
|
||||||
|
for(TransactionReference reference : getHistory()) {
|
||||||
|
copy.getHistory().add(reference.copy());
|
||||||
|
}
|
||||||
|
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue