Commit 01f49379 authored by zeroleak's avatar zeroleak
Browse files

refactor HD_Wallet.accounts to a map by accountIdx

parent 25e202e4
......@@ -28,7 +28,7 @@ public class BipWallet {
}
public String getPub(AddressType addressType) {
HD_Account hdAccount = bipWallet.getAccountAt(account.getAccountIndex());
HD_Account hdAccount = bipWallet.getAccount(account.getAccountIndex());
switch (addressType) {
case LEGACY:
return hdAccount.xpubstr();
......
......@@ -29,7 +29,7 @@ public class BIP47Account extends HD_Account {
*
*/
public BIP47Account(NetworkParameters params, DeterministicKey wKey, int child) {
super(params, wKey, "", child);
super(params, wKey, child);
strPaymentCode = createPaymentCodeFromAccountKey();
}
......
......@@ -22,12 +22,11 @@ public class BIP47Wallet extends HD_Wallet {
* @param NetworkParameters params
* @param byte[] seed seed for this wallet
* @param String passphrase optional BIP39 passphrase
* @param int nbAccounts number of accounts to create
*
*/
public BIP47Wallet(int purpose, MnemonicCode mc, NetworkParameters params, byte[] seed, String passphrase, int nbAccounts) throws MnemonicException.MnemonicLengthException {
public BIP47Wallet(int purpose, MnemonicCode mc, NetworkParameters params, byte[] seed, String passphrase) throws MnemonicException.MnemonicLengthException {
super(purpose, mc, params, seed, passphrase, nbAccounts);
super(purpose, mc, params, seed, passphrase);
mAccount = new BIP47Account(params, mRoot, 0);
......@@ -38,7 +37,7 @@ public class BIP47Wallet extends HD_Wallet {
* @param hdWallet
*/
public BIP47Wallet(HD_Wallet hdWallet) {
this(47, hdWallet, 1);
this(47, hdWallet);
}
/**
......@@ -46,12 +45,11 @@ public class BIP47Wallet extends HD_Wallet {
*
* @param int purpose
* @param HD_Wallet hdWallet to copy from
* @param int nbAccounts
*
*/
public BIP47Wallet(int purpose, HD_Wallet hdWallet, int nbAccounts) {
public BIP47Wallet(int purpose, HD_Wallet hdWallet) {
super(purpose, hdWallet, nbAccounts);
super(purpose, hdWallet);
mAccount = new BIP47Account(mParams, mRoot, 0);
......
......@@ -375,7 +375,7 @@ public class Stonewallx2Service extends AbstractCahootsService<STONEWALLx2> {
//
HD_Wallet bip84Wallet = cahootsWallet.getBip84Wallet();
String zpub = bip84Wallet.getAccountAt(stonewall1.getAccount()).zpubstr();
String zpub = bip84Wallet.getAccount(stonewall1.getAccount()).zpubstr();
HashMap<MyTransactionOutPoint, Triple<byte[], byte[], String>> inputsB = new HashMap<MyTransactionOutPoint, Triple<byte[], byte[], String>>();
for (CahootsUtxo utxo : selectedUTXO) {
......
......@@ -14,7 +14,6 @@ import org.json.JSONObject;
public class HD_Account {
protected DeterministicKey aKey = null;
private String strLabel = null;
protected int mAID; // accountIndex
private HD_Chain mReceive = null;
......@@ -28,10 +27,9 @@ public class HD_Account {
protected HD_Account() { ; }
public HD_Account(NetworkParameters params, DeterministicKey mKey, String label, int child) {
public HD_Account(NetworkParameters params, DeterministicKey mKey, int child) {
mParams = params;
strLabel = label;
mAID = child;
// L0PRV & STDVx: private derivation.
......@@ -48,10 +46,9 @@ public class HD_Account {
}
public HD_Account(NetworkParameters params, String xpub, String label, int child) throws AddressFormatException {
public HD_Account(NetworkParameters params, String xpub, int child) throws AddressFormatException {
mParams = params;
strLabel = label;
mAID = child;
// assign master key to account key
......@@ -82,14 +79,6 @@ public class HD_Account {
}
public String getLabel() {
return strLabel;
}
public void setLabel(String label) {
strLabel = label;
}
public int getId() {
return mAID;
}
......
......@@ -10,9 +10,7 @@ import org.bitcoinj.crypto.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
public class HD_Wallet {
private byte[] mSeed = null;
......@@ -21,7 +19,7 @@ public class HD_Wallet {
protected DeterministicKey mRoot = null; // null when created from xpub
protected ArrayList<HD_Account> mAccounts = null;
protected Map<Integer,HD_Account> mAccounts = null;
protected NetworkParameters mParams = null;
......@@ -30,50 +28,40 @@ public class HD_Wallet {
/*
create from seed+passphrase
*/
public HD_Wallet(int purpose, MnemonicCode mc, NetworkParameters mParams, byte[] mSeed, String strPassphrase, int nbAccounts) throws MnemonicException.MnemonicLengthException {
this(purpose, mc.toMnemonic(mSeed), mParams, mSeed, strPassphrase, nbAccounts);
public HD_Wallet(int purpose, MnemonicCode mc, NetworkParameters mParams, byte[] mSeed, String strPassphrase) throws MnemonicException.MnemonicLengthException {
this(purpose, mc.toMnemonic(mSeed), mParams, mSeed, strPassphrase);
}
protected HD_Wallet(int purpose, List<String> wordList, NetworkParameters mParams, byte[] mSeed, String strPassphrase, int nbAccounts) {
// used by Sparrow
public HD_Wallet(byte[] mSeed, String strPassphrase, List<String> mWordList, NetworkParameters mParams) {
this.mSeed = mSeed;
this.strPassphrase = strPassphrase;
this.mWordList = mWordList;
this.mParams = mParams;
this.mAccounts = new LinkedHashMap<>();
}
protected HD_Wallet(int purpose, List<String> wordList, NetworkParameters mParams, byte[] mSeed, String strPassphrase) {
this(mSeed, strPassphrase, wordList, mParams);
// compute rootKey for accounts
this.mRoot = computeRootKey(purpose, mWordList, strPassphrase, mParams);
// create accounts
mAccounts = new ArrayList<HD_Account>();
for(int i = 0; i < nbAccounts; i++) {
String acctName = String.format("account %02d", i);
mAccounts.add(new HD_Account(mParams, mRoot, acctName, i));
}
mAccounts = new LinkedHashMap<>();
}
protected HD_Wallet(int purpose, HD_Wallet inputWallet, int nbAccounts) {
this(purpose, inputWallet.mWordList, inputWallet.mParams, inputWallet.mSeed, inputWallet.strPassphrase, nbAccounts);
}
public HD_Wallet(int purpose, HD_Wallet inputWallet) {
this(purpose, inputWallet, 1);
this(purpose, inputWallet.mWordList, inputWallet.mParams, inputWallet.mSeed, inputWallet.strPassphrase);
}
/*
create from account xpub key(s)
*/
public HD_Wallet(NetworkParameters params, String[] xpub) throws AddressFormatException {
mParams = params;
mAccounts = new ArrayList<HD_Account>();
mAccounts = new LinkedHashMap<>();
for(int i = 0; i < xpub.length; i++) {
mAccounts.add(new HD_Account(mParams, xpub[i], "", i));
mAccounts.put(i, new HD_Account(mParams, xpub[i], i));
}
}
// used by Sparrow
public HD_Wallet(byte[] mSeed, String strPassphrase, List<String> mWordList, NetworkParameters mParams) {
this.mSeed = mSeed;
this.strPassphrase = strPassphrase;
this.mWordList = mWordList;
this.mParams = mParams;
}
private static DeterministicKey computeRootKey(int purpose, List<String> mWordList, String strPassphrase, NetworkParameters params) {
......@@ -101,25 +89,17 @@ public class HD_Wallet {
return strPassphrase;
}
public List<HD_Account> getAccounts() {
return mAccounts;
}
public NetworkParameters getParams() {
return mParams;
}
public HD_Account getAccount(int accountId) {
return mAccounts.get(accountId);
}
public HD_Account getAccountAt(int accountIdx) {
return new HD_Account(mParams, mRoot, "", accountIdx);
}
public void addAccount() {
String strName = String.format("Account %d", mAccounts.size());
mAccounts.add(new HD_Account(mParams, mRoot, strName, mAccounts.size()));
public HD_Account getAccount(int accountIdx) {
HD_Account hdAccount = mAccounts.get(accountIdx);
if (hdAccount == null) {
hdAccount = new HD_Account(mParams, mRoot, accountIdx);
mAccounts.put(accountIdx, hdAccount);
}
return hdAccount;
}
public String[] getXPUBs() {
......@@ -152,7 +132,7 @@ public class HD_Wallet {
}
public HD_Address getAddressAt(int account, int chain, int idx) {
return getAccountAt(account).getChain(chain).getAddressAt(idx);
return getAccount(account).getChain(chain).getAddressAt(idx);
}
public SegwitAddress getSegwitAddressAt(int account, int chain, int idx) {
......@@ -164,4 +144,11 @@ public class HD_Wallet {
public HD_Address getAddressAt(int account, UnspentOutput utxo) {
return getAddressAt(account, utxo.computePathChainIndex(), utxo.computePathAddressIndex());
}
public void wipe() {
for(HD_Account hdAccount : mAccounts.values()) {
hdAccount.getReceive().setAddrIdx(0);
hdAccount.getChange().setAddrIdx(0);
}
}
}
......@@ -31,7 +31,7 @@ public class HD_WalletFactoryGeneric {
this.mc = mc;
}
public HD_Wallet restoreWallet(String data, String passphrase, int nbAccounts, NetworkParameters params)
public HD_Wallet restoreWallet(String data, String passphrase, NetworkParameters params)
throws AddressFormatException, DecoderException,
MnemonicException.MnemonicLengthException, MnemonicException.MnemonicWordException,
MnemonicException.MnemonicChecksumException {
......@@ -47,10 +47,10 @@ public class HD_WalletFactoryGeneric {
hdw = new HD_Wallet(params, xpub);
} else if (data.matches(FormatsUtilGeneric.HEX) && data.length() % 4 == 0) {
byte[] seed = Hex.decodeHex(data.toCharArray());
hdw = new HD_Wallet(44, mc, params, seed, passphrase, nbAccounts);
hdw = new HD_Wallet(44, mc, params, seed, passphrase);
} else {
byte[] seed = computeSeedFromWords(data);
hdw = new HD_Wallet(44, mc, params, seed, passphrase, nbAccounts);
hdw = new HD_Wallet(44, mc, params, seed, passphrase);
}
return hdw;
}
......@@ -71,12 +71,12 @@ public class HD_WalletFactoryGeneric {
}
public HD_Wallet getHD(int purpose, byte[] seed, String passphrase, NetworkParameters params) throws MnemonicException.MnemonicLengthException {
HD_Wallet hdw = new HD_Wallet(purpose, mc, params, seed, passphrase, 1);
HD_Wallet hdw = new HD_Wallet(purpose, mc, params, seed, passphrase);
return hdw;
}
public BIP47Wallet getBIP47(String seed, String passphrase, NetworkParameters params) throws MnemonicException.MnemonicLengthException {
BIP47Wallet hdw47 = new BIP47Wallet(47, mc, params, org.bouncycastle.util.encoders.Hex.decode(seed), passphrase, 1);
BIP47Wallet hdw47 = new BIP47Wallet(47, mc, params, org.bouncycastle.util.encoders.Hex.decode(seed), passphrase);
return hdw47;
}
......
......@@ -2,6 +2,7 @@ package com.samourai.wallet.util;
import com.samourai.wallet.hd.*;
import com.samourai.wallet.segwit.SegwitAddress;
import com.samourai.whirlpool.client.wallet.beans.WhirlpoolAccount;
import org.apache.commons.lang3.tuple.Pair;
import org.bitcoinj.core.NetworkParameters;
import org.slf4j.Logger;
......@@ -34,6 +35,9 @@ public class AddressFactoryGeneric {
}
public void reset(HD_Wallet bip44Wallet, HD_Wallet bip49Wallet, HD_Wallet bip84Wallet, NetworkParameters params) {
if (log.isDebugEnabled()) {
log.debug("reset");
}
if (bip44Wallet == null) {
throw new RuntimeException("bip44Wallet is null");
}
......@@ -172,7 +176,7 @@ public class AddressFactoryGeneric {
// may happen on wallet startup
return null;
}
return hdWallet.getAccountAt(account).getChain(chain);
return hdWallet.getAccount(account).getChain(chain);
}
protected int getWalletIdx(WALLET_INDEX walletIndex) {
......@@ -281,18 +285,30 @@ public class AddressFactoryGeneric {
int walletIdx = walletIdxMap.get(walletIndex);
int hdIdx = getHdIdx(walletIndex);
int index = getIndex(walletIndex);
return highestIdx+" ; "+walletIdx+" ; "+hdIdx+" => "+index;
String debugStr = highestIdx+" ; "+walletIdx+" ; "+hdIdx+" => "+index;
if (log.isDebugEnabled()) {
log.debug(walletIndex+": "+debugStr);
}
return debugStr;
}
public void wipe() {
int nbAccounts = bip44Wallet.getAccounts().size();
for(int i = 0; i < nbAccounts; i++) {
bip44Wallet.getAccount(i).getReceive().setAddrIdx(0);
bip44Wallet.getAccount(i).getChange().setAddrIdx(0);
if (log.isDebugEnabled()) {
log.debug("wipe");
}
bip44Wallet.wipe();
for (WALLET_INDEX walletIndex : WALLET_INDEX.values()) {
setHighestIdx(walletIndex, 0);
setWalletIdx(walletIndex, 0, true);
}
}
public String getPub(AddressType addressType, WhirlpoolAccount account) {
HD_Wallet hdWallet = getHdWallet(addressType);
if (hdWallet == null) {
// may happen on wallet startup
throw new RuntimeException("getPub("+addressType+","+account+") failed: wallet is null");
}
return hdWallet.getAccount(account.getAccountIndex()).xpubstr();
}
}
......@@ -38,7 +38,7 @@ public class CryptoTestUtil {
public BIP47Wallet generateBip47Wallet(NetworkParameters networkParameters) throws Exception {
HD_Wallet bip44Wallet = generateWallet(44, networkParameters);
BIP47Wallet bip47Wallet = new BIP47Wallet(47, bip44Wallet, 1);
BIP47Wallet bip47Wallet = new BIP47Wallet(47, bip44Wallet);
return bip47Wallet;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment