Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add segwit support to the BTC wallet #4568

Merged
merged 30 commits into from
Oct 8, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f13a7b1
Create a P2WPKH keychain for new btc wallets
oscarguindzberg Sep 14, 2020
cd28660
Add a P2WPKH keychain for existing wallets
oscarguindzberg Sep 14, 2020
ced357c
AddressEntry: Add boolean segwit flag
oscarguindzberg Sep 14, 2020
e85c66b
Stop using LegacyAddress for btc addresses
oscarguindzberg Sep 14, 2020
0c7f345
Fix log msg in BtcCoinSelector
oscarguindzberg Sep 14, 2020
0f4c66f
Comment out segwit BSQ account path
oscarguindzberg Sep 29, 2020
2551571
TradeWalletService: adapt to segwit wallet
oscarguindzberg Sep 29, 2020
d8b7557
WalletService: adapt to segwit wallet
oscarguindzberg Sep 29, 2020
a370848
New AddressEntry: use different script types
oscarguindzberg Sep 25, 2020
a9cc28f
AddressEntryList: arbitrator entry use P2PKH
oscarguindzberg Sep 25, 2020
f9f5d92
Add segwit/legacy checbox for address creation
oscarguindzberg Sep 25, 2020
1f3c585
Serialize tx without segwit
oscarguindzberg Sep 28, 2020
58afc00
Don't create an extra address at startup
oscarguindzberg Sep 28, 2020
e2f74f0
Don't create a wallet address when not needed
oscarguindzberg Sep 28, 2020
d1aeedd
Remove unused WalletService.findKeyFromPubKeyHash()
oscarguindzberg Sep 24, 2020
78a2a43
Remove unused import
oscarguindzberg Sep 14, 2020
01455d2
Enable reusing unused AVAILABLE entries
oscarguindzberg Oct 1, 2020
4a2c0ad
Make codacy happy
oscarguindzberg Oct 1, 2020
86ddd06
Validate AddressEntry.segwit
oscarguindzberg Oct 5, 2020
b9e404f
Make it clear segwit is not used for the trade protocol yet.
oscarguindzberg Oct 5, 2020
5524ba3
BtcWalletService.getFreshAddressEntry(): code clean up
oscarguindzberg Oct 5, 2020
d1aaf3e
Construct dummy outputs with LegacyAddress
oscarguindzberg Oct 5, 2020
3554e19
setWitness(): Code clean up
oscarguindzberg Oct 5, 2020
499d7b7
Use try-with-resources
oscarguindzberg Oct 5, 2020
1d82c01
Improve error handling for P2WPKH
oscarguindzberg Oct 5, 2020
694446c
Switch back to LegacyAddress for fee estimation
oscarguindzberg Oct 5, 2020
a747e83
Fix add segwit keychain for encrypted wallet
oscarguindzberg Oct 7, 2020
417daf5
Use bitcoinj 0.15.8 (commit a733034)
oscarguindzberg Oct 8, 2020
87da2ae
Do a backup of the wallet before segwit migration
oscarguindzberg Oct 8, 2020
261e0ec
Check migratedWalletToSegwit is true
oscarguindzberg Oct 8, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
AddressEntry: Add boolean segwit flag
  • Loading branch information
oscarguindzberg committed Oct 8, 2020
commit ced357ce258a1538b592b5f00e703eab12619e1e
25 changes: 18 additions & 7 deletions core/src/main/java/bisq/core/btc/model/AddressEntry.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.LegacyAddress;
import org.bitcoinj.crypto.DeterministicKey;
import org.bitcoinj.script.Script;

import java.util.Optional;

Expand Down Expand Up @@ -74,6 +75,9 @@ public enum Context {

private long coinLockedInMultiSig;

@Getter
private boolean segwit;

@Nullable
transient private DeterministicKey keyPair;
@Nullable
Expand All @@ -86,18 +90,20 @@ public enum Context {
// Constructor, initialization
///////////////////////////////////////////////////////////////////////////////////////////

public AddressEntry(DeterministicKey keyPair, Context context) {
this(keyPair, context, null);
public AddressEntry(DeterministicKey keyPair, Context context, boolean segwit) {
this(keyPair, context, null, segwit);
}

public AddressEntry(@NotNull DeterministicKey keyPair,
Context context,
@Nullable String offerId) {
@Nullable String offerId,
boolean segwit) {
this.keyPair = keyPair;
this.context = context;
this.offerId = offerId;
pubKey = keyPair.getPubKey();
pubKeyHash = keyPair.getPubKeyHash();
this.segwit = segwit;
}


Expand All @@ -109,20 +115,23 @@ private AddressEntry(byte[] pubKey,
byte[] pubKeyHash,
Context context,
@Nullable String offerId,
Coin coinLockedInMultiSig) {
Coin coinLockedInMultiSig,
boolean segwit) {
this.pubKey = pubKey;
this.pubKeyHash = pubKeyHash;
this.context = context;
this.offerId = offerId;
this.coinLockedInMultiSig = coinLockedInMultiSig.value;
this.segwit = segwit;
}

public static AddressEntry fromProto(protobuf.AddressEntry proto) {
return new AddressEntry(proto.getPubKey().toByteArray(),
proto.getPubKeyHash().toByteArray(),
ProtoUtil.enumFromProto(AddressEntry.Context.class, proto.getContext().name()),
ProtoUtil.stringOrNullFromProto(proto.getOfferId()),
Coin.valueOf(proto.getCoinLockedInMultiSig()));
Coin.valueOf(proto.getCoinLockedInMultiSig()),
proto.getSegwit());
}

@Override
Expand All @@ -131,7 +140,8 @@ public protobuf.AddressEntry toProtoMessage() {
.setPubKey(ByteString.copyFrom(pubKey))
.setPubKeyHash(ByteString.copyFrom(pubKeyHash))
.setContext(protobuf.AddressEntry.Context.valueOf(context.name()))
.setCoinLockedInMultiSig(coinLockedInMultiSig);
.setCoinLockedInMultiSig(coinLockedInMultiSig)
.setSegwit(segwit);
Optional.ofNullable(offerId).ifPresent(builder::setOfferId);
return builder.build();
}
Expand Down Expand Up @@ -175,7 +185,7 @@ public String getAddressString() {
@Nullable
public Address getAddress() {
if (address == null && keyPair != null)
address = LegacyAddress.fromKey(Config.baseCurrencyNetworkParameters(), keyPair);
address = Address.fromKey(Config.baseCurrencyNetworkParameters(), keyPair, segwit ? Script.ScriptType.P2WPKH : Script.ScriptType.P2PKH);
return address;
}

Expand All @@ -198,6 +208,7 @@ public String toString() {
", context=" + context +
", offerId='" + offerId + '\'' +
", coinLockedInMultiSig=" + coinLockedInMultiSig +
", segwit=" + segwit +
"}";
}
}
20 changes: 12 additions & 8 deletions core/src/main/java/bisq/core/btc/model/AddressEntryList.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import org.bitcoinj.core.Address;
import org.bitcoinj.core.LegacyAddress;
import org.bitcoinj.core.SegwitAddress;
import org.bitcoinj.core.Transaction;
import org.bitcoinj.crypto.DeterministicKey;
import org.bitcoinj.script.Script;
Expand All @@ -35,6 +36,8 @@

import com.google.common.collect.ImmutableList;

import org.apache.commons.lang3.tuple.Pair;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
Expand Down Expand Up @@ -133,7 +136,7 @@ public void onWalletReady(Wallet wallet) {
toBeRemoved.forEach(entrySet::remove);
} else {
// As long the old arbitration domain is not removed from the code base we still support it here.
entrySet.add(new AddressEntry(wallet.freshReceiveKey(), AddressEntry.Context.ARBITRATOR));
entrySet.add(new AddressEntry(wallet.freshReceiveKey(), AddressEntry.Context.ARBITRATOR, true));
}

// In case we restore from seed words and have balance we need to add the relevant addresses to our list.
Expand All @@ -147,7 +150,7 @@ public void onWalletReady(Wallet wallet) {
DeterministicKey key = (DeterministicKey) wallet.findKeyFromAddress(address);
if (key != null) {
// Address will be derived from key in getAddress method
entrySet.add(new AddressEntry(key, AddressEntry.Context.AVAILABLE));
entrySet.add(new AddressEntry(key, AddressEntry.Context.AVAILABLE, address instanceof SegwitAddress));
}
});
}
Expand Down Expand Up @@ -192,7 +195,8 @@ public void addAddressEntry(AddressEntry addressEntry) {
public void swapToAvailable(AddressEntry addressEntry) {
boolean setChangedByRemove = entrySet.remove(addressEntry);
boolean setChangedByAdd = entrySet.add(new AddressEntry(addressEntry.getKeyPair(),
AddressEntry.Context.AVAILABLE));
AddressEntry.Context.AVAILABLE,
addressEntry.isSegwit()));
if (setChangedByRemove || setChangedByAdd) {
requestPersistence();
}
Expand All @@ -202,7 +206,7 @@ public AddressEntry swapAvailableToAddressEntryWithOfferId(AddressEntry addressE
AddressEntry.Context context,
String offerId) {
boolean setChangedByRemove = entrySet.remove(addressEntry);
final AddressEntry newAddressEntry = new AddressEntry(addressEntry.getKeyPair(), context, offerId);
final AddressEntry newAddressEntry = new AddressEntry(addressEntry.getKeyPair(), context, offerId, addressEntry.isSegwit());
boolean setChangedByAdd = entrySet.add(newAddressEntry);
if (setChangedByRemove || setChangedByAdd)
requestPersistence();
Expand All @@ -225,10 +229,10 @@ private void maybeAddNewAddressEntry(Transaction tx) {
.map(output -> output.getScriptPubKey().getToAddress(wallet.getNetworkParameters()))
.filter(Objects::nonNull)
.filter(this::isAddressNotInEntries)
.map(address -> (DeterministicKey) wallet.findKeyFromPubKeyHash(address.getHash(),
Script.ScriptType.P2PKH))
.filter(Objects::nonNull)
.map(deterministicKey -> new AddressEntry(deterministicKey, AddressEntry.Context.AVAILABLE))
.map(address -> Pair.of(address, (DeterministicKey) wallet.findKeyFromAddress(address)))
.filter(pair -> pair.getRight() != null)
.map(pair -> new AddressEntry(pair.getRight(), AddressEntry.Context.AVAILABLE,
pair.getLeft() instanceof SegwitAddress))
.forEach(this::addAddressEntry);
}

Expand Down
22 changes: 11 additions & 11 deletions core/src/main/java/bisq/core/btc/wallet/BtcWalletService.java
Original file line number Diff line number Diff line change
Expand Up @@ -584,23 +584,13 @@ public AddressEntry getOrCreateAddressEntry(String offerId, AddressEntry.Context
if (emptyAvailableAddressEntry.isPresent()) {
return addressEntryList.swapAvailableToAddressEntryWithOfferId(emptyAvailableAddressEntry.get(), context, offerId);
} else {
AddressEntry entry = new AddressEntry(wallet.freshReceiveKey(), context, offerId);
AddressEntry entry = new AddressEntry(wallet.freshReceiveKey(), context, offerId, true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that never called from a trade protocol entry? e.g. the one for the multisig.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems you commented on outdated code.

addressEntryList.addAddressEntry(entry);
return entry;
}
}
}

private AddressEntry getOrCreateAddressEntry(AddressEntry.Context context, Optional<AddressEntry> addressEntry) {
if (addressEntry.isPresent()) {
return addressEntry.get();
} else {
AddressEntry entry = new AddressEntry(wallet.freshReceiveKey(), context);
addressEntryList.addAddressEntry(entry);
return entry;
}
}

public AddressEntry getArbitratorAddressEntry() {
AddressEntry.Context context = AddressEntry.Context.ARBITRATOR;
Optional<AddressEntry> addressEntry = getAddressEntryListAsImmutableList().stream()
Expand All @@ -623,6 +613,16 @@ public void recoverAddressEntry(String offerId, String address, AddressEntry.Con
addressEntryList.swapAvailableToAddressEntryWithOfferId(addressEntry, context, offerId));
}

private AddressEntry getOrCreateAddressEntry(AddressEntry.Context context, Optional<AddressEntry> addressEntry) {
if (addressEntry.isPresent()) {
return addressEntry.get();
} else {
AddressEntry entry = new AddressEntry(wallet.freshReceiveKey(), context, true);
addressEntryList.addAddressEntry(entry);
return entry;
}
}

private Optional<AddressEntry> findAddressEntry(String address, AddressEntry.Context context) {
return getAddressEntryListAsImmutableList().stream()
.filter(e -> address.equals(e.getAddressString()))
Expand Down
1 change: 1 addition & 0 deletions proto/src/main/proto/pb.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,7 @@ message AddressEntry {
bytes pub_key = 9;
bytes pub_key_hash = 10;
int64 coin_locked_in_multi_sig = 11;
bool segwit = 12;
}

message NavigationPath {
Expand Down