mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 15:00:30 +01:00
Arbitrator signing of AccountAgeWitness with known pubkey
Improve debug logging. Lower level from warning to info Fix broken test Add example code to clean out unnecessary SignedWitnesses
This commit is contained in:
parent
7bd5969dcf
commit
0dc769bf9b
5 changed files with 51 additions and 24 deletions
|
@ -50,12 +50,15 @@ import java.time.temporal.ChronoUnit;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
import java.util.stream.Collector;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -125,6 +128,8 @@ public class SignedWitnessService {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// TODO: Enable cleaning of signed witness list when necessary
|
||||||
|
// cleanSignedWitnesses();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onBootstrapComplete() {
|
private void onBootstrapComplete() {
|
||||||
|
@ -441,7 +446,6 @@ public class SignedWitnessService {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void addToMap(SignedWitness signedWitness) {
|
void addToMap(SignedWitness signedWitness) {
|
||||||
// TODO: Perhaps filter out all but one signedwitness per accountagewitness
|
|
||||||
signedWitnessMap.putIfAbsent(signedWitness.getHashAsByteArray(), signedWitness);
|
signedWitnessMap.putIfAbsent(signedWitness.getHashAsByteArray(), signedWitness);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,4 +460,19 @@ public class SignedWitnessService {
|
||||||
private void doRepublishAllSignedWitnesses() {
|
private void doRepublishAllSignedWitnesses() {
|
||||||
signedWitnessMap.forEach((e, signedWitness) -> p2PService.addPersistableNetworkPayload(signedWitness, true));
|
signedWitnessMap.forEach((e, signedWitness) -> p2PService.addPersistableNetworkPayload(signedWitness, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove SignedWitnesses that are signed by TRADE that also have an ARBITRATOR signature
|
||||||
|
// for the same ownerPubKey and AccountAgeWitnessHash
|
||||||
|
private void cleanSignedWitnesses() {
|
||||||
|
var orphans = getRootSignedWitnessSet(false);
|
||||||
|
var signedWitnessesCopy = new HashSet<>(signedWitnessMap.values());
|
||||||
|
signedWitnessesCopy.forEach(sw -> orphans.forEach(orphan -> {
|
||||||
|
if (sw.getVerificationMethod() == SignedWitness.VerificationMethod.ARBITRATOR &&
|
||||||
|
Arrays.equals(sw.getWitnessOwnerPubKey(), orphan.getWitnessOwnerPubKey()) &&
|
||||||
|
Arrays.equals(sw.getAccountAgeWitnessHash(), orphan.getAccountAgeWitnessHash())) {
|
||||||
|
signedWitnessMap.remove(orphan.getHashAsByteArray());
|
||||||
|
log.info("Remove duplicate SignedWitness: {}", orphan.toString());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package bisq.core.account.witness;
|
package bisq.core.account.witness;
|
||||||
|
|
||||||
import bisq.core.account.sign.SignedWitness;
|
|
||||||
import bisq.core.account.sign.SignedWitnessService;
|
import bisq.core.account.sign.SignedWitnessService;
|
||||||
import bisq.core.filter.FilterManager;
|
import bisq.core.filter.FilterManager;
|
||||||
import bisq.core.filter.PaymentAccountFilter;
|
import bisq.core.filter.PaymentAccountFilter;
|
||||||
|
@ -67,14 +66,12 @@ import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -82,8 +79,6 @@ import java.util.stream.Stream;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -248,7 +243,7 @@ public class AccountAgeWitnessService {
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<AccountAgeWitness> findWitness(PaymentAccountPayload paymentAccountPayload,
|
Optional<AccountAgeWitness> findWitness(PaymentAccountPayload paymentAccountPayload,
|
||||||
PubKeyRing pubKeyRing) {
|
PubKeyRing pubKeyRing) {
|
||||||
byte[] accountInputDataWithSalt = getAccountInputDataWithSalt(paymentAccountPayload);
|
byte[] accountInputDataWithSalt = getAccountInputDataWithSalt(paymentAccountPayload);
|
||||||
byte[] hash = Hash.getSha256Ripemd160hash(Utilities.concatenateByteArrays(accountInputDataWithSalt,
|
byte[] hash = Hash.getSha256Ripemd160hash(Utilities.concatenateByteArrays(accountInputDataWithSalt,
|
||||||
pubKeyRing.getSignaturePubKeyBytes()));
|
pubKeyRing.getSignaturePubKeyBytes()));
|
||||||
|
@ -640,17 +635,24 @@ public class AccountAgeWitnessService {
|
||||||
signedWitnessService.signAccountAgeWitness(tradeAmount, accountAgeWitness, key, peersPubKey);
|
signedWitnessService.signAccountAgeWitness(tradeAmount, accountAgeWitness, key, peersPubKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String arbitratorSignAccountAgeWitness(AccountAgeWitness accountAgeWitness,
|
public String arbitratorSignOrphanWitness(AccountAgeWitness accountAgeWitness,
|
||||||
ECKey key,
|
ECKey key,
|
||||||
long time) {
|
long time) {
|
||||||
return signedWitnessService.signAccountAgeWitness(accountAgeWitness, key, null, time);
|
// Find AccountAgeWitness as signedwitness
|
||||||
|
var signedWitness = signedWitnessService.getSignedWitnessMap().values().stream()
|
||||||
|
.filter(sw -> Arrays.equals(sw.getAccountAgeWitnessHash(), accountAgeWitness.getHash()))
|
||||||
|
.findAny()
|
||||||
|
.orElse(null);
|
||||||
|
checkNotNull(signedWitness);
|
||||||
|
return signedWitnessService.signAccountAgeWitness(accountAgeWitness, key, signedWitness.getWitnessOwnerPubKey(),
|
||||||
|
time);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String arbitratorSignAccountAgeWitness(AccountAgeWitness accountAgeWitness,
|
public void arbitratorSignAccountAgeWitness(AccountAgeWitness accountAgeWitness,
|
||||||
ECKey key,
|
ECKey key,
|
||||||
byte[] tradersPubKey,
|
byte[] tradersPubKey,
|
||||||
long time) {
|
long time) {
|
||||||
return signedWitnessService.signAccountAgeWitness(accountAgeWitness, key, tradersPubKey, time);
|
signedWitnessService.signAccountAgeWitness(accountAgeWitness, key, tradersPubKey, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void traderSignPeersAccountAgeWitness(Trade trade) {
|
public void traderSignPeersAccountAgeWitness(Trade trade) {
|
||||||
|
|
|
@ -55,18 +55,23 @@ public class AccountAgeWitnessUtils {
|
||||||
|
|
||||||
// Log tree of signed witnesses
|
// Log tree of signed witnesses
|
||||||
public void logSignedWitnesses() {
|
public void logSignedWitnesses() {
|
||||||
var orphanSigners = signedWitnessService.getRootSignedWitnessSet(false);
|
var orphanSigners = signedWitnessService.getRootSignedWitnessSet(true);
|
||||||
log.info("Orphaned signed account age witnesses:");
|
log.info("Orphaned signed account age witnesses:");
|
||||||
orphanSigners.forEach(w -> {
|
orphanSigners.forEach(w -> {
|
||||||
log.warn("{}: {}", w.getVerificationMethod().toString(),
|
log.info("{}: Signer PKH: {} Owner PKH: {} time: {}", w.getVerificationMethod().toString(),
|
||||||
Utilities.bytesAsHexString(Hash.getRipemd160hash(w.getSignerPubKey())));
|
Utilities.bytesAsHexString(Hash.getRipemd160hash(w.getSignerPubKey())).substring(0,7),
|
||||||
|
Utilities.bytesAsHexString(Hash.getRipemd160hash(w.getWitnessOwnerPubKey())).substring(0,7),
|
||||||
|
w.getDate());
|
||||||
logChild(w, " ", new Stack<>());
|
logChild(w, " ", new Stack<>());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logChild(SignedWitness sigWit, String initString, Stack<P2PDataStorage.ByteArray> excluded) {
|
private void logChild(SignedWitness sigWit, String initString, Stack<P2PDataStorage.ByteArray> excluded) {
|
||||||
var allSig = signedWitnessService.getSignedWitnessMap();
|
var allSig = signedWitnessService.getSignedWitnessMap();
|
||||||
log.warn("{}{}", initString, Utilities.bytesAsHexString(sigWit.getAccountAgeWitnessHash()));
|
log.info("{}AEW: {} PKH: {} time: {}", initString,
|
||||||
|
Utilities.bytesAsHexString(sigWit.getAccountAgeWitnessHash()).substring(0, 7),
|
||||||
|
Utilities.bytesAsHexString(Hash.getRipemd160hash(sigWit.getWitnessOwnerPubKey())).substring(0, 7),
|
||||||
|
sigWit.getDate());
|
||||||
allSig.values().forEach(w -> {
|
allSig.values().forEach(w -> {
|
||||||
if (!excluded.contains(new P2PDataStorage.ByteArray(w.getWitnessOwnerPubKey())) &&
|
if (!excluded.contains(new P2PDataStorage.ByteArray(w.getWitnessOwnerPubKey())) &&
|
||||||
Arrays.equals(w.getSignerPubKey(), sigWit.getWitnessOwnerPubKey())) {
|
Arrays.equals(w.getSignerPubKey(), sigWit.getWitnessOwnerPubKey())) {
|
||||||
|
|
|
@ -324,11 +324,11 @@ public class AccountAgeWitnessServiceTest {
|
||||||
assertFalse(signedWitnessService.isSignedAccountAgeWitness(aew2));
|
assertFalse(signedWitnessService.isSignedAccountAgeWitness(aew2));
|
||||||
|
|
||||||
// Sign dummy AccountAgeWitness using signer key from SW_1
|
// Sign dummy AccountAgeWitness using signer key from SW_1
|
||||||
assertEquals(signedWitnessService.getRootSignedWitnessSet().size(), 1);
|
assertEquals(signedWitnessService.getRootSignedWitnessSet(false).size(), 1);
|
||||||
|
|
||||||
// TODO: move this to accountagewitnessservice
|
// TODO: move this to accountagewitnessservice
|
||||||
@SuppressWarnings("OptionalGetWithoutIsPresent")
|
@SuppressWarnings("OptionalGetWithoutIsPresent")
|
||||||
var orphanedSignedWitness = signedWitnessService.getRootSignedWitnessSet().stream().findAny().get();
|
var orphanedSignedWitness = signedWitnessService.getRootSignedWitnessSet(false).stream().findAny().get();
|
||||||
var dummyAccountAgeWitnessHash = Hash.getRipemd160hash(orphanedSignedWitness.getSignerPubKey());
|
var dummyAccountAgeWitnessHash = Hash.getRipemd160hash(orphanedSignedWitness.getSignerPubKey());
|
||||||
var dummyAEW = new AccountAgeWitness(dummyAccountAgeWitnessHash,
|
var dummyAEW = new AccountAgeWitness(dummyAccountAgeWitnessHash,
|
||||||
orphanedSignedWitness.getDate() -
|
orphanedSignedWitness.getDate() -
|
||||||
|
|
|
@ -94,7 +94,7 @@ public class SignSpecificWitnessWindow extends Overlay<SignSpecificWitnessWindow
|
||||||
|
|
||||||
searchAutoComplete = new JFXAutoCompletePopup<>();
|
searchAutoComplete = new JFXAutoCompletePopup<>();
|
||||||
searchAutoComplete.setPrefWidth(400);
|
searchAutoComplete.setPrefWidth(400);
|
||||||
searchAutoComplete.getSuggestions().addAll(accountAgeWitnessService.getAccountAgeWitnessMap().values());
|
searchAutoComplete.getSuggestions().addAll(accountAgeWitnessService.getOrphanSignedWitnesses());
|
||||||
searchAutoComplete.setSuggestionsCellFactory(param -> new ListCell<>() {
|
searchAutoComplete.setSuggestionsCellFactory(param -> new ListCell<>() {
|
||||||
@Override
|
@Override
|
||||||
protected void updateItem(AccountAgeWitness item, boolean empty) {
|
protected void updateItem(AccountAgeWitness item, boolean empty) {
|
||||||
|
@ -160,7 +160,8 @@ public class SignSpecificWitnessWindow extends Overlay<SignSpecificWitnessWindow
|
||||||
var arbitratorPubKeyAsHex = Utils.HEX.encode(arbitratorKey.getPubKey());
|
var arbitratorPubKeyAsHex = Utils.HEX.encode(arbitratorKey.getPubKey());
|
||||||
var isKeyValid = arbitratorManager.isPublicKeyInList(arbitratorPubKeyAsHex);
|
var isKeyValid = arbitratorManager.isPublicKeyInList(arbitratorPubKeyAsHex);
|
||||||
if (isKeyValid) {
|
if (isKeyValid) {
|
||||||
var result = accountAgeWitnessService.arbitratorSignAccountAgeWitness(selectedWitness, arbitratorKey,
|
var result = accountAgeWitnessService.arbitratorSignOrphanWitness(selectedWitness,
|
||||||
|
arbitratorKey,
|
||||||
datePicker.getValue().atStartOfDay().toEpochSecond(ZoneOffset.UTC) * 1000);
|
datePicker.getValue().atStartOfDay().toEpochSecond(ZoneOffset.UTC) * 1000);
|
||||||
if (result.isEmpty()) {
|
if (result.isEmpty()) {
|
||||||
addSuccessContent();
|
addSuccessContent();
|
||||||
|
|
Loading…
Add table
Reference in a new issue