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:
sqrrm 2020-05-31 15:08:00 +02:00
parent 7bd5969dcf
commit 0dc769bf9b
No known key found for this signature in database
GPG key ID: 45235F9EF87089EC
5 changed files with 51 additions and 24 deletions

View file

@ -50,12 +50,15 @@ import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import lombok.Getter;
@ -125,6 +128,8 @@ public class SignedWitnessService {
}
});
}
// TODO: Enable cleaning of signed witness list when necessary
// cleanSignedWitnesses();
}
private void onBootstrapComplete() {
@ -441,7 +446,6 @@ public class SignedWitnessService {
@VisibleForTesting
void addToMap(SignedWitness signedWitness) {
// TODO: Perhaps filter out all but one signedwitness per accountagewitness
signedWitnessMap.putIfAbsent(signedWitness.getHashAsByteArray(), signedWitness);
}
@ -456,4 +460,19 @@ public class SignedWitnessService {
private void doRepublishAllSignedWitnesses() {
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());
}
}));
}
}

View file

@ -17,7 +17,6 @@
package bisq.core.account.witness;
import bisq.core.account.sign.SignedWitness;
import bisq.core.account.sign.SignedWitnessService;
import bisq.core.filter.FilterManager;
import bisq.core.filter.PaymentAccountFilter;
@ -67,14 +66,12 @@ import java.util.Arrays;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -82,8 +79,6 @@ import java.util.stream.Stream;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
@Slf4j
@ -248,7 +243,7 @@ public class AccountAgeWitnessService {
}
Optional<AccountAgeWitness> findWitness(PaymentAccountPayload paymentAccountPayload,
PubKeyRing pubKeyRing) {
PubKeyRing pubKeyRing) {
byte[] accountInputDataWithSalt = getAccountInputDataWithSalt(paymentAccountPayload);
byte[] hash = Hash.getSha256Ripemd160hash(Utilities.concatenateByteArrays(accountInputDataWithSalt,
pubKeyRing.getSignaturePubKeyBytes()));
@ -640,17 +635,24 @@ public class AccountAgeWitnessService {
signedWitnessService.signAccountAgeWitness(tradeAmount, accountAgeWitness, key, peersPubKey);
}
public String arbitratorSignAccountAgeWitness(AccountAgeWitness accountAgeWitness,
ECKey key,
long time) {
return signedWitnessService.signAccountAgeWitness(accountAgeWitness, key, null, time);
public String arbitratorSignOrphanWitness(AccountAgeWitness accountAgeWitness,
ECKey key,
long 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,
ECKey key,
byte[] tradersPubKey,
long time) {
return signedWitnessService.signAccountAgeWitness(accountAgeWitness, key, tradersPubKey, time);
public void arbitratorSignAccountAgeWitness(AccountAgeWitness accountAgeWitness,
ECKey key,
byte[] tradersPubKey,
long time) {
signedWitnessService.signAccountAgeWitness(accountAgeWitness, key, tradersPubKey, time);
}
public void traderSignPeersAccountAgeWitness(Trade trade) {

View file

@ -55,18 +55,23 @@ public class AccountAgeWitnessUtils {
// Log tree of signed witnesses
public void logSignedWitnesses() {
var orphanSigners = signedWitnessService.getRootSignedWitnessSet(false);
var orphanSigners = signedWitnessService.getRootSignedWitnessSet(true);
log.info("Orphaned signed account age witnesses:");
orphanSigners.forEach(w -> {
log.warn("{}: {}", w.getVerificationMethod().toString(),
Utilities.bytesAsHexString(Hash.getRipemd160hash(w.getSignerPubKey())));
log.info("{}: Signer PKH: {} Owner PKH: {} time: {}", w.getVerificationMethod().toString(),
Utilities.bytesAsHexString(Hash.getRipemd160hash(w.getSignerPubKey())).substring(0,7),
Utilities.bytesAsHexString(Hash.getRipemd160hash(w.getWitnessOwnerPubKey())).substring(0,7),
w.getDate());
logChild(w, " ", new Stack<>());
});
}
private void logChild(SignedWitness sigWit, String initString, Stack<P2PDataStorage.ByteArray> excluded) {
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 -> {
if (!excluded.contains(new P2PDataStorage.ByteArray(w.getWitnessOwnerPubKey())) &&
Arrays.equals(w.getSignerPubKey(), sigWit.getWitnessOwnerPubKey())) {

View file

@ -324,11 +324,11 @@ public class AccountAgeWitnessServiceTest {
assertFalse(signedWitnessService.isSignedAccountAgeWitness(aew2));
// 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
@SuppressWarnings("OptionalGetWithoutIsPresent")
var orphanedSignedWitness = signedWitnessService.getRootSignedWitnessSet().stream().findAny().get();
var orphanedSignedWitness = signedWitnessService.getRootSignedWitnessSet(false).stream().findAny().get();
var dummyAccountAgeWitnessHash = Hash.getRipemd160hash(orphanedSignedWitness.getSignerPubKey());
var dummyAEW = new AccountAgeWitness(dummyAccountAgeWitnessHash,
orphanedSignedWitness.getDate() -

View file

@ -94,7 +94,7 @@ public class SignSpecificWitnessWindow extends Overlay<SignSpecificWitnessWindow
searchAutoComplete = new JFXAutoCompletePopup<>();
searchAutoComplete.setPrefWidth(400);
searchAutoComplete.getSuggestions().addAll(accountAgeWitnessService.getAccountAgeWitnessMap().values());
searchAutoComplete.getSuggestions().addAll(accountAgeWitnessService.getOrphanSignedWitnesses());
searchAutoComplete.setSuggestionsCellFactory(param -> new ListCell<>() {
@Override
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 isKeyValid = arbitratorManager.isPublicKeyInList(arbitratorPubKeyAsHex);
if (isKeyValid) {
var result = accountAgeWitnessService.arbitratorSignAccountAgeWitness(selectedWitness, arbitratorKey,
var result = accountAgeWitnessService.arbitratorSignOrphanWitness(selectedWitness,
arbitratorKey,
datePicker.getValue().atStartOfDay().toEpochSecond(ZoneOffset.UTC) * 1000);
if (result.isEmpty()) {
addSuccessContent();