From 0d481ac084cbc2f8a7f156ba475533d7ff6d62b3 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 12:48:21 -0500 Subject: [PATCH 01/27] Fix wrong linebreaks --- core/src/main/resources/i18n/displayStrings.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 4e8ef470bd8..e8e55a0296c 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -814,7 +814,8 @@ you can open a support ticket manually by selecting the trade which causes the p under \"Portfolio/Open trades\" and typing the key combination \"alt + o\" or \"option + o\". \ Please use that only if you are sure that the software is not working as expected. \ If you have problems or questions, please review the FAQ at the \ -bisq.network web page or post in the Bisq forum at the support section.\n\n\ +bisq.network web page or post in the Bisq forum at the support section. + support.initialInfo=Please note the basic rules for the dispute process:\n\ 1. You need to respond to the arbitrators requests in between 2 days.\n\ 2. The maximum period for the dispute is 14 days.\n\ From 6ef9ba00dbf325d85e8399a3da0bb6cf115b13b5 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 12:48:41 -0500 Subject: [PATCH 02/27] Add printStackTrace if resource not found --- core/src/main/java/bisq/core/locale/Res.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/bisq/core/locale/Res.java b/core/src/main/java/bisq/core/locale/Res.java index 738c1ae8eaa..a1c3a07d75e 100644 --- a/core/src/main/java/bisq/core/locale/Res.java +++ b/core/src/main/java/bisq/core/locale/Res.java @@ -46,7 +46,7 @@ @Slf4j public class Res { public static void setup() { - final BaseCurrencyNetwork baseCurrencyNetwork = BisqEnvironment.getBaseCurrencyNetwork(); + BaseCurrencyNetwork baseCurrencyNetwork = BisqEnvironment.getBaseCurrencyNetwork(); setBaseCurrencyCode(baseCurrencyNetwork.getCurrencyCode()); setBaseCurrencyName(baseCurrencyNetwork.getCurrencyName()); } @@ -116,6 +116,7 @@ public static String get(String key) { .replace("bitcoin", baseCurrencyNameLowerCase); } catch (MissingResourceException e) { log.warn("Missing resource for key: " + key); + e.printStackTrace(); if (DevEnv.isDevMode()) UserThread.runAfter(() -> { // We delay a bit to not throw while UI is not ready From 4094ff99a8e344d5eefb75e53ebbf4ddf46eed16 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 13:40:07 -0500 Subject: [PATCH 03/27] Add equals and hashCode methods to classes which use enums as fields Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! The equals and hashCode methods cannot be overwritten in Enums. It was only applied to classed which are used as value objects and potentially are used in Sets or other context which involve usage of equals or hashCode --- .../dao/governance/asset/RemovedAsset.java | 21 ++++++++++- .../proposal/param/ChangeParamProposal.java | 22 ++++++++++- .../core/dao/governance/role/BondedRole.java | 7 ++-- .../governance/role/BondedRolesService.java | 3 ++ .../java/bisq/core/dao/node/json/JsonTx.java | 28 ++++++++++++++ .../bisq/core/dao/node/json/JsonTxOutput.java | 37 +++++++++++++++++++ .../dao/state/blockchain/PubKeyScript.java | 22 +++++++++++ .../core/dao/state/blockchain/TempTx.java | 25 ++++++++++++- .../dao/state/blockchain/TempTxOutput.java | 23 +++++++++++- .../bisq/core/dao/state/blockchain/Tx.java | 25 ++++++++++++- .../core/dao/state/blockchain/TxOutput.java | 22 ++++++++++- .../core/dao/state/governance/Issuance.java | 21 +++++++++++ .../bisq/core/dao/state/period/DaoPhase.java | 19 ++++++++++ 13 files changed, 261 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/bisq/core/dao/governance/asset/RemovedAsset.java b/core/src/main/java/bisq/core/dao/governance/asset/RemovedAsset.java index 908b2adb083..122693c2b59 100644 --- a/core/src/main/java/bisq/core/dao/governance/asset/RemovedAsset.java +++ b/core/src/main/java/bisq/core/dao/governance/asset/RemovedAsset.java @@ -22,6 +22,8 @@ import io.bisq.generated.protobuffer.PB; +import java.util.Objects; + import lombok.Value; @Value @@ -29,7 +31,7 @@ public class RemovedAsset implements PersistablePayload { private final String tickerSymbol; private final RemoveReason removeReason; - public RemovedAsset(String tickerSymbol, RemoveReason removeReason) { + RemovedAsset(String tickerSymbol, RemoveReason removeReason) { this.tickerSymbol = tickerSymbol; this.removeReason = removeReason; } @@ -50,4 +52,21 @@ public static RemovedAsset fromProto(PB.RemovedAsset proto) { return new RemovedAsset(proto.getTickerSymbol(), ProtoUtil.enumFromProto(RemoveReason.class, proto.getRemoveReason())); } + + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof RemovedAsset)) return false; + if (!super.equals(o)) return false; + RemovedAsset that = (RemovedAsset) o; + return Objects.equals(tickerSymbol, that.tickerSymbol) && + removeReason.name().equals(that.removeReason.name()); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), tickerSymbol, removeReason.name()); + } } diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java index 1db2ee642d2..74483113046 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java @@ -27,8 +27,8 @@ import io.bisq.generated.protobuffer.PB; import java.util.Date; +import java.util.Objects; -import lombok.EqualsAndHashCode; import lombok.Value; import lombok.extern.slf4j.Slf4j; @@ -36,7 +36,6 @@ @Immutable @Slf4j -@EqualsAndHashCode(callSuper = true) @Value public final class ChangeParamProposal extends Proposal { private final Param param; @@ -139,4 +138,23 @@ public String toString() { ",\n paramValue=" + paramValue + "\n} " + super.toString(); } + + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ChangeParamProposal)) return false; + if (!super.equals(o)) return false; + ChangeParamProposal that = (ChangeParamProposal) o; + boolean paramTypeNameIsEquals = param.getParamType().name().equals(that.param.getParamType().name()); + boolean paramNameIsEquals = param.name().equals(that.param.name()); + return paramNameIsEquals && paramTypeNameIsEquals && + Objects.equals(paramValue, that.paramValue); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), param.getParamType().name(), param.name(), paramValue); + } } diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java index 64ffeede2eb..7aca0360adf 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java +++ b/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java @@ -67,7 +67,7 @@ public final class BondedRole implements PersistablePayload, NetworkPayload, Bon /** * @param name Full name or nickname - * @param link Github account or forum account of user + * @param link Github account or forum account of user * @param bondedRoleType BondedRoleType */ public BondedRole(String name, @@ -158,7 +158,7 @@ public byte[] getHash() { /////////////////////////////////////////////////////////////////////////////////////////// public String getDisplayString() { - return name + " / " + Res.get("dao.bond.bondedRoleType." + bondedRoleType.name()); + return Res.get("dao.bond.bondedRoleType." + bondedRoleType.name()) + ": " + name; } public boolean isLockedUp() { @@ -178,7 +178,8 @@ public boolean isUnlocking(DaoStateService daoStateService) { } // We use only the immutable data - // bondedRoleType must not be used directly for hashCode or equals as it delivers he Object.hashCode (internal address)! + // bondedRoleType must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java index d860dce654f..0c4004a0e1a 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java +++ b/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java @@ -39,6 +39,9 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; +/** + * Manages bonded roles if they got accepted by voting. + */ @Slf4j public class BondedRolesService implements PersistedDataHost, DaoStateListener { diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonTx.java b/core/src/main/java/bisq/core/dao/node/json/JsonTx.java index e68e74859ef..3bff69de155 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonTx.java +++ b/core/src/main/java/bisq/core/dao/node/json/JsonTx.java @@ -20,6 +20,7 @@ import bisq.common.app.Version; import java.util.List; +import java.util.Objects; import lombok.Value; @@ -37,4 +38,31 @@ class JsonTx { private final long burntFee; // If not set it is -1. LockTime of 0 is a valid value. private final int unlockBlockHeight; + + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof JsonTx)) return false; + if (!super.equals(o)) return false; + JsonTx jsonTx = (JsonTx) o; + return blockHeight == jsonTx.blockHeight && + time == jsonTx.time && + burntFee == jsonTx.burntFee && + unlockBlockHeight == jsonTx.unlockBlockHeight && + Objects.equals(txVersion, jsonTx.txVersion) && + Objects.equals(id, jsonTx.id) && + Objects.equals(blockHash, jsonTx.blockHash) && + Objects.equals(inputs, jsonTx.inputs) && + Objects.equals(outputs, jsonTx.outputs) && + txType.name().equals(jsonTx.txType.name()) && + Objects.equals(txTypeDisplayString, jsonTx.txTypeDisplayString); + } + + @Override + public int hashCode() { + + return Objects.hash(super.hashCode(), txVersion, id, blockHeight, blockHash, time, inputs, outputs, txType.name(), txTypeDisplayString, burntFee, unlockBlockHeight); + } } diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonTxOutput.java b/core/src/main/java/bisq/core/dao/node/json/JsonTxOutput.java index 03e56d0d796..ddbd9ac68e1 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonTxOutput.java +++ b/core/src/main/java/bisq/core/dao/node/json/JsonTxOutput.java @@ -19,6 +19,8 @@ import bisq.common.app.Version; +import java.util.Objects; + import lombok.Value; import javax.annotation.Nullable; @@ -51,4 +53,39 @@ class JsonTxOutput { String getId() { return txId + ":" + index; } + + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof JsonTxOutput)) return false; + if (!super.equals(o)) return false; + JsonTxOutput that = (JsonTxOutput) o; + return index == that.index && + bsqAmount == that.bsqAmount && + btcAmount == that.btcAmount && + height == that.height && + isVerified == that.isVerified && + burntFee == that.burntFee && + time == that.time && + lockTime == that.lockTime && + isUnspent == that.isUnspent && + Objects.equals(txVersion, that.txVersion) && + Objects.equals(txId, that.txId) && + Objects.equals(address, that.address) && + Objects.equals(scriptPubKey, that.scriptPubKey) && + Objects.equals(spentInfo, that.spentInfo) && + txType.name().equals(that.txType.name()) && + Objects.equals(txTypeDisplayString, that.txTypeDisplayString) && + txOutputType == that.txOutputType && + Objects.equals(txOutputTypeDisplayString, that.txOutputTypeDisplayString) && + Objects.equals(opReturn, that.opReturn); + } + + @Override + public int hashCode() { + + return Objects.hash(super.hashCode(), txVersion, txId, index, bsqAmount, btcAmount, height, isVerified, burntFee, address, scriptPubKey, spentInfo, time, txType.name(), txTypeDisplayString, txOutputType, txOutputTypeDisplayString, opReturn, lockTime, isUnspent); + } } diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java b/core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java index bc28ce375ce..23f672afe74 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableList; +import java.util.Objects; import java.util.Optional; import lombok.AllArgsConstructor; @@ -70,4 +71,25 @@ public static PubKeyScript fromProto(PB.PubKeyScript proto) { proto.getAsm(), proto.getHex()); } + + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof PubKeyScript)) return false; + if (!super.equals(o)) return false; + PubKeyScript that = (PubKeyScript) o; + return reqSigs == that.reqSigs && + scriptType.name().equals(that.scriptType.name()) && + Objects.equals(addresses, that.addresses) && + Objects.equals(asm, that.asm) && + Objects.equals(hex, that.hex); + } + + @Override + public int hashCode() { + + return Objects.hash(super.hashCode(), reqSigs, scriptType.name(), addresses, asm, hex); + } } diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TempTx.java b/core/src/main/java/bisq/core/dao/state/blockchain/TempTx.java index 5d2622c998e..a2282f3fe6c 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TempTx.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/TempTx.java @@ -19,10 +19,10 @@ import com.google.common.collect.ImmutableList; +import java.util.Objects; import java.util.stream.Collectors; import lombok.Data; -import lombok.EqualsAndHashCode; import javax.annotation.Nullable; @@ -31,7 +31,6 @@ * After parsing it will get cloned to the immutable Tx. * We don't need to implement the ProtoBuffer methods as it is not persisted or sent over the wire. */ -@EqualsAndHashCode(callSuper = true) @Data public class TempTx extends BaseTx { public static TempTx fromRawTx(RawTx rawTx) { @@ -86,4 +85,26 @@ public String toString() { ",\n burntFee=" + burntFee + "\n} " + super.toString(); } + + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TempTx)) return false; + if (!super.equals(o)) return false; + TempTx tempTx = (TempTx) o; + + String name = txType != null ? txType.name() : ""; + String name1 = tempTx.txType != null ? tempTx.txType.name() : ""; + boolean isTxTypeEquals = name.equals(name1); + return burntFee == tempTx.burntFee && + Objects.equals(tempTxOutputs, tempTx.tempTxOutputs) && + isTxTypeEquals; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), tempTxOutputs, txType, burntFee); + } } diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TempTxOutput.java b/core/src/main/java/bisq/core/dao/state/blockchain/TempTxOutput.java index 2f8e8c7bc7f..85f3c380772 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TempTxOutput.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/TempTxOutput.java @@ -17,8 +17,9 @@ package bisq.core.dao.state.blockchain; +import java.util.Objects; + import lombok.Data; -import lombok.EqualsAndHashCode; import javax.annotation.Nullable; @@ -26,7 +27,6 @@ * Contains mutable BSQ specific data (TxOutputType) and used only during tx parsing. * Will get converted to immutable TxOutput after tx parsing is completed. */ -@EqualsAndHashCode(callSuper = true) @Data public class TempTxOutput extends BaseTxOutput { public static TempTxOutput fromRawTxOutput(RawTxOutput txOutput) { @@ -87,4 +87,23 @@ public boolean isOpReturnOutput() { // We do not check for pubKeyScript.scriptType.NULL_DATA because that is only set if dumpBlockchainData is true return getOpReturnData() != null; } + + + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TempTxOutput)) return false; + if (!super.equals(o)) return false; + TempTxOutput that = (TempTxOutput) o; + return lockTime == that.lockTime && + unlockBlockHeight == that.unlockBlockHeight && + txOutputType.name().equals(that.txOutputType.name()); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), txOutputType.name(), lockTime, unlockBlockHeight); + } } diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/Tx.java b/core/src/main/java/bisq/core/dao/state/blockchain/Tx.java index d7917e04279..0871253ff8b 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/Tx.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/Tx.java @@ -24,10 +24,10 @@ import com.google.common.collect.ImmutableList; import java.util.ArrayList; +import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -import lombok.EqualsAndHashCode; import lombok.Value; import javax.annotation.Nullable; @@ -36,7 +36,6 @@ * Immutable class for a Bsq transaction. * Gets persisted. */ -@EqualsAndHashCode(callSuper = true) @Value public final class Tx extends BaseTx implements PersistablePayload { // Created after parsing of a tx is completed. We store only the immutable tx in the block. @@ -150,4 +149,26 @@ public String toString() { "\n} " + super.toString(); } + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Tx)) return false; + if (!super.equals(o)) return false; + Tx tx = (Tx) o; + + String name = txType != null ? txType.name() : ""; + String name1 = tx.txType != null ? tx.txType.name() : ""; + boolean isTxTypeEquals = name.equals(name1); + + return burntFee == tx.burntFee && + Objects.equals(txOutputs, tx.txOutputs) && + isTxTypeEquals; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), txOutputs, txType, burntFee); + } } diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java b/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java index a38b66cfe1f..cd6e04ad577 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java @@ -21,8 +21,9 @@ import io.bisq.generated.protobuffer.PB; +import java.util.Objects; + import lombok.Data; -import lombok.EqualsAndHashCode; import javax.annotation.Nullable; @@ -32,7 +33,6 @@ * TempTxOutput get converted to immutable TxOutput after tx parsing is completed. * Gets persisted. */ -@EqualsAndHashCode(callSuper = true) @Data public class TxOutput extends BaseTxOutput implements PersistablePayload { public static TxOutput fromTempOutput(TempTxOutput tempTxOutput) { @@ -116,4 +116,22 @@ public String toString() { ",\n unlockBlockHeight=" + unlockBlockHeight + "\n} " + super.toString(); } + + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TxOutput)) return false; + if (!super.equals(o)) return false; + TxOutput txOutput = (TxOutput) o; + return lockTime == txOutput.lockTime && + unlockBlockHeight == txOutput.unlockBlockHeight && + txOutputType.name().equals(txOutput.txOutputType.name()); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), txOutputType.name(), lockTime, unlockBlockHeight); + } } diff --git a/core/src/main/java/bisq/core/dao/state/governance/Issuance.java b/core/src/main/java/bisq/core/dao/state/governance/Issuance.java index 2d9b1d5d659..4fed7f7afe6 100644 --- a/core/src/main/java/bisq/core/dao/state/governance/Issuance.java +++ b/core/src/main/java/bisq/core/dao/state/governance/Issuance.java @@ -23,6 +23,7 @@ import io.bisq.generated.protobuffer.PB; +import java.util.Objects; import java.util.Optional; import lombok.Value; @@ -89,4 +90,24 @@ public String toString() { ",\n issuanceType='" + issuanceType + '\'' + "\n}"; } + + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Issuance)) return false; + if (!super.equals(o)) return false; + Issuance issuance = (Issuance) o; + return chainHeight == issuance.chainHeight && + amount == issuance.amount && + Objects.equals(txId, issuance.txId) && + Objects.equals(pubKey, issuance.pubKey) && + issuanceType.name().equals(issuance.issuanceType.name()); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), txId, chainHeight, amount, pubKey, issuanceType.name()); + } } diff --git a/core/src/main/java/bisq/core/dao/state/period/DaoPhase.java b/core/src/main/java/bisq/core/dao/state/period/DaoPhase.java index cf564cecc83..c81d3c5958e 100644 --- a/core/src/main/java/bisq/core/dao/state/period/DaoPhase.java +++ b/core/src/main/java/bisq/core/dao/state/period/DaoPhase.java @@ -21,6 +21,8 @@ import io.bisq.generated.protobuffer.PB; +import java.util.Objects; + import lombok.Value; import javax.annotation.concurrent.Immutable; @@ -83,4 +85,21 @@ public String toString() { ",\n duration=" + duration + "\n}"; } + + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof DaoPhase)) return false; + if (!super.equals(o)) return false; + DaoPhase daoPhase = (DaoPhase) o; + return duration == daoPhase.duration && + phase.name().equals(daoPhase.phase.name()); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), phase.name(), duration); + } } From dbddb46bf669e613a5ebf9270e8b296dea3b20c2 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 13:58:49 -0500 Subject: [PATCH 04/27] Remove BondedRoleList - We store the bonded roles in the evaluated proposals in the dao state. From there we can get the bonded role object as it is part of the bonded role proposal. Though we need to take that data immutable (next commit will handle that) --- common/src/main/proto/pb.proto | 11 +-- .../core/app/misc/AppSetupWithP2PAndDAO.java | 3 - .../main/java/bisq/core/dao/DaoFacade.java | 4 +- .../dao/governance/role/BondedRoleList.java | 76 ----------------- .../governance/role/BondedRolesService.java | 82 ++++++------------- .../voteresult/VoteResultService.java | 1 - .../CorePersistenceProtoResolver.java | 3 - .../core/setup/CorePersistedDataHost.java | 2 - .../main/dao/governance/ProposalDisplay.java | 2 +- 9 files changed, 29 insertions(+), 155 deletions(-) delete mode 100644 core/src/main/java/bisq/core/dao/governance/role/BondedRoleList.java diff --git a/common/src/main/proto/pb.proto b/common/src/main/proto/pb.proto index b8332104908..6d7ddc2e4a4 100644 --- a/common/src/main/proto/pb.proto +++ b/common/src/main/proto/pb.proto @@ -941,10 +941,9 @@ message PersistableEnvelope { MyVoteList my_vote_list = 21; MyBlindVoteList my_blind_vote_list = 22; MeritList merit_list = 23; - BondedRoleList bonded_role_list = 24; - RemovedAssetList removed_asset_list = 25; - DaoStateStore dao_state_store = 26; - BondedReputationList bonded_reputation_list = 27; + RemovedAssetList removed_asset_list = 24; + DaoStateStore dao_state_store = 25; + BondedReputationList bonded_reputation_list = 26; } } @@ -1551,10 +1550,6 @@ message BondedRole { string unlock_tx_id = 8; } -message BondedRoleList { - repeated BondedRole bonded_role = 1; -} - message BondedReputation { string salt = 1; string lockup_tx_id = 2; diff --git a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java index 72ebc9b7949..282c4fa1a75 100644 --- a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java +++ b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java @@ -25,7 +25,6 @@ import bisq.core.dao.governance.blindvote.MyBlindVoteListService; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.proposal.MyProposalListService; -import bisq.core.dao.governance.role.BondedRolesService; import bisq.core.filter.FilterManager; import bisq.core.payment.AccountAgeWitnessService; import bisq.core.trade.statistics.TradeStatisticsManager; @@ -56,7 +55,6 @@ public AppSetupWithP2PAndDAO(EncryptionService encryptionService, BallotListService ballotListService, MyBlindVoteListService myBlindVoteListService, MyProposalListService myProposalListService, - BondedRolesService bondedRolesService, BondedReputationService bondedReputationService, AssetService assetService, @Named(DaoOptionKeys.DAO_ACTIVATED) boolean daoActivated) { @@ -75,7 +73,6 @@ public AppSetupWithP2PAndDAO(EncryptionService encryptionService, persistedDataHosts.add(ballotListService); persistedDataHosts.add(myBlindVoteListService); persistedDataHosts.add(myProposalListService); - persistedDataHosts.add(bondedRolesService); persistedDataHosts.add(bondedReputationService); persistedDataHosts.add(assetService); } diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index 98ae2d52056..14821d54150 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -510,8 +510,8 @@ public Optional getLockTime(String txId) { return daoStateService.getLockTime(txId); } - public List getValidBondedRoleList() { - return bondedRolesService.getValidBondedRoleList(); + public List getActiveBondedRoles() { + return bondedRolesService.getActiveBondedRoles(); } /*public List getValidBondedReputationList() { diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRoleList.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRoleList.java deleted file mode 100644 index e08885b4bbf..00000000000 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRoleList.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.core.dao.governance.role; - -import bisq.core.dao.governance.ConsensusCritical; - -import bisq.common.proto.persistable.PersistableList; - -import io.bisq.generated.protobuffer.PB; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import lombok.EqualsAndHashCode; - -/** - * PersistableEnvelope wrapper for list of bondedRoles. - */ -@EqualsAndHashCode(callSuper = true) -public class BondedRoleList extends PersistableList implements ConsensusCritical { - - public BondedRoleList(List list) { - super(list); - } - - public BondedRoleList() { - super(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public PB.PersistableEnvelope toProtoMessage() { - return PB.PersistableEnvelope.newBuilder().setBondedRoleList(getBuilder()).build(); - } - - public PB.BondedRoleList.Builder getBuilder() { - return PB.BondedRoleList.newBuilder() - .addAllBondedRole(getList().stream() - .map(BondedRole::toProtoMessage) - .collect(Collectors.toList())); - } - - public static BondedRoleList fromProto(PB.BondedRoleList proto) { - return new BondedRoleList(new ArrayList<>(proto.getBondedRoleList().stream() - .map(BondedRole::fromProto) - .collect(Collectors.toList()))); - } - - @Override - public String toString() { - return "List of lockupTxIds in BondedRoleList: " + getList().stream() - .map(BondedRole::getLockupTxId) - .collect(Collectors.toList()); - } -} - diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java index 0c4004a0e1a..890f1719dad 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java +++ b/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java @@ -17,8 +17,8 @@ package bisq.core.dao.governance.role; -import bisq.core.app.BisqEnvironment; import bisq.core.dao.bonding.BondingConsensus; +import bisq.core.dao.governance.proposal.role.BondedRoleProposal; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.BaseTxOutput; @@ -26,35 +26,23 @@ import bisq.core.dao.state.blockchain.SpentInfo; import bisq.core.dao.state.blockchain.TxType; -import bisq.common.proto.persistable.PersistedDataHost; -import bisq.common.storage.Storage; - import javax.inject.Inject; import java.util.Arrays; import java.util.List; import java.util.Optional; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; +import java.util.stream.Stream; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; /** * Manages bonded roles if they got accepted by voting. */ @Slf4j -public class BondedRolesService implements PersistedDataHost, DaoStateListener { - - public interface BondedRoleListChangeListener { - void onListChanged(List list); - } - +public class BondedRolesService implements DaoStateListener { private final DaoStateService daoStateService; - private final Storage storage; - private final BondedRoleList bondedRoleList = new BondedRoleList(); - @Getter - private final List listeners = new CopyOnWriteArrayList<>(); /////////////////////////////////////////////////////////////////////////////////////////// @@ -62,30 +50,13 @@ public interface BondedRoleListChangeListener { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public BondedRolesService(Storage storage, DaoStateService daoStateService) { - this.storage = storage; + public BondedRolesService(DaoStateService daoStateService) { this.daoStateService = daoStateService; daoStateService.addBsqStateListener(this); } - /////////////////////////////////////////////////////////////////////////////////////////// - // PersistedDataHost - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void readPersisted() { - if (BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq()) { - BondedRoleList persisted = storage.initAndGetPersisted(bondedRoleList, 100); - if (persisted != null) { - bondedRoleList.clear(); - bondedRoleList.addAll(persisted.getList()); - listeners.forEach(l -> l.onListChanged(bondedRoleList.getList())); - } - } - } - /////////////////////////////////////////////////////////////////////////////////////////// // DaoStateListener /////////////////////////////////////////////////////////////////////////////////////////// @@ -96,8 +67,7 @@ public void onNewBlockHeight(int blockHeight) { @Override public void onParseTxsComplete(Block block) { - bondedRoleList.getList().forEach(bondedRole -> { - + getBondedRoleStream().forEach(bondedRole -> { daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> { String lockupTxId = lockupTxOutput.getTxId(); // log.error("lockupTxId " + lockupTxId); @@ -112,7 +82,6 @@ public void onParseTxsComplete(Block block) { bondedRole.setLockupTxId(lockupTxId); // We use the tx time as we want to have a unique time for all users bondedRole.setStartDate(lockupTx.getTime()); - persist(); } if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { @@ -125,7 +94,6 @@ public void onParseTxsComplete(Block block) { if (bondedRole.getUnlockTxId() == null) { bondedRole.setUnlockTxId(unlockTx.getId()); bondedRole.setRevokeDate(unlockTx.getTime()); - persist(); } // TODO check lock time @@ -137,6 +105,7 @@ public void onParseTxsComplete(Block block) { }); } + @Override public void onParseBlockChainComplete() { } @@ -149,28 +118,19 @@ public void onParseBlockChainComplete() { public void start() { } - public void addListener(BondedRoleListChangeListener listener) { - listeners.add(listener); - } - - public void addAcceptedBondedRole(BondedRole bondedRole) { - if (bondedRoleList.getList().stream().noneMatch(role -> role.equals(bondedRole))) { - bondedRoleList.add(bondedRole); - persist(); - listeners.forEach(l -> l.onListChanged(bondedRoleList.getList())); - } - } public List getBondedRoleList() { - return bondedRoleList.getList(); + return getBondedRoleStream().collect(Collectors.toList()); } - public List getValidBondedRoleList() { - return bondedRoleList.getList(); + // bonded roles which are active and can be confiscated + public List getActiveBondedRoles() { + //TODO + return getBondedRoleList(); } public Optional getBondedRoleFromHash(byte[] hash) { - return bondedRoleList.getList().stream() + return getBondedRoleStream() .filter(bondedRole -> { byte[] candidateHash = bondedRole.getHash(); /* log.error("getBondedRoleFromHash: equals?={}, hash={}, candidateHash={}\nbondedRole={}", @@ -184,15 +144,14 @@ public Optional getBondedRoleFromHash(byte[] hash) { } public Optional getBondedRoleFromLockupTxId(String lockupTxId) { - return bondedRoleList.getList().stream() + return getBondedRoleStream() .filter(bondedRole -> lockupTxId.equals(bondedRole.getLockupTxId())) .findAny(); } public Optional getBondedRoleType(String lockUpTxId) { - Optional bondedRoleType = getBondedRoleFromLockupTxId(lockUpTxId).map(BondedRole::getBondedRoleType); - return bondedRoleType; + return getBondedRoleFromLockupTxId(lockUpTxId).map(BondedRole::getBondedRoleType); } @@ -200,13 +159,18 @@ public Optional getBondedRoleType(String lockUpTxId) { // Private /////////////////////////////////////////////////////////////////////////////////////////// + + private Stream getBondedRoleStream() { + return daoStateService.getEvaluatedProposalList().stream() + .filter(evaluatedProposal -> evaluatedProposal.getProposal() instanceof BondedRoleProposal) + .map(e -> ((BondedRoleProposal) e.getProposal()).getBondedRole()); + } + + private Optional getOpReturnData(String lockUpTxId) { return daoStateService.getLockupOpReturnTxOutput(lockUpTxId).map(BaseTxOutput::getOpReturnData); } - private void persist() { - storage.queueUpForSave(20); - } /* private Optional getOptionalLockupType(String lockUpTxId) { return getOpReturnData(lockUpTxId) diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java index 2f2c2302566..a2bdea95bfa 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java @@ -644,7 +644,6 @@ private void applyBondedRole(Set acceptedEvaluatedProposals, if (evaluatedProposal.getProposal() instanceof BondedRoleProposal) { BondedRoleProposal bondedRoleProposal = (BondedRoleProposal) evaluatedProposal.getProposal(); BondedRole bondedRole = bondedRoleProposal.getBondedRole(); - bondedRolesService.addAcceptedBondedRole(bondedRole); StringBuilder sb = new StringBuilder(); sb.append("\n################################################################################\n"); sb.append("We added a bonded role. ProposalTxId=").append(bondedRoleProposal.getTxId()) diff --git a/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java b/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java index b70ec2b3d8f..bc930b806d4 100644 --- a/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java +++ b/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java @@ -29,7 +29,6 @@ import bisq.core.dao.governance.proposal.MyProposalList; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStore; import bisq.core.dao.governance.proposal.storage.temp.TempProposalStore; -import bisq.core.dao.governance.role.BondedRoleList; import bisq.core.dao.state.DaoStateStore; import bisq.core.payment.AccountAgeWitnessStore; import bisq.core.payment.PaymentAccountList; @@ -129,8 +128,6 @@ public PersistableEnvelope fromProto(PB.PersistableEnvelope proto) { return MyBlindVoteList.fromProto(proto.getMyBlindVoteList()); case MERIT_LIST: return MeritList.fromProto(proto.getMeritList()); - case BONDED_ROLE_LIST: - return BondedRoleList.fromProto(proto.getBondedRoleList()); case REMOVED_ASSET_LIST: return RemovedAssetsList.fromProto(proto.getRemovedAssetList()); case DAO_STATE_STORE: diff --git a/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java b/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java index 521c9eb9e94..7c118311589 100644 --- a/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java +++ b/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java @@ -26,7 +26,6 @@ import bisq.core.dao.governance.blindvote.MyBlindVoteListService; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.proposal.MyProposalListService; -import bisq.core.dao.governance.role.BondedRolesService; import bisq.core.offer.OpenOfferManager; import bisq.core.trade.TradeManager; import bisq.core.trade.closed.ClosedTradableManager; @@ -68,7 +67,6 @@ public static List getPersistedDataHosts(Injector injector) { persistedDataHosts.add(injector.getInstance(MyBlindVoteListService.class)); persistedDataHosts.add(injector.getInstance(MyVoteListService.class)); persistedDataHosts.add(injector.getInstance(MyProposalListService.class)); - persistedDataHosts.add(injector.getInstance(BondedRolesService.class)); persistedDataHosts.add(injector.getInstance(BondedReputationService.class)); persistedDataHosts.add(injector.getInstance(AssetService.class)); } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java index fdf2cef13a1..5713d0f3c72 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java @@ -303,7 +303,7 @@ public BondedRoleType fromString(String string) { Res.get("dao.proposal.display.confiscateBondComboBox.label")); comboBoxValueTextFieldIndex = gridRow; checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); - confiscateBondComboBox.setItems(FXCollections.observableArrayList(daoFacade.getValidBondedRoleList())); + confiscateBondComboBox.setItems(FXCollections.observableArrayList(daoFacade.getActiveBondedRoles())); confiscateBondComboBox.setConverter(new StringConverter<>() { @Override public String toString(BondedRole bondedRole) { From e41be44e9c32a6edbf3a377999f5f37260fe0fa6 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 15:20:35 -0500 Subject: [PATCH 05/27] Remove mutable data from BondedRole Use BondedRoleState to hold the mutable data. Store the BondedRoleState in a local map. --- common/src/main/proto/pb.proto | 4 - .../main/java/bisq/core/dao/DaoFacade.java | 12 +- .../core/dao/bonding/bond/BondWithHash.java | 2 - .../dao/bonding/bond/BondedReputation.java | 17 ++- .../dao/bonding/lockup/LockupService.java | 23 ++-- .../core/dao/governance/role/BondedRole.java | 85 ++------------ .../dao/governance/role/BondedRoleState.java | 59 ++++++++++ .../governance/role/BondedRolesService.java | 107 ++++++++++++------ .../bisq/core/dao/state/DaoStateService.java | 7 +- .../desktop/components/HyperlinkWithIcon.java | 2 +- .../main/dao/bonding/lockup/LockupView.java | 26 +++-- .../bonding/roles/BondedRolesListItem.java | 26 +++-- .../dao/bonding/roles/BondedRolesView.java | 10 +- .../dao/bonding/unlock/LockupTxListItem.java | 8 +- 14 files changed, 211 insertions(+), 177 deletions(-) create mode 100644 core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java diff --git a/common/src/main/proto/pb.proto b/common/src/main/proto/pb.proto index 6d7ddc2e4a4..ad1310e0d85 100644 --- a/common/src/main/proto/pb.proto +++ b/common/src/main/proto/pb.proto @@ -1544,10 +1544,6 @@ message BondedRole { string name = 2; string link = 3; string bonded_role_type = 4; // name of BondedRoleType enum - uint64 start_date = 5; - string lockup_tx_id = 6; - uint64 revoke_date = 7; - string unlock_tx_id = 8; } message BondedReputation { diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index 14821d54150..f6ddeb296d6 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -50,6 +50,7 @@ import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalService; import bisq.core.dao.governance.proposal.role.BondedRoleProposalService; import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.BondedRoleState; import bisq.core.dao.governance.role.BondedRolesService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; @@ -84,6 +85,7 @@ import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; +import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.Set; @@ -279,8 +281,8 @@ public ProposalWithTransaction getRemoveAssetProposalWithTransaction(String name return removeAssetProposalService.createProposalWithTransaction(name, link, asset); } - public List getBondedRoleList() { - return bondedRolesService.getBondedRoleList(); + public Collection getBondedRoleStates() { + return bondedRolesService.getBondedRoleStates(); } public List getBondedReputationList() { @@ -627,9 +629,9 @@ public Optional getBondedReputationFromHash(byte[] hash) { return bondedReputationService.getBondedReputationFromHash(hash); } - public boolean isUnlocking(BondWithHash bondWithHash) { - return daoStateService.isUnlocking(bondWithHash); - } + /*public boolean isUnlocking(String unlockTxId) { + return daoStateService.isUnlocking(unlockTxId); + }*/ public Coin getMinCompensationRequestAmount() { return CompensationConsensus.getMinCompensationRequestAmount(daoStateService, periodService.getChainHeight()); diff --git a/core/src/main/java/bisq/core/dao/bonding/bond/BondWithHash.java b/core/src/main/java/bisq/core/dao/bonding/bond/BondWithHash.java index 3419e7dc7e2..27d08273e8e 100644 --- a/core/src/main/java/bisq/core/dao/bonding/bond/BondWithHash.java +++ b/core/src/main/java/bisq/core/dao/bonding/bond/BondWithHash.java @@ -18,7 +18,5 @@ package bisq.core.dao.bonding.bond; public interface BondWithHash { - - String getUnlockTxId(); byte[] getHash(); } diff --git a/core/src/main/java/bisq/core/dao/bonding/bond/BondedReputation.java b/core/src/main/java/bisq/core/dao/bonding/bond/BondedReputation.java index 3ffc41cb949..1134c00e1eb 100644 --- a/core/src/main/java/bisq/core/dao/bonding/bond/BondedReputation.java +++ b/core/src/main/java/bisq/core/dao/bonding/bond/BondedReputation.java @@ -17,8 +17,6 @@ package bisq.core.dao.bonding.bond; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.DaoStateService; import bisq.core.locale.Res; import bisq.common.crypto.Hash; @@ -38,6 +36,7 @@ import javax.annotation.Nullable; +//TODO shoudld be immutable? @Getter public final class BondedReputation implements PersistablePayload, NetworkPayload, BondWithHash { private final String salt; @@ -92,11 +91,11 @@ public static BondedReputation fromProto(PB.BondedReputation proto) { /////////////////////////////////////////////////////////////////////////////////////////// // API /////////////////////////////////////////////////////////////////////////////////////////// - +/* @Override public String getUnlockTxId() { return unlockTxId; - } + }*/ @Override public byte[] getHash() { @@ -118,13 +117,13 @@ public boolean isUnlocked() { return unlockTxId != null; } - public boolean isUnlocking(DaoFacade daoFacade) { - return daoFacade.isUnlocking(this); - } + /* public boolean isUnlocking(DaoFacade daoFacade) { + return daoFacade.isUnlocking(unlockTxId); + }*/ - public boolean isUnlocking(DaoStateService daoStateService) { + /* public boolean isUnlocking(DaoStateService daoStateService) { return daoStateService.isUnlocking(this); - } + }*/ // We use only the immutable data @Override diff --git a/core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java b/core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java index d8e5cbb543e..ba87db7d75b 100644 --- a/core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java +++ b/core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java @@ -50,6 +50,7 @@ public class LockupService { private final WalletsManager walletsManager; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; + private final BondedRolesService bondedRolesService; /////////////////////////////////////////////////////////////////////////////////////////// @@ -64,12 +65,22 @@ public LockupService(WalletsManager walletsManager, this.walletsManager = walletsManager; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; + this.bondedRolesService = bondedRolesService; } public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, BondWithHash bondWithHash, ResultHandler resultHandler, ExceptionHandler exceptionHandler) { checkArgument(lockTime <= BondingConsensus.getMaxLockTime() && lockTime >= BondingConsensus.getMinLockTime(), "lockTime not in rage"); + + if (bondWithHash instanceof BondedRole) { + BondedRole bondedRole = (BondedRole) bondWithHash; + if (bondedRolesService.wasRoleAlreadyBonded(bondedRole)) { + exceptionHandler.handleException(new RuntimeException("The role has been used already for a lockup tx.")); + return; + } + } + try { byte[] hash = BondingConsensus.getHash(bondWithHash); @@ -80,14 +91,6 @@ public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupTy walletsManager.publishAndCommitBsqTx(lockupTx, new TxBroadcaster.Callback() { @Override public void onSuccess(Transaction transaction) { - - // TODO we should not support repeated locks - if (bondWithHash instanceof BondedRole) { - BondedRole bondedRole = (BondedRole) bondWithHash; - bondedRole.setLockupTxId(transaction.getHashAsString()); - bondedRole.setUnlockTxId(null); - } - resultHandler.handleResult(); } @@ -112,8 +115,6 @@ private Transaction getLockupTx(Coin lockupAmount, byte[] opReturnData) throws InsufficientMoneyException, WalletException, TransactionVerificationException { Transaction preparedTx = bsqWalletService.getPreparedLockupTx(lockupAmount); Transaction txWithBtcFee = btcWalletService.completePreparedBsqTx(preparedTx, true, opReturnData); - final Transaction transaction = bsqWalletService.signTx(txWithBtcFee); - log.info("Lockup tx: " + transaction); - return transaction; + return bsqWalletService.signTx(txWithBtcFee); } } diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java index 7aca0360adf..a2b967a7d24 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java +++ b/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java @@ -17,9 +17,7 @@ package bisq.core.dao.governance.role; -import bisq.core.dao.DaoFacade; import bisq.core.dao.bonding.bond.BondWithHash; -import bisq.core.dao.state.DaoStateService; import bisq.core.locale.Res; import bisq.common.crypto.Hash; @@ -32,39 +30,22 @@ import java.math.BigInteger; import java.util.Objects; -import java.util.Optional; import java.util.UUID; -import lombok.Getter; -import lombok.Setter; +import lombok.Value; import lombok.extern.slf4j.Slf4j; -import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +@Immutable @Slf4j -@Getter +@Value public final class BondedRole implements PersistablePayload, NetworkPayload, BondWithHash { private final String uid; private final String name; private final String link; private final BondedRoleType bondedRoleType; - @Setter - private long startDate; - - // LockupTxId is null as long the bond holder has not been accepted by voting and made the lockup tx. - // It will get set after the proposal has been accepted and the lockup tx is confirmed. - @Nullable - @Setter - private String lockupTxId; - - // Date when role has been revoked - @Setter - private long revokeDate; - @Nullable - @Setter - private String unlockTxId; - /** * @param name Full name or nickname * @param link Github account or forum account of user @@ -76,11 +57,7 @@ public BondedRole(String name, this(UUID.randomUUID().toString(), name, link, - bondedRoleType, - 0, - null, - 0, - null + bondedRoleType ); } @@ -92,19 +69,11 @@ public BondedRole(String name, public BondedRole(String uid, String name, String link, - BondedRoleType bondedRoleType, - long startDate, - @Nullable String lockupTxId, - long revokeDate, - @Nullable String unlockTxId) { + BondedRoleType bondedRoleType) { this.uid = uid; this.name = name; this.link = link; this.bondedRoleType = bondedRoleType; - this.startDate = startDate; - this.lockupTxId = lockupTxId; - this.revokeDate = revokeDate; - this.unlockTxId = unlockTxId; } @Override @@ -113,11 +82,7 @@ public PB.BondedRole toProtoMessage() { .setUid(uid) .setName(name) .setLink(link) - .setBondedRoleType(bondedRoleType.name()) - .setStartDate(startDate) - .setRevokeDate(revokeDate); - Optional.ofNullable(lockupTxId).ifPresent(builder::setLockupTxId); - Optional.ofNullable(unlockTxId).ifPresent(builder::setUnlockTxId); + .setBondedRoleType(bondedRoleType.name()); return builder.build(); } @@ -125,11 +90,7 @@ public static BondedRole fromProto(PB.BondedRole proto) { return new BondedRole(proto.getUid(), proto.getName(), proto.getLink(), - ProtoUtil.enumFromProto(BondedRoleType.class, proto.getBondedRoleType()), - proto.getStartDate(), - proto.getLockupTxId().isEmpty() ? null : proto.getLockupTxId(), - proto.getRevokeDate(), - proto.getUnlockTxId().isEmpty() ? null : proto.getUnlockTxId()); + ProtoUtil.enumFromProto(BondedRoleType.class, proto.getBondedRoleType())); } @@ -137,19 +98,11 @@ public static BondedRole fromProto(PB.BondedRole proto) { // BondWithHash implementation /////////////////////////////////////////////////////////////////////////////////////////// - @Override - public String getUnlockTxId() { - return unlockTxId; - } - @Override public byte[] getHash() { // We use only the immutable data as input for hash byte[] bytes = BigInteger.valueOf(hashCode()).toByteArray(); - byte[] hash = Hash.getSha256Ripemd160hash(bytes); - /* log.error("BondedRole.getHash: hash={}, bytes={}\nbondedRole={}", Utilities.bytesAsHexString(hash), - Utilities.bytesAsHexString(bytes), toString());*/ - return hash; + return Hash.getSha256Ripemd160hash(bytes); } @@ -161,22 +114,6 @@ public String getDisplayString() { return Res.get("dao.bond.bondedRoleType." + bondedRoleType.name()) + ": " + name; } - public boolean isLockedUp() { - return lockupTxId != null; - } - - public boolean isUnlocked() { - return unlockTxId != null; - } - - public boolean isUnlocking(DaoFacade daoFacade) { - return daoFacade.isUnlocking(this); - } - - public boolean isUnlocking(DaoStateService daoStateService) { - return daoStateService.isUnlocking(this); - } - // We use only the immutable data // bondedRoleType must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! // The equals and hashCode methods cannot be overwritten in Enums. @@ -203,10 +140,6 @@ public String toString() { ",\n name='" + name + '\'' + ",\n link='" + link + '\'' + ",\n bondedRoleType=" + bondedRoleType + - ",\n startDate=" + startDate + - ",\n lockupTxId='" + lockupTxId + '\'' + - ",\n revokeDate=" + revokeDate + - ",\n unlockTxId='" + unlockTxId + '\'' + "\n}"; } } diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java new file mode 100644 index 00000000000..91680dae5d0 --- /dev/null +++ b/core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java @@ -0,0 +1,59 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.governance.role; + +import lombok.Getter; +import lombok.Setter; + +import javax.annotation.Nullable; + +/** + * Mutable state of a bonded role. Only kept in memory. + */ +@Getter +public class BondedRoleState { + private final BondedRole bondedRole; + + @Setter + private long startDate; + // LockupTxId is null as long the bond holder has not been accepted by voting and made the lockup tx. + // It will get set after the proposal has been accepted and the lockup tx is confirmed. + @Setter + @Nullable + private String lockupTxId; + // Date when role has been revoked + @Setter + private long revokeDate; + @Setter + @Nullable + private String unlockTxId; + @Setter + private boolean isUnlocking; + + BondedRoleState(BondedRole bondedRole) { + this.bondedRole = bondedRole; + } + + public boolean isLockedUp() { + return lockupTxId != null; + } + + public boolean isUnlocked() { + return unlockTxId != null; + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java index 890f1719dad..38f47b687a8 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java +++ b/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java @@ -29,13 +29,18 @@ import javax.inject.Inject; import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; +import static com.google.common.base.Preconditions.checkArgument; + /** * Manages bonded roles if they got accepted by voting. */ @@ -43,6 +48,8 @@ public class BondedRolesService implements DaoStateListener { private final DaoStateService daoStateService; + // This map is just for convenience. The data which are used to fill the map are store din the DaoState (role, txs). + private final Map bondedRoleStateMap = new HashMap<>(); /////////////////////////////////////////////////////////////////////////////////////////// @@ -67,40 +74,63 @@ public void onNewBlockHeight(int blockHeight) { @Override public void onParseTxsComplete(Block block) { + // TODO optimize to not re-write the whole map at each block getBondedRoleStream().forEach(bondedRole -> { + bondedRoleStateMap.putIfAbsent(bondedRole.getUid(), new BondedRoleState(bondedRole)); + BondedRoleState bondedRoleState = bondedRoleStateMap.get(bondedRole.getUid()); + + // Lets see if we have a lock up tx. daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> { String lockupTxId = lockupTxOutput.getTxId(); // log.error("lockupTxId " + lockupTxId); - daoStateService.getTx(lockupTxId) - .ifPresent(lockupTx -> { - byte[] opReturnData = lockupTx.getLastTxOutput().getOpReturnData(); - byte[] hash = BondingConsensus.getHashFromOpReturnData(opReturnData); - Optional candidate = getBondedRoleFromHash(hash); - if (candidate.isPresent() && bondedRole.equals(candidate.get())) { - if (bondedRole.getLockupTxId() == null) { - bondedRole.setLockupTxId(lockupTxId); - // We use the tx time as we want to have a unique time for all users - bondedRole.setStartDate(lockupTx.getTime()); - } - - if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { - daoStateService.getSpentInfo(lockupTxOutput) - .map(SpentInfo::getTxId) - .map(daoStateService::getTx) - .map(Optional::get) - .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) - .ifPresent(unlockTx -> { - if (bondedRole.getUnlockTxId() == null) { - bondedRole.setUnlockTxId(unlockTx.getId()); - bondedRole.setRevokeDate(unlockTx.getTime()); - } - - // TODO check lock time - }); - } - } - }); + daoStateService.getTx(lockupTxId).ifPresent(lockupTx -> { + byte[] opReturnData = lockupTx.getLastTxOutput().getOpReturnData(); + + // We used the hash of th bonded role object as our hash in OpReturn of the lock up tx to have a + // unique binding of the tx to the data object. + byte[] hash = BondingConsensus.getHashFromOpReturnData(opReturnData); + Optional candidate = getBondedRoleFromHash(hash); + if (candidate.isPresent() && bondedRole.equals(candidate.get())) { + if (bondedRoleState.getLockupTxId() == null) { + bondedRoleState.setLockupTxId(lockupTxId); + // We use the tx time as we want to have a unique time for all users + bondedRoleState.setStartDate(lockupTx.getTime()); + } else { + checkArgument(bondedRoleState.getLockupTxId().equals(lockupTxId), + "We have already the lockup tx set in bondedRoleState " + + "but it is different to the one we found in the daoState transactions. " + + "That should not happen. bondedRole={}, bondedRoleState={}", + bondedRole, bondedRoleState); + } + + if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { + // Lockup is already spent (in unlock tx) + daoStateService.getSpentInfo(lockupTxOutput) + .map(SpentInfo::getTxId) + .flatMap(daoStateService::getTx) + .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) + .ifPresent(unlockTx -> { + // cross check if it is in daoStateService.getUnlockTxOutputs() ? + String unlockTxId = unlockTx.getId(); + if (bondedRoleState.getUnlockTxId() == null) { + bondedRoleState.setUnlockTxId(unlockTxId); + bondedRoleState.setRevokeDate(unlockTx.getTime()); + bondedRoleState.setUnlocking(daoStateService.isUnlocking(unlockTxId)); + //TODO after locktime set to false or maybe better use states for lock state + } else { + checkArgument(bondedRoleState.getUnlockTxId().equals(unlockTxId), + "We have already the unlock tx set in bondedRoleState " + + "but it is different to the one we found in the daoState transactions. " + + "That should not happen. bondedRole={}, bondedRoleState={}", + bondedRole, bondedRoleState); + } + + // TODO check lock time + }); + } + } + }); }); }); } @@ -123,6 +153,10 @@ public List getBondedRoleList() { return getBondedRoleStream().collect(Collectors.toList()); } + public Collection getBondedRoleStates() { + return bondedRoleStateMap.values(); + } + // bonded roles which are active and can be confiscated public List getActiveBondedRoles() { //TODO @@ -143,15 +177,17 @@ public Optional getBondedRoleFromHash(byte[] hash) { .findAny(); } - public Optional getBondedRoleFromLockupTxId(String lockupTxId) { - return getBondedRoleStream() - .filter(bondedRole -> lockupTxId.equals(bondedRole.getLockupTxId())) + public Optional getBondedRoleStateFromLockupTxId(String lockupTxId) { + return bondedRoleStateMap.values().stream() + .filter(bondedRoleState -> lockupTxId.equals(bondedRoleState.getLockupTxId())) .findAny(); } public Optional getBondedRoleType(String lockUpTxId) { - return getBondedRoleFromLockupTxId(lockUpTxId).map(BondedRole::getBondedRoleType); + return getBondedRoleStateFromLockupTxId(lockUpTxId) + .map(BondedRoleState::getBondedRole) + .map(BondedRole::getBondedRoleType); } @@ -171,6 +207,11 @@ private Optional getOpReturnData(String lockUpTxId) { return daoStateService.getLockupOpReturnTxOutput(lockUpTxId).map(BaseTxOutput::getOpReturnData); } + public boolean wasRoleAlreadyBonded(BondedRole bondedRole) { + BondedRoleState bondedRoleState = bondedRoleStateMap.get(bondedRole.getUid()); + return bondedRoleState != null && bondedRoleState.getLockupTxId() != null; + } + /* private Optional getOptionalLockupType(String lockUpTxId) { return getOpReturnData(lockUpTxId) diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateService.java b/core/src/main/java/bisq/core/dao/state/DaoStateService.java index b6dd75b202e..f94ce0f2ae7 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateService.java @@ -19,7 +19,6 @@ import bisq.core.dao.DaoSetupService; import bisq.core.dao.bonding.BondingConsensus; -import bisq.core.dao.bonding.bond.BondWithHash; import bisq.core.dao.governance.voteresult.DecryptedBallotsWithMerits; import bisq.core.dao.governance.voteresult.EvaluatedProposal; import bisq.core.dao.state.blockchain.Block; @@ -647,7 +646,7 @@ public Optional getLockupTxOutput(String txId) { } public Optional getLockupOpReturnTxOutput(String txId) { - return getTx(txId).map(Tx::getLastTxOutput); + return getTx(txId).map(Tx::getLastTxOutput).filter(txOutput -> txOutput.getOpReturnData() != null); } // Returns amount of all LOCKUP txOutputs (they might have been unlocking or unlocked in the meantime) @@ -756,8 +755,8 @@ public void applyConfiscateBond(TxOutput txOutput) { // txOutput.setTxOutputType(TxOutputType.BTC_OUTPUT); } - public boolean isUnlocking(BondWithHash bondWithHash) { - Optional optionalTx = getTx(bondWithHash.getUnlockTxId()); + public boolean isUnlocking(String unlockTxId) { + Optional optionalTx = getTx(unlockTxId); return optionalTx.isPresent() && isUnlockingOutput(optionalTx.get().getTxOutputs().get(0)); } diff --git a/desktop/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java b/desktop/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java index be5e5004f33..61e597fa2fe 100644 --- a/desktop/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java +++ b/desktop/src/main/java/bisq/desktop/components/HyperlinkWithIcon.java @@ -52,7 +52,7 @@ public HyperlinkWithIcon(String text, AwesomeIcon awesomeIcon) { setGraphicTextGap(7.0); //TODO: replace workaround of setting the style this way - tooltipProperty().addListener((observable, oldValue, newValue) -> newValue.setStyle("-fx-text-fill: -bs-black")); + tooltipProperty().addListener((observable, oldValue, newValue) -> newValue.setStyle("-fx-text-fill: #000")); } public void clear() { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index 924493cbb08..91cd74e6384 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -33,6 +33,7 @@ import bisq.core.dao.bonding.BondingConsensus; import bisq.core.dao.bonding.lockup.LockupType; import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.BondedRoleState; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.validation.IntegerValidator; @@ -71,11 +72,11 @@ public class LockupView extends ActivatableView implements BsqBa private InputTextField amountInputTextField; private InputTextField timeInputTextField; private ComboBox lockupTypeComboBox; - private ComboBox bondedRolesComboBox; + private ComboBox bondedRolesComboBox; private Button lockupButton; private ChangeListener amountFocusOutListener, timeFocusOutListener; private ChangeListener amountInputTextFieldListener, timeInputTextFieldListener; - private ChangeListener bondedRolesListener; + private ChangeListener bondedRoleStateListener; private ChangeListener lockupTypeListener; private TitledGroupBg titledGroupBg; @@ -149,7 +150,7 @@ public LockupType fromString(String string) { bondedRolesComboBox.setVisible(true); lockupRows++; - bondedRolesComboBox.setItems(FXCollections.observableArrayList(daoFacade.getBondedRoleList())); + bondedRolesComboBox.setItems(FXCollections.observableArrayList(daoFacade.getBondedRoleStates())); } else { bondedRolesComboBox.setVisible(false); bondedRolesComboBox.getItems().clear(); @@ -164,19 +165,20 @@ public LockupType fromString(String string) { bondedRolesComboBox.setVisible(false); bondedRolesComboBox.setConverter(new StringConverter<>() { @Override - public String toString(BondedRole bondedRole) { - return bondedRole.getDisplayString(); + public String toString(BondedRoleState bondedRoleState) { + return bondedRoleState.getBondedRole().getDisplayString(); } @Override - public BondedRole fromString(String string) { + public BondedRoleState fromString(String string) { return null; } }); - bondedRolesListener = (observable, oldValue, newValue) -> { + bondedRoleStateListener = (observable, oldValue, newValue) -> { if (newValue != null) { - amountInputTextField.setText(bsqFormatter.formatCoin(Coin.valueOf(newValue.getBondedRoleType().getRequiredBond()))); - timeInputTextField.setText(String.valueOf(newValue.getBondedRoleType().getUnlockTimeInBlocks())); + BondedRole bondedRole = newValue.getBondedRole(); + amountInputTextField.setText(bsqFormatter.formatCoin(Coin.valueOf(bondedRole.getBondedRoleType().getRequiredBond()))); + timeInputTextField.setText(String.valueOf(bondedRole.getBondedRoleType().getUnlockTimeInBlocks())); amountInputTextField.resetValidation(); timeInputTextField.resetValidation(); amountInputTextField.setEditable(false); @@ -196,7 +198,7 @@ public BondedRole fromString(String string) { switch (lockupTypeComboBox.getValue()) { case BONDED_ROLE: if (bondedRolesComboBox.getValue() != null) { - bondingViewUtils.lockupBondForBondedRole(bondedRolesComboBox.getValue(), + bondingViewUtils.lockupBondForBondedRole(bondedRolesComboBox.getValue().getBondedRole(), () -> bondedRolesComboBox.getSelectionModel().clearSelection()); } break; @@ -238,7 +240,7 @@ protected void activate() { amountInputTextField.focusedProperty().addListener(amountFocusOutListener); timeInputTextField.focusedProperty().addListener(timeFocusOutListener); lockupTypeComboBox.getSelectionModel().selectedItemProperty().addListener(lockupTypeListener); - bondedRolesComboBox.getSelectionModel().selectedItemProperty().addListener(bondedRolesListener); + bondedRolesComboBox.getSelectionModel().selectedItemProperty().addListener(bondedRoleStateListener); bsqWalletService.addBsqBalanceListener(this); @@ -257,7 +259,7 @@ protected void deactivate() { amountInputTextField.focusedProperty().removeListener(amountFocusOutListener); timeInputTextField.focusedProperty().removeListener(timeFocusOutListener); lockupTypeComboBox.getSelectionModel().selectedItemProperty().removeListener(lockupTypeListener); - bondedRolesComboBox.getSelectionModel().selectedItemProperty().removeListener(bondedRolesListener); + bondedRolesComboBox.getSelectionModel().selectedItemProperty().removeListener(bondedRoleStateListener); bsqWalletService.removeBsqBalanceListener(this); } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java index 9a2916294fb..fc43579a155 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java @@ -21,6 +21,7 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.BondedRoleState; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.locale.Res; @@ -38,19 +39,22 @@ @EqualsAndHashCode @Data class BondedRolesListItem implements DaoStateListener { - private final BondedRole bondedRole; + private final BondedRoleState bondedRoleState; private final DaoFacade daoFacade; private final BsqFormatter bsqFormatter; private final AutoTooltipButton button; private final Label label; + private final BondedRole bondedRole; - BondedRolesListItem(BondedRole bondedRole, + BondedRolesListItem(BondedRoleState bondedRoleState, DaoFacade daoFacade, BsqFormatter bsqFormatter) { - this.bondedRole = bondedRole; + this.bondedRoleState = bondedRoleState; this.daoFacade = daoFacade; this.bsqFormatter = bsqFormatter; + bondedRole = bondedRoleState.getBondedRole(); + daoFacade.addBsqStateListener(this); button = new AutoTooltipButton(); @@ -62,14 +66,14 @@ class BondedRolesListItem implements DaoStateListener { } public String getStartDate() { - return bondedRole.getStartDate() > 0 ? - bsqFormatter.formatDateTime(new Date(bondedRole.getStartDate())) : + return bondedRoleState.getStartDate() > 0 ? + bsqFormatter.formatDateTime(new Date(bondedRoleState.getStartDate())) : "-"; } public String getRevokeDate() { - return bondedRole.getRevokeDate() > 0 ? - bsqFormatter.formatDateTime(new Date(bondedRole.getRevokeDate())) : + return bondedRoleState.getRevokeDate() > 0 ? + bsqFormatter.formatDateTime(new Date(bondedRoleState.getRevokeDate())) : "-"; } @@ -83,7 +87,7 @@ public void setOnAction(Runnable handler) { } public boolean isBonded() { - return bondedRole.isLockedUp(); + return bondedRoleState.isLockedUp(); } private void update() { @@ -93,9 +97,9 @@ private void update() { // 3. Unlocking: isLockedUp, isUnlocked, isUnlocking: unlocking // 4. Unlocked: isLockedUp, isUnlocked, !isUnlocking: unlocked - boolean isLockedUp = bondedRole.isLockedUp(); - boolean isUnlocked = bondedRole.isUnlocked(); - boolean isUnlocking = bondedRole.isUnlocking(daoFacade); + boolean isLockedUp = bondedRoleState.isLockedUp(); + boolean isUnlocked = bondedRoleState.isUnlocked(); + boolean isUnlocking = bondedRoleState.isUnlocking(); String text; if (!isLockedUp) diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java index 3a75156ae02..0e2ec7c48e6 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java @@ -153,8 +153,8 @@ public void onParseBlockChainComplete() { private void updateList() { observableList.forEach(BondedRolesListItem::cleanup); - observableList.setAll(daoFacade.getBondedRoleList().stream() - .map(bondedRole -> new BondedRolesListItem(bondedRole, daoFacade, bsqFormatter)) + observableList.setAll(daoFacade.getBondedRoleStates().stream() + .map(bondedRoleState -> new BondedRolesListItem(bondedRoleState, daoFacade, bsqFormatter)) .collect(Collectors.toList())); } @@ -332,7 +332,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - String transactionId = item.getBondedRole().getLockupTxId(); + String transactionId = item.getBondedRoleState().getLockupTxId(); if (transactionId != null) { hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(transactionId)); @@ -374,7 +374,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - String transactionId = item.getBondedRole().getUnlockTxId(); + String transactionId = item.getBondedRoleState().getUnlockTxId(); if (transactionId != null) { hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(transactionId)); @@ -449,7 +449,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { button = item.getButton(); item.setOnAction(() -> { if (item.isBonded()) - bondingViewUtils.unLock(item.getBondedRole().getLockupTxId(), + bondingViewUtils.unLock(item.getBondedRoleState().getLockupTxId(), () -> { // TODO button.setDisable(true); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java index 0a55270db7a..1f8af91934b 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java @@ -27,7 +27,7 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.bonding.BondingConsensus; import bisq.core.dao.bonding.lockup.LockupType; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.BondedRoleState; import bisq.core.dao.governance.role.BondedRoleType; import bisq.core.dao.governance.role.BondedRolesService; import bisq.core.dao.state.blockchain.BaseTxOutput; @@ -100,9 +100,9 @@ class LockupTxListItem extends TxConfidenceListItem { public boolean isLockupAndUnspent() { boolean isLocked; - Optional optionalBondedRole = bondedRolesService.getBondedRoleFromLockupTxId(txId); - if (optionalBondedRole.isPresent()) { - BondedRole bondedRole = optionalBondedRole.get(); + Optional optionalBondedRoleState = bondedRolesService.getBondedRoleStateFromLockupTxId(txId); + if (optionalBondedRoleState.isPresent()) { + BondedRoleState bondedRoleState = optionalBondedRoleState.get(); //TODO //isLocked = bondedRole.getLockupTxId() != null && bondedRole.getUnlockTxId() == null; //log.error("isLocked {}, tx={}",isLocked,bondedRole.getLockupTxId()); From 8b3c06fb81eefd34c9fe977fc1a3561483d20275 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 15:22:50 -0500 Subject: [PATCH 06/27] Rename BondedRole to Role This is the first of a series of renaming commits. We want to use role for the immutable class and BondedRole for the wrapper which contains role and the mutable state. --- .../main/java/bisq/core/dao/DaoFacade.java | 10 ++++---- .../dao/bonding/lockup/LockupService.java | 8 +++---- .../proposal/role/BondedRoleProposal.java | 24 +++++++++---------- .../role/BondedRoleProposalService.java | 12 +++++----- .../proposal/role/BondedRoleValidator.java | 6 ++--- .../dao/governance/role/BondedRoleState.java | 6 ++--- .../governance/role/BondedRolesService.java | 24 +++++++++---------- .../role/{BondedRole.java => Role.java} | 24 +++++++++---------- .../voteresult/VoteResultService.java | 6 ++--- .../main/dao/bonding/BondingViewUtils.java | 8 +++---- .../main/dao/bonding/lockup/LockupView.java | 12 +++++----- .../bonding/roles/BondedRolesListItem.java | 6 ++--- .../dao/bonding/roles/BondedRolesView.java | 8 +++---- .../main/dao/governance/ProposalDisplay.java | 20 ++++++++-------- .../dao/governance/make/MakeProposalView.java | 12 +++++----- .../governance/result/ProposalListItem.java | 6 ++--- 16 files changed, 96 insertions(+), 96 deletions(-) rename core/src/main/java/bisq/core/dao/governance/role/{BondedRole.java => Role.java} (88%) diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index f6ddeb296d6..e80e8e3d8bb 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -49,7 +49,7 @@ import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposalService; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalService; import bisq.core.dao.governance.proposal.role.BondedRoleProposalService; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.role.BondedRoleState; import bisq.core.dao.governance.role.BondedRolesService; import bisq.core.dao.state.DaoStateListener; @@ -263,9 +263,9 @@ public ProposalWithTransaction getConfiscateBondProposalWithTransaction(String n hash); } - public ProposalWithTransaction getBondedRoleProposalWithTransaction(BondedRole bondedRole) + public ProposalWithTransaction getBondedRoleProposalWithTransaction(Role role) throws ValidationException, InsufficientMoneyException, TxException { - return bondedRoleProposalService.createProposalWithTransaction(bondedRole); + return bondedRoleProposalService.createProposalWithTransaction(role); } public ProposalWithTransaction getGenericProposalWithTransaction(String name, @@ -512,7 +512,7 @@ public Optional getLockTime(String txId) { return daoStateService.getLockTime(txId); } - public List getActiveBondedRoles() { + public List getActiveBondedRoles() { return bondedRolesService.getActiveBondedRoles(); } @@ -621,7 +621,7 @@ public boolean isUnspent(TxOutputKey key) { return daoStateService.isUnspent(key); } - public Optional getBondedRoleFromHash(byte[] hash) { + public Optional getBondedRoleFromHash(byte[] hash) { return bondedRolesService.getBondedRoleFromHash(hash); } diff --git a/core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java b/core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java index ba87db7d75b..cd5b26dd7a1 100644 --- a/core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java +++ b/core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java @@ -27,7 +27,7 @@ import bisq.core.btc.wallet.WalletsManager; import bisq.core.dao.bonding.BondingConsensus; import bisq.core.dao.bonding.bond.BondWithHash; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.role.BondedRolesService; import bisq.common.handlers.ExceptionHandler; @@ -73,9 +73,9 @@ public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupTy checkArgument(lockTime <= BondingConsensus.getMaxLockTime() && lockTime >= BondingConsensus.getMinLockTime(), "lockTime not in rage"); - if (bondWithHash instanceof BondedRole) { - BondedRole bondedRole = (BondedRole) bondWithHash; - if (bondedRolesService.wasRoleAlreadyBonded(bondedRole)) { + if (bondWithHash instanceof Role) { + Role role = (Role) bondWithHash; + if (bondedRolesService.wasRoleAlreadyBonded(role)) { exceptionHandler.handleException(new RuntimeException("The role has been used already for a lockup tx.")); return; } diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposal.java index 0a961b5e29d..583066f6374 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposal.java @@ -19,7 +19,7 @@ import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; @@ -40,12 +40,12 @@ @EqualsAndHashCode(callSuper = true) @Value public final class BondedRoleProposal extends Proposal { - private final BondedRole bondedRole; + private final Role role; - BondedRoleProposal(BondedRole bondedRole) { - this(bondedRole.getName(), - bondedRole.getLink(), - bondedRole, + BondedRoleProposal(Role role) { + this(role.getName(), + role.getLink(), + role, Version.PROPOSAL, new Date().getTime(), ""); @@ -58,7 +58,7 @@ public final class BondedRoleProposal extends Proposal { private BondedRoleProposal(String name, String link, - BondedRole bondedRole, + Role role, byte version, long creationDate, String txId) { @@ -68,13 +68,13 @@ private BondedRoleProposal(String name, creationDate, txId); - this.bondedRole = bondedRole; + this.role = role; } @Override public PB.Proposal.Builder getProposalBuilder() { final PB.BondedRoleProposal.Builder builder = PB.BondedRoleProposal.newBuilder() - .setBondedRole(bondedRole.toProtoMessage()); + .setBondedRole(role.toProtoMessage()); return super.getProposalBuilder().setBondedRoleProposal(builder); } @@ -82,7 +82,7 @@ public static BondedRoleProposal fromProto(PB.Proposal proto) { final PB.BondedRoleProposal proposalProto = proto.getBondedRoleProposal(); return new BondedRoleProposal(proto.getName(), proto.getLink(), - BondedRole.fromProto(proposalProto.getBondedRole()), + Role.fromProto(proposalProto.getBondedRole()), (byte) proto.getVersion(), proto.getCreationDate(), proto.getTxId()); @@ -117,7 +117,7 @@ public TxType getTxType() { public Proposal cloneProposalAndAddTxId(String txId) { return new BondedRoleProposal(getName(), getLink(), - getBondedRole(), + this.getRole(), getVersion(), getCreationDate().getTime(), txId); @@ -126,7 +126,7 @@ public Proposal cloneProposalAndAddTxId(String txId) { @Override public String toString() { return "BondedRoleProposal{" + - "\n bondedRole=" + bondedRole + + "\n role=" + role + "\n} " + super.toString(); } } diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposalService.java index 2c879a7c3b6..0d458c10175 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposalService.java @@ -23,7 +23,7 @@ import bisq.core.dao.governance.proposal.BaseProposalService; import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.state.DaoStateService; import org.bitcoinj.core.InsufficientMoneyException; @@ -37,7 +37,7 @@ */ @Slf4j public class BondedRoleProposalService extends BaseProposalService { - private BondedRole bondedRole; + private Role role; /////////////////////////////////////////////////////////////////////////////////////////// @@ -55,15 +55,15 @@ public BondedRoleProposalService(BsqWalletService bsqWalletService, proposalValidator); } - public ProposalWithTransaction createProposalWithTransaction(BondedRole bondedRole) + public ProposalWithTransaction createProposalWithTransaction(Role role) throws ValidationException, InsufficientMoneyException, TxException { - this.bondedRole = bondedRole; + this.role = role; - return super.createProposalWithTransaction(bondedRole.getName(), bondedRole.getLink()); + return super.createProposalWithTransaction(role.getName(), role.getLink()); } @Override protected BondedRoleProposal createProposalWithoutTxId() { - return new BondedRoleProposal(bondedRole); + return new BondedRoleProposal(role); } } diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleValidator.java index 806741c0834..70fa69a1351 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleValidator.java @@ -20,7 +20,7 @@ import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalValidator; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.period.PeriodService; @@ -44,10 +44,10 @@ public void validateDataFields(Proposal proposal) throws ValidationException { super.validateDataFields(proposal); BondedRoleProposal bondedRoleProposal = (BondedRoleProposal) proposal; - BondedRole bondedRole = bondedRoleProposal.getBondedRole(); + Role role = bondedRoleProposal.getRole(); //TODO - notEmpty(bondedRole.getName(), "bondedRole.name must not be empty"); + notEmpty(role.getName(), "role.name must not be empty"); } catch (Throwable throwable) { throw new ValidationException(throwable); diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java index 91680dae5d0..fb356b336f5 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java +++ b/core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java @@ -27,7 +27,7 @@ */ @Getter public class BondedRoleState { - private final BondedRole bondedRole; + private final Role role; @Setter private long startDate; @@ -45,8 +45,8 @@ public class BondedRoleState { @Setter private boolean isUnlocking; - BondedRoleState(BondedRole bondedRole) { - this.bondedRole = bondedRole; + BondedRoleState(Role role) { + this.role = role; } public boolean isLockedUp() { diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java index 38f47b687a8..8043644d034 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java +++ b/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java @@ -90,7 +90,7 @@ public void onParseTxsComplete(Block block) { // We used the hash of th bonded role object as our hash in OpReturn of the lock up tx to have a // unique binding of the tx to the data object. byte[] hash = BondingConsensus.getHashFromOpReturnData(opReturnData); - Optional candidate = getBondedRoleFromHash(hash); + Optional candidate = getBondedRoleFromHash(hash); if (candidate.isPresent() && bondedRole.equals(candidate.get())) { if (bondedRoleState.getLockupTxId() == null) { bondedRoleState.setLockupTxId(lockupTxId); @@ -149,7 +149,7 @@ public void start() { } - public List getBondedRoleList() { + public List getBondedRoleList() { return getBondedRoleStream().collect(Collectors.toList()); } @@ -158,12 +158,12 @@ public Collection getBondedRoleStates() { } // bonded roles which are active and can be confiscated - public List getActiveBondedRoles() { + public List getActiveBondedRoles() { //TODO return getBondedRoleList(); } - public Optional getBondedRoleFromHash(byte[] hash) { + public Optional getBondedRoleFromHash(byte[] hash) { return getBondedRoleStream() .filter(bondedRole -> { byte[] candidateHash = bondedRole.getHash(); @@ -186,8 +186,8 @@ public Optional getBondedRoleStateFromLockupTxId(String lockupT public Optional getBondedRoleType(String lockUpTxId) { return getBondedRoleStateFromLockupTxId(lockUpTxId) - .map(BondedRoleState::getBondedRole) - .map(BondedRole::getBondedRoleType); + .map(BondedRoleState::getRole) + .map(Role::getBondedRoleType); } @@ -196,10 +196,10 @@ public Optional getBondedRoleType(String lockUpTxId) { /////////////////////////////////////////////////////////////////////////////////////////// - private Stream getBondedRoleStream() { + private Stream getBondedRoleStream() { return daoStateService.getEvaluatedProposalList().stream() .filter(evaluatedProposal -> evaluatedProposal.getProposal() instanceof BondedRoleProposal) - .map(e -> ((BondedRoleProposal) e.getProposal()).getBondedRole()); + .map(e -> ((BondedRoleProposal) e.getProposal()).getRole()); } @@ -207,8 +207,8 @@ private Optional getOpReturnData(String lockUpTxId) { return daoStateService.getLockupOpReturnTxOutput(lockUpTxId).map(BaseTxOutput::getOpReturnData); } - public boolean wasRoleAlreadyBonded(BondedRole bondedRole) { - BondedRoleState bondedRoleState = bondedRoleStateMap.get(bondedRole.getUid()); + public boolean wasRoleAlreadyBonded(Role role) { + BondedRoleState bondedRoleState = bondedRoleStateMap.get(role.getUid()); return bondedRoleState != null && bondedRoleState.getLockupTxId() != null; } @@ -218,13 +218,13 @@ public boolean wasRoleAlreadyBonded(BondedRole bondedRole) { .flatMap(BondingConsensus::getLockupType); }*/ - /*public static Optional getBondedRoleByLockupTxId(String lockupTxId) { + /*public static Optional getBondedRoleByLockupTxId(String lockupTxId) { return bondedRoles.stream() .filter(bondedRole -> bondedRole.getLockupTxId().equals(lockupTxId)). findAny(); }*/ /* - public static Optional getBondedRoleByHashOfBondId(byte[] hash) { + public static Optional getBondedRoleByHashOfBondId(byte[] hash) { return Optional.empty(); *//* bondedRoles.stream() .filter(bondedRole -> Arrays.equals(bondedRole.getHash(), hash)) diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java b/core/src/main/java/bisq/core/dao/governance/role/Role.java similarity index 88% rename from core/src/main/java/bisq/core/dao/governance/role/BondedRole.java rename to core/src/main/java/bisq/core/dao/governance/role/Role.java index a2b967a7d24..9033494b83c 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java +++ b/core/src/main/java/bisq/core/dao/governance/role/Role.java @@ -40,7 +40,7 @@ @Immutable @Slf4j @Value -public final class BondedRole implements PersistablePayload, NetworkPayload, BondWithHash { +public final class Role implements PersistablePayload, NetworkPayload, BondWithHash { private final String uid; private final String name; private final String link; @@ -51,9 +51,9 @@ public final class BondedRole implements PersistablePayload, NetworkPayload, Bon * @param link Github account or forum account of user * @param bondedRoleType BondedRoleType */ - public BondedRole(String name, - String link, - BondedRoleType bondedRoleType) { + public Role(String name, + String link, + BondedRoleType bondedRoleType) { this(UUID.randomUUID().toString(), name, link, @@ -66,10 +66,10 @@ public BondedRole(String name, // PROTO BUFFER /////////////////////////////////////////////////////////////////////////////////////////// - public BondedRole(String uid, - String name, - String link, - BondedRoleType bondedRoleType) { + public Role(String uid, + String name, + String link, + BondedRoleType bondedRoleType) { this.uid = uid; this.name = name; this.link = link; @@ -86,8 +86,8 @@ public PB.BondedRole toProtoMessage() { return builder.build(); } - public static BondedRole fromProto(PB.BondedRole proto) { - return new BondedRole(proto.getUid(), + public static Role fromProto(PB.BondedRole proto) { + return new Role(proto.getUid(), proto.getName(), proto.getLink(), ProtoUtil.enumFromProto(BondedRoleType.class, proto.getBondedRoleType())); @@ -121,7 +121,7 @@ public String getDisplayString() { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - BondedRole that = (BondedRole) o; + Role that = (Role) o; return Objects.equals(uid, that.uid) && Objects.equals(name, that.name) && Objects.equals(link, that.link) && @@ -135,7 +135,7 @@ public int hashCode() { @Override public String toString() { - return "BondedRole{" + + return "Role{" + "\n uid='" + uid + '\'' + ",\n name='" + name + '\'' + ",\n link='" + link + '\'' + diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java index a2bdea95bfa..2e640eb2586 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java @@ -37,7 +37,7 @@ import bisq.core.dao.governance.proposal.param.ChangeParamProposal; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; import bisq.core.dao.governance.proposal.role.BondedRoleProposal; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.role.BondedRolesService; import bisq.core.dao.governance.voteresult.issuance.IssuanceService; import bisq.core.dao.governance.votereveal.VoteRevealConsensus; @@ -643,11 +643,11 @@ private void applyBondedRole(Set acceptedEvaluatedProposals, acceptedEvaluatedProposals.forEach(evaluatedProposal -> { if (evaluatedProposal.getProposal() instanceof BondedRoleProposal) { BondedRoleProposal bondedRoleProposal = (BondedRoleProposal) evaluatedProposal.getProposal(); - BondedRole bondedRole = bondedRoleProposal.getBondedRole(); + Role role = bondedRoleProposal.getRole(); StringBuilder sb = new StringBuilder(); sb.append("\n################################################################################\n"); sb.append("We added a bonded role. ProposalTxId=").append(bondedRoleProposal.getTxId()) - .append("\nBondedRole: ").append(bondedRole.getDisplayString()) + .append("\nRole: ").append(role.getDisplayString()) .append("\n################################################################################\n"); log.info(sb.toString()); } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java index bf78c2ecde4..a79d2a31fab 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java @@ -29,7 +29,7 @@ import bisq.core.dao.bonding.bond.BondWithHash; import bisq.core.dao.bonding.bond.BondedReputation; import bisq.core.dao.bonding.lockup.LockupType; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.role.BondedRoleType; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.locale.Res; @@ -104,11 +104,11 @@ private void publishLockupTx(BondWithHash bondWithHash, Coin lockupAmount, int l resultHandler.handleResult(); } - public void lockupBondForBondedRole(BondedRole bondedRole, ResultHandler resultHandler) { - BondedRoleType bondedRoleType = bondedRole.getBondedRoleType(); + public void lockupBondForBondedRole(Role role, ResultHandler resultHandler) { + BondedRoleType bondedRoleType = role.getBondedRoleType(); Coin lockupAmount = Coin.valueOf(bondedRoleType.getRequiredBond()); int lockupTime = bondedRoleType.getUnlockTimeInBlocks(); - lockupBond(bondedRole, lockupAmount, lockupTime, LockupType.BONDED_ROLE, resultHandler); + lockupBond(role, lockupAmount, lockupTime, LockupType.BONDED_ROLE, resultHandler); } public void lockupBondForReputation(Coin lockupAmount, int lockupTime, ResultHandler resultHandler) { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index 91cd74e6384..ae259394150 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -32,7 +32,7 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.bonding.BondingConsensus; import bisq.core.dao.bonding.lockup.LockupType; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.role.BondedRoleState; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; @@ -166,7 +166,7 @@ public LockupType fromString(String string) { bondedRolesComboBox.setConverter(new StringConverter<>() { @Override public String toString(BondedRoleState bondedRoleState) { - return bondedRoleState.getBondedRole().getDisplayString(); + return bondedRoleState.getRole().getDisplayString(); } @Override @@ -176,9 +176,9 @@ public BondedRoleState fromString(String string) { }); bondedRoleStateListener = (observable, oldValue, newValue) -> { if (newValue != null) { - BondedRole bondedRole = newValue.getBondedRole(); - amountInputTextField.setText(bsqFormatter.formatCoin(Coin.valueOf(bondedRole.getBondedRoleType().getRequiredBond()))); - timeInputTextField.setText(String.valueOf(bondedRole.getBondedRoleType().getUnlockTimeInBlocks())); + Role role = newValue.getRole(); + amountInputTextField.setText(bsqFormatter.formatCoin(Coin.valueOf(role.getBondedRoleType().getRequiredBond()))); + timeInputTextField.setText(String.valueOf(role.getBondedRoleType().getUnlockTimeInBlocks())); amountInputTextField.resetValidation(); timeInputTextField.resetValidation(); amountInputTextField.setEditable(false); @@ -198,7 +198,7 @@ public BondedRoleState fromString(String string) { switch (lockupTypeComboBox.getValue()) { case BONDED_ROLE: if (bondedRolesComboBox.getValue() != null) { - bondingViewUtils.lockupBondForBondedRole(bondedRolesComboBox.getValue().getBondedRole(), + bondingViewUtils.lockupBondForBondedRole(bondedRolesComboBox.getValue().getRole(), () -> bondedRolesComboBox.getSelectionModel().clearSelection()); } break; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java index fc43579a155..a27280b8a5a 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java @@ -20,7 +20,7 @@ import bisq.desktop.components.AutoTooltipButton; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.role.BondedRoleState; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.blockchain.Block; @@ -44,7 +44,7 @@ class BondedRolesListItem implements DaoStateListener { private final BsqFormatter bsqFormatter; private final AutoTooltipButton button; private final Label label; - private final BondedRole bondedRole; + private final Role role; BondedRolesListItem(BondedRoleState bondedRoleState, DaoFacade daoFacade, @@ -53,7 +53,7 @@ class BondedRolesListItem implements DaoStateListener { this.daoFacade = daoFacade; this.bsqFormatter = bsqFormatter; - bondedRole = bondedRoleState.getBondedRole(); + role = bondedRoleState.getRole(); daoFacade.addBsqStateListener(this); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java index 0e2ec7c48e6..b7e8d15c2ea 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java @@ -186,7 +186,7 @@ public TableCell call(TableColumn call(TableColumn GUIUtil.openWebPage(link)); hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("shared.openURL", link))); @@ -246,7 +246,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - BondedRoleType bondedRoleType = item.getBondedRole().getBondedRoleType(); + BondedRoleType bondedRoleType = item.getRole().getBondedRoleType(); String type = bondedRoleType.getDisplayString(); hyperlink = new Hyperlink(type); hyperlink.setOnAction(event -> { @@ -455,7 +455,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { button.setDisable(true); }); else - bondingViewUtils.lockupBondForBondedRole(item.getBondedRole(), null); + bondingViewUtils.lockupBondForBondedRole(item.getRole(), null); }); setGraphic(button); } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java index 5713d0f3c72..8989be584b9 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java @@ -40,7 +40,7 @@ import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; import bisq.core.dao.governance.proposal.role.BondedRoleProposal; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.role.BondedRoleType; import bisq.core.dao.governance.voteresult.EvaluatedProposal; import bisq.core.dao.governance.voteresult.ProposalVoteResult; @@ -111,7 +111,7 @@ public class ProposalDisplay { @Nullable public ComboBox paramComboBox; @Nullable - public ComboBox confiscateBondComboBox; + public ComboBox confiscateBondComboBox; @Nullable public ComboBox bondedRoleTypeComboBox; @Nullable @@ -299,19 +299,19 @@ public BondedRoleType fromString(String string) { break; case CONFISCATE_BOND: - confiscateBondComboBox = FormBuilder.addComboBox(gridPane, ++gridRow, + confiscateBondComboBox = FormBuilder.addComboBox(gridPane, ++gridRow, Res.get("dao.proposal.display.confiscateBondComboBox.label")); comboBoxValueTextFieldIndex = gridRow; checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); confiscateBondComboBox.setItems(FXCollections.observableArrayList(daoFacade.getActiveBondedRoles())); confiscateBondComboBox.setConverter(new StringConverter<>() { @Override - public String toString(BondedRole bondedRole) { - return bondedRole != null ? bondedRole.getDisplayString() : ""; + public String toString(Role role) { + return role != null ? role.getDisplayString() : ""; } @Override - public BondedRole fromString(String string) { + public Role fromString(String string) { return null; } }); @@ -473,10 +473,10 @@ public void applyProposalPayload(Proposal proposal) { } else if (proposal instanceof BondedRoleProposal) { BondedRoleProposal bondedRoleProposal = (BondedRoleProposal) proposal; checkNotNull(bondedRoleTypeComboBox, "bondedRoleComboBox must not be null"); - BondedRole bondedRole = bondedRoleProposal.getBondedRole(); - bondedRoleTypeComboBox.getSelectionModel().select(bondedRole.getBondedRoleType()); - comboBoxValueTextField.setText(bondedRoleTypeComboBox.getConverter().toString(bondedRole.getBondedRoleType())); - requiredBondForRoleTextField.setText(bsqFormatter.formatCoin(Coin.valueOf(bondedRole.getBondedRoleType().getRequiredBond()))); + Role role = bondedRoleProposal.getRole(); + bondedRoleTypeComboBox.getSelectionModel().select(role.getBondedRoleType()); + comboBoxValueTextField.setText(bondedRoleTypeComboBox.getConverter().toString(role.getBondedRoleType())); + requiredBondForRoleTextField.setText(bsqFormatter.formatCoin(Coin.valueOf(role.getBondedRoleType().getRequiredBond()))); } else if (proposal instanceof ConfiscateBondProposal) { ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) proposal; checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java index 169a17e4f5f..e5743357ea7 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java @@ -37,7 +37,7 @@ import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.governance.proposal.param.ChangeParamValidator; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.governance.Param; @@ -254,7 +254,7 @@ private void doPublishMyProposal(Proposal proposal, Transaction transaction) { private ProposalWithTransaction getProposalWithTransaction(ProposalType type) throws InsufficientMoneyException, ValidationException, TxException { - BondedRole bondedRole; + Role role; switch (type) { case COMPENSATION_REQUEST: checkNotNull(proposalDisplay.requestedBsqTextField, @@ -297,17 +297,17 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) case BONDED_ROLE: checkNotNull(proposalDisplay.bondedRoleTypeComboBox, "proposalDisplay.bondedRoleTypeComboBox must not be null"); - bondedRole = new BondedRole(proposalDisplay.nameTextField.getText(), + role = new Role(proposalDisplay.nameTextField.getText(), proposalDisplay.linkInputTextField.getText(), proposalDisplay.bondedRoleTypeComboBox.getSelectionModel().getSelectedItem()); - return daoFacade.getBondedRoleProposalWithTransaction(bondedRole); + return daoFacade.getBondedRoleProposalWithTransaction(role); case CONFISCATE_BOND: checkNotNull(proposalDisplay.confiscateBondComboBox, "proposalDisplay.confiscateBondComboBox must not be null"); - bondedRole = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); + role = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); return daoFacade.getConfiscateBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.linkInputTextField.getText(), - bondedRole.getHash()); + role.getHash()); case GENERIC: return daoFacade.getGenericProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.linkInputTextField.getText()); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java index f84cdbdbcd5..14c6e097537 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java @@ -28,7 +28,7 @@ import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; import bisq.core.dao.governance.proposal.role.BondedRoleProposal; -import bisq.core.dao.governance.role.BondedRole; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.voteresult.EvaluatedProposal; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; @@ -120,8 +120,8 @@ public String getDetails() { return changeParamProposal.getParam().getDisplayString(); case BONDED_ROLE: BondedRoleProposal bondedRoleProposal = (BondedRoleProposal) proposal; - BondedRole bondedRole = bondedRoleProposal.getBondedRole(); - return Res.get("dao.bond.bondedRoleType." + bondedRole.getBondedRoleType().name()); + Role role = bondedRoleProposal.getRole(); + return Res.get("dao.bond.bondedRoleType." + role.getBondedRoleType().name()); case CONFISCATE_BOND: ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) proposal; // TODO add info to bond From 111df6e679a09e444653b7ffc49e743562372aa6 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 15:24:06 -0500 Subject: [PATCH 07/27] Rename BondedRoleState to BondedRole --- .../main/java/bisq/core/dao/DaoFacade.java | 6 ++--- .../{BondedRoleState.java => BondedRole.java} | 6 ++--- .../governance/role/BondedRolesService.java | 16 ++++++------ .../main/dao/bonding/lockup/LockupView.java | 12 ++++----- .../bonding/roles/BondedRolesListItem.java | 26 +++++++++---------- .../dao/bonding/roles/BondedRolesView.java | 6 ++--- .../dao/bonding/unlock/LockupTxListItem.java | 6 ++--- 7 files changed, 39 insertions(+), 39 deletions(-) rename core/src/main/java/bisq/core/dao/governance/role/{BondedRoleState.java => BondedRole.java} (91%) diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index e80e8e3d8bb..bf685eb042d 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -49,9 +49,9 @@ import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposalService; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalService; import bisq.core.dao.governance.proposal.role.BondedRoleProposalService; -import bisq.core.dao.governance.role.Role; -import bisq.core.dao.governance.role.BondedRoleState; +import bisq.core.dao.governance.role.BondedRole; import bisq.core.dao.governance.role.BondedRolesService; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateStorageService; @@ -281,7 +281,7 @@ public ProposalWithTransaction getRemoveAssetProposalWithTransaction(String name return removeAssetProposalService.createProposalWithTransaction(name, link, asset); } - public Collection getBondedRoleStates() { + public Collection getBondedRoleStates() { return bondedRolesService.getBondedRoleStates(); } diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java similarity index 91% rename from core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java rename to core/src/main/java/bisq/core/dao/governance/role/BondedRole.java index fb356b336f5..441449d2f7c 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRoleState.java +++ b/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java @@ -23,10 +23,10 @@ import javax.annotation.Nullable; /** - * Mutable state of a bonded role. Only kept in memory. + * Wrapper for role which contains the mutable state of a bonded role. Only kept in memory. */ @Getter -public class BondedRoleState { +public class BondedRole { private final Role role; @Setter @@ -45,7 +45,7 @@ public class BondedRoleState { @Setter private boolean isUnlocking; - BondedRoleState(Role role) { + BondedRole(Role role) { this.role = role; } diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java b/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java index 8043644d034..371d0060cf9 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java +++ b/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java @@ -49,7 +49,7 @@ public class BondedRolesService implements DaoStateListener { private final DaoStateService daoStateService; // This map is just for convenience. The data which are used to fill the map are store din the DaoState (role, txs). - private final Map bondedRoleStateMap = new HashMap<>(); + private final Map bondedRoleStateMap = new HashMap<>(); /////////////////////////////////////////////////////////////////////////////////////////// @@ -76,8 +76,8 @@ public void onNewBlockHeight(int blockHeight) { public void onParseTxsComplete(Block block) { // TODO optimize to not re-write the whole map at each block getBondedRoleStream().forEach(bondedRole -> { - bondedRoleStateMap.putIfAbsent(bondedRole.getUid(), new BondedRoleState(bondedRole)); - BondedRoleState bondedRoleState = bondedRoleStateMap.get(bondedRole.getUid()); + bondedRoleStateMap.putIfAbsent(bondedRole.getUid(), new BondedRole(bondedRole)); + BondedRole bondedRoleState = bondedRoleStateMap.get(bondedRole.getUid()); // Lets see if we have a lock up tx. daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> { @@ -153,7 +153,7 @@ public List getBondedRoleList() { return getBondedRoleStream().collect(Collectors.toList()); } - public Collection getBondedRoleStates() { + public Collection getBondedRoleStates() { return bondedRoleStateMap.values(); } @@ -177,7 +177,7 @@ public Optional getBondedRoleFromHash(byte[] hash) { .findAny(); } - public Optional getBondedRoleStateFromLockupTxId(String lockupTxId) { + public Optional getBondedRoleStateFromLockupTxId(String lockupTxId) { return bondedRoleStateMap.values().stream() .filter(bondedRoleState -> lockupTxId.equals(bondedRoleState.getLockupTxId())) .findAny(); @@ -186,7 +186,7 @@ public Optional getBondedRoleStateFromLockupTxId(String lockupT public Optional getBondedRoleType(String lockUpTxId) { return getBondedRoleStateFromLockupTxId(lockUpTxId) - .map(BondedRoleState::getRole) + .map(BondedRole::getRole) .map(Role::getBondedRoleType); } @@ -208,8 +208,8 @@ private Optional getOpReturnData(String lockUpTxId) { } public boolean wasRoleAlreadyBonded(Role role) { - BondedRoleState bondedRoleState = bondedRoleStateMap.get(role.getUid()); - return bondedRoleState != null && bondedRoleState.getLockupTxId() != null; + BondedRole bondedRole = bondedRoleStateMap.get(role.getUid()); + return bondedRole != null && bondedRole.getLockupTxId() != null; } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index ae259394150..1780ca9726f 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -32,8 +32,8 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.bonding.BondingConsensus; import bisq.core.dao.bonding.lockup.LockupType; +import bisq.core.dao.governance.role.BondedRole; import bisq.core.dao.governance.role.Role; -import bisq.core.dao.governance.role.BondedRoleState; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.validation.IntegerValidator; @@ -72,11 +72,11 @@ public class LockupView extends ActivatableView implements BsqBa private InputTextField amountInputTextField; private InputTextField timeInputTextField; private ComboBox lockupTypeComboBox; - private ComboBox bondedRolesComboBox; + private ComboBox bondedRolesComboBox; private Button lockupButton; private ChangeListener amountFocusOutListener, timeFocusOutListener; private ChangeListener amountInputTextFieldListener, timeInputTextFieldListener; - private ChangeListener bondedRoleStateListener; + private ChangeListener bondedRoleStateListener; private ChangeListener lockupTypeListener; private TitledGroupBg titledGroupBg; @@ -165,12 +165,12 @@ public LockupType fromString(String string) { bondedRolesComboBox.setVisible(false); bondedRolesComboBox.setConverter(new StringConverter<>() { @Override - public String toString(BondedRoleState bondedRoleState) { - return bondedRoleState.getRole().getDisplayString(); + public String toString(BondedRole bondedRole) { + return bondedRole.getRole().getDisplayString(); } @Override - public BondedRoleState fromString(String string) { + public BondedRole fromString(String string) { return null; } }); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java index a27280b8a5a..5f21eb0f6f0 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java @@ -20,8 +20,8 @@ import bisq.desktop.components.AutoTooltipButton; import bisq.core.dao.DaoFacade; +import bisq.core.dao.governance.role.BondedRole; import bisq.core.dao.governance.role.Role; -import bisq.core.dao.governance.role.BondedRoleState; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.blockchain.Block; import bisq.core.locale.Res; @@ -39,21 +39,21 @@ @EqualsAndHashCode @Data class BondedRolesListItem implements DaoStateListener { - private final BondedRoleState bondedRoleState; + private final BondedRole bondedRole; private final DaoFacade daoFacade; private final BsqFormatter bsqFormatter; private final AutoTooltipButton button; private final Label label; private final Role role; - BondedRolesListItem(BondedRoleState bondedRoleState, + BondedRolesListItem(BondedRole bondedRole, DaoFacade daoFacade, BsqFormatter bsqFormatter) { - this.bondedRoleState = bondedRoleState; + this.bondedRole = bondedRole; this.daoFacade = daoFacade; this.bsqFormatter = bsqFormatter; - role = bondedRoleState.getRole(); + role = bondedRole.getRole(); daoFacade.addBsqStateListener(this); @@ -66,14 +66,14 @@ class BondedRolesListItem implements DaoStateListener { } public String getStartDate() { - return bondedRoleState.getStartDate() > 0 ? - bsqFormatter.formatDateTime(new Date(bondedRoleState.getStartDate())) : + return bondedRole.getStartDate() > 0 ? + bsqFormatter.formatDateTime(new Date(bondedRole.getStartDate())) : "-"; } public String getRevokeDate() { - return bondedRoleState.getRevokeDate() > 0 ? - bsqFormatter.formatDateTime(new Date(bondedRoleState.getRevokeDate())) : + return bondedRole.getRevokeDate() > 0 ? + bsqFormatter.formatDateTime(new Date(bondedRole.getRevokeDate())) : "-"; } @@ -87,7 +87,7 @@ public void setOnAction(Runnable handler) { } public boolean isBonded() { - return bondedRoleState.isLockedUp(); + return bondedRole.isLockedUp(); } private void update() { @@ -97,9 +97,9 @@ private void update() { // 3. Unlocking: isLockedUp, isUnlocked, isUnlocking: unlocking // 4. Unlocked: isLockedUp, isUnlocked, !isUnlocking: unlocked - boolean isLockedUp = bondedRoleState.isLockedUp(); - boolean isUnlocked = bondedRoleState.isUnlocked(); - boolean isUnlocking = bondedRoleState.isUnlocking(); + boolean isLockedUp = bondedRole.isLockedUp(); + boolean isUnlocked = bondedRole.isUnlocked(); + boolean isUnlocking = bondedRole.isUnlocking(); String text; if (!isLockedUp) diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java index b7e8d15c2ea..a13fb7676c0 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java @@ -332,7 +332,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - String transactionId = item.getBondedRoleState().getLockupTxId(); + String transactionId = item.getBondedRole().getLockupTxId(); if (transactionId != null) { hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(transactionId)); @@ -374,7 +374,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - String transactionId = item.getBondedRoleState().getUnlockTxId(); + String transactionId = item.getBondedRole().getUnlockTxId(); if (transactionId != null) { hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(transactionId)); @@ -449,7 +449,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { button = item.getButton(); item.setOnAction(() -> { if (item.isBonded()) - bondingViewUtils.unLock(item.getBondedRoleState().getLockupTxId(), + bondingViewUtils.unLock(item.getBondedRole().getLockupTxId(), () -> { // TODO button.setDisable(true); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java index 1f8af91934b..c619f371565 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java @@ -27,7 +27,7 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.bonding.BondingConsensus; import bisq.core.dao.bonding.lockup.LockupType; -import bisq.core.dao.governance.role.BondedRoleState; +import bisq.core.dao.governance.role.BondedRole; import bisq.core.dao.governance.role.BondedRoleType; import bisq.core.dao.governance.role.BondedRolesService; import bisq.core.dao.state.blockchain.BaseTxOutput; @@ -100,9 +100,9 @@ class LockupTxListItem extends TxConfidenceListItem { public boolean isLockupAndUnspent() { boolean isLocked; - Optional optionalBondedRoleState = bondedRolesService.getBondedRoleStateFromLockupTxId(txId); + Optional optionalBondedRoleState = bondedRolesService.getBondedRoleStateFromLockupTxId(txId); if (optionalBondedRoleState.isPresent()) { - BondedRoleState bondedRoleState = optionalBondedRoleState.get(); + BondedRole bondedRole = optionalBondedRoleState.get(); //TODO //isLocked = bondedRole.getLockupTxId() != null && bondedRole.getUnlockTxId() == null; //log.error("isLocked {}, tx={}",isLocked,bondedRole.getLockupTxId()); From 2575a0aa90bb27f17419b904d0bdc3bb4a92e20d Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 15:29:07 -0500 Subject: [PATCH 08/27] Rename BondedRoleProposal and service --- common/src/main/proto/pb.proto | 8 ++--- .../main/java/bisq/core/dao/DaoFacade.java | 10 +++--- .../main/java/bisq/core/dao/DaoModule.java | 8 ++--- .../dao/governance/proposal/Proposal.java | 6 ++-- ...dedRoleProposal.java => RoleProposal.java} | 34 +++++++++---------- ...lService.java => RoleProposalService.java} | 16 ++++----- ...dRoleValidator.java => RoleValidator.java} | 8 ++--- .../governance/role/BondedRolesService.java | 6 ++-- .../bisq/core/dao/governance/role/Role.java | 6 ++-- .../voteresult/VoteResultService.java | 12 +++---- .../main/dao/governance/ProposalDisplay.java | 10 +++--- .../governance/result/ProposalListItem.java | 6 ++-- 12 files changed, 65 insertions(+), 65 deletions(-) rename core/src/main/java/bisq/core/dao/governance/proposal/role/{BondedRoleProposal.java => RoleProposal.java} (76%) rename core/src/main/java/bisq/core/dao/governance/proposal/role/{BondedRoleProposalService.java => RoleProposalService.java} (78%) rename core/src/main/java/bisq/core/dao/governance/proposal/role/{BondedRoleValidator.java => RoleValidator.java} (84%) diff --git a/common/src/main/proto/pb.proto b/common/src/main/proto/pb.proto index ad1310e0d85..91af8cb1ab7 100644 --- a/common/src/main/proto/pb.proto +++ b/common/src/main/proto/pb.proto @@ -1494,7 +1494,7 @@ message Proposal { CompensationProposal compensation_proposal = 6; ReimbursementProposal reimbursement_proposal = 7; ChangeParamProposal change_param_proposal = 8; - BondedRoleProposal bonded_role_proposal = 9; + RoleProposal role_proposal = 9; ConfiscateBondProposal confiscate_bond_proposal = 10; GenericProposal generic_proposal = 11; RemoveAssetProposal remove_asset_proposal = 12; @@ -1516,8 +1516,8 @@ message ChangeParamProposal { string param_value = 2; } -message BondedRoleProposal { - BondedRole bonded_role = 1; +message RoleProposal { + Role role = 1; } message ConfiscateBondProposal { @@ -1539,7 +1539,7 @@ message RemovedAssetList { repeated RemovedAsset removed_asset = 1; } -message BondedRole { +message Role { string uid = 1; string name = 2; string link = 3; diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index bf685eb042d..db5e523a73d 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -48,7 +48,7 @@ import bisq.core.dao.governance.proposal.reimbursement.ReimbursementConsensus; import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposalService; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalService; -import bisq.core.dao.governance.proposal.role.BondedRoleProposalService; +import bisq.core.dao.governance.proposal.role.RoleProposalService; import bisq.core.dao.governance.role.BondedRole; import bisq.core.dao.governance.role.BondedRolesService; import bisq.core.dao.governance.role.Role; @@ -112,7 +112,7 @@ public class DaoFacade implements DaoSetupService { private final ReimbursementProposalService reimbursementProposalService; private final ChangeParamProposalService changeParamProposalService; private final ConfiscateBondProposalService confiscateBondProposalService; - private final BondedRoleProposalService bondedRoleProposalService; + private final RoleProposalService roleProposalService; private final GenericProposalService genericProposalService; private final RemoveAssetProposalService removeAssetProposalService; private final BondedRolesService bondedRolesService; @@ -136,7 +136,7 @@ public DaoFacade(MyProposalListService myProposalListService, ReimbursementProposalService reimbursementProposalService, ChangeParamProposalService changeParamProposalService, ConfiscateBondProposalService confiscateBondProposalService, - BondedRoleProposalService bondedRoleProposalService, + RoleProposalService roleProposalService, GenericProposalService genericProposalService, RemoveAssetProposalService removeAssetProposalService, BondedRolesService bondedRolesService, @@ -156,7 +156,7 @@ public DaoFacade(MyProposalListService myProposalListService, this.reimbursementProposalService = reimbursementProposalService; this.changeParamProposalService = changeParamProposalService; this.confiscateBondProposalService = confiscateBondProposalService; - this.bondedRoleProposalService = bondedRoleProposalService; + this.roleProposalService = roleProposalService; this.genericProposalService = genericProposalService; this.removeAssetProposalService = removeAssetProposalService; this.bondedRolesService = bondedRolesService; @@ -265,7 +265,7 @@ public ProposalWithTransaction getConfiscateBondProposalWithTransaction(String n public ProposalWithTransaction getBondedRoleProposalWithTransaction(Role role) throws ValidationException, InsufficientMoneyException, TxException { - return bondedRoleProposalService.createProposalWithTransaction(role); + return roleProposalService.createProposalWithTransaction(role); } public ProposalWithTransaction getGenericProposalWithTransaction(String name, diff --git a/core/src/main/java/bisq/core/dao/DaoModule.java b/core/src/main/java/bisq/core/dao/DaoModule.java index 597b791f7aa..653b00b449e 100644 --- a/core/src/main/java/bisq/core/dao/DaoModule.java +++ b/core/src/main/java/bisq/core/dao/DaoModule.java @@ -46,8 +46,8 @@ import bisq.core.dao.governance.proposal.reimbursement.ReimbursementValidator; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalService; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetValidator; -import bisq.core.dao.governance.proposal.role.BondedRoleProposalService; -import bisq.core.dao.governance.proposal.role.BondedRoleValidator; +import bisq.core.dao.governance.proposal.role.RoleProposalService; +import bisq.core.dao.governance.proposal.role.RoleValidator; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStorageService; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStore; import bisq.core.dao.governance.proposal.storage.temp.TempProposalStorageService; @@ -140,8 +140,8 @@ protected void configure() { bind(ChangeParamValidator.class).in(Singleton.class); bind(ChangeParamProposalService.class).in(Singleton.class); - bind(BondedRoleValidator.class).in(Singleton.class); - bind(BondedRoleProposalService.class).in(Singleton.class); + bind(RoleValidator.class).in(Singleton.class); + bind(RoleProposalService.class).in(Singleton.class); bind(ConfiscateBondValidator.class).in(Singleton.class); bind(ConfiscateBondProposalService.class).in(Singleton.class); diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java index dcc61b67880..9db55016894 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java @@ -24,7 +24,7 @@ import bisq.core.dao.governance.proposal.param.ChangeParamProposal; import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; -import bisq.core.dao.governance.proposal.role.BondedRoleProposal; +import bisq.core.dao.governance.proposal.role.RoleProposal; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; @@ -98,8 +98,8 @@ public static Proposal fromProto(PB.Proposal proto) { return ReimbursementProposal.fromProto(proto); case CHANGE_PARAM_PROPOSAL: return ChangeParamProposal.fromProto(proto); - case BONDED_ROLE_PROPOSAL: - return BondedRoleProposal.fromProto(proto); + case ROLE_PROPOSAL: + return RoleProposal.fromProto(proto); case CONFISCATE_BOND_PROPOSAL: return ConfiscateBondProposal.fromProto(proto); case GENERIC_PROPOSAL: diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposal.java similarity index 76% rename from core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposal.java rename to core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposal.java index 583066f6374..53f322246ec 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposal.java @@ -39,10 +39,10 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class BondedRoleProposal extends Proposal { +public final class RoleProposal extends Proposal { private final Role role; - BondedRoleProposal(Role role) { + RoleProposal(Role role) { this(role.getName(), role.getLink(), role, @@ -56,12 +56,12 @@ public final class BondedRoleProposal extends Proposal { // PROTO BUFFER /////////////////////////////////////////////////////////////////////////////////////////// - private BondedRoleProposal(String name, - String link, - Role role, - byte version, - long creationDate, - String txId) { + private RoleProposal(String name, + String link, + Role role, + byte version, + long creationDate, + String txId) { super(name, link, version, @@ -73,16 +73,16 @@ private BondedRoleProposal(String name, @Override public PB.Proposal.Builder getProposalBuilder() { - final PB.BondedRoleProposal.Builder builder = PB.BondedRoleProposal.newBuilder() - .setBondedRole(role.toProtoMessage()); - return super.getProposalBuilder().setBondedRoleProposal(builder); + final PB.RoleProposal.Builder builder = PB.RoleProposal.newBuilder() + .setRole(role.toProtoMessage()); + return super.getProposalBuilder().setRoleProposal(builder); } - public static BondedRoleProposal fromProto(PB.Proposal proto) { - final PB.BondedRoleProposal proposalProto = proto.getBondedRoleProposal(); - return new BondedRoleProposal(proto.getName(), + public static RoleProposal fromProto(PB.Proposal proto) { + final PB.RoleProposal proposalProto = proto.getRoleProposal(); + return new RoleProposal(proto.getName(), proto.getLink(), - Role.fromProto(proposalProto.getBondedRole()), + Role.fromProto(proposalProto.getRole()), (byte) proto.getVersion(), proto.getCreationDate(), proto.getTxId()); @@ -115,7 +115,7 @@ public TxType getTxType() { @Override public Proposal cloneProposalAndAddTxId(String txId) { - return new BondedRoleProposal(getName(), + return new RoleProposal(getName(), getLink(), this.getRole(), getVersion(), @@ -125,7 +125,7 @@ public Proposal cloneProposalAndAddTxId(String txId) { @Override public String toString() { - return "BondedRoleProposal{" + + return "RoleProposal{" + "\n role=" + role + "\n} " + super.toString(); } diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposalService.java similarity index 78% rename from core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposalService.java rename to core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposalService.java index 0d458c10175..14222b827df 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/role/BondedRoleProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposalService.java @@ -33,10 +33,10 @@ import lombok.extern.slf4j.Slf4j; /** - * Creates BondedRoleProposal and transaction. + * Creates RoleProposal and transaction. */ @Slf4j -public class BondedRoleProposalService extends BaseProposalService { +public class RoleProposalService extends BaseProposalService { private Role role; @@ -45,10 +45,10 @@ public class BondedRoleProposalService extends BaseProposalService getBondedRoleType(String lockUpTxId) { private Stream getBondedRoleStream() { return daoStateService.getEvaluatedProposalList().stream() - .filter(evaluatedProposal -> evaluatedProposal.getProposal() instanceof BondedRoleProposal) - .map(e -> ((BondedRoleProposal) e.getProposal()).getRole()); + .filter(evaluatedProposal -> evaluatedProposal.getProposal() instanceof RoleProposal) + .map(e -> ((RoleProposal) e.getProposal()).getRole()); } diff --git a/core/src/main/java/bisq/core/dao/governance/role/Role.java b/core/src/main/java/bisq/core/dao/governance/role/Role.java index 9033494b83c..39c4700d3bd 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/Role.java +++ b/core/src/main/java/bisq/core/dao/governance/role/Role.java @@ -77,8 +77,8 @@ public Role(String uid, } @Override - public PB.BondedRole toProtoMessage() { - PB.BondedRole.Builder builder = PB.BondedRole.newBuilder() + public PB.Role toProtoMessage() { + PB.Role.Builder builder = PB.Role.newBuilder() .setUid(uid) .setName(name) .setLink(link) @@ -86,7 +86,7 @@ public PB.BondedRole toProtoMessage() { return builder.build(); } - public static Role fromProto(PB.BondedRole proto) { + public static Role fromProto(PB.Role proto) { return new Role(proto.getUid(), proto.getName(), proto.getLink(), diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java index 2e640eb2586..1fdf7dd785a 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java @@ -36,9 +36,9 @@ import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposal; import bisq.core.dao.governance.proposal.param.ChangeParamProposal; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; -import bisq.core.dao.governance.proposal.role.BondedRoleProposal; -import bisq.core.dao.governance.role.Role; +import bisq.core.dao.governance.proposal.role.RoleProposal; import bisq.core.dao.governance.role.BondedRolesService; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.voteresult.issuance.IssuanceService; import bisq.core.dao.governance.votereveal.VoteRevealConsensus; import bisq.core.dao.governance.votereveal.VoteRevealService; @@ -641,12 +641,12 @@ private ParamChange getParamChange(ChangeParamProposal changeParamProposal, int private void applyBondedRole(Set acceptedEvaluatedProposals, int chainHeight) { acceptedEvaluatedProposals.forEach(evaluatedProposal -> { - if (evaluatedProposal.getProposal() instanceof BondedRoleProposal) { - BondedRoleProposal bondedRoleProposal = (BondedRoleProposal) evaluatedProposal.getProposal(); - Role role = bondedRoleProposal.getRole(); + if (evaluatedProposal.getProposal() instanceof RoleProposal) { + RoleProposal roleProposal = (RoleProposal) evaluatedProposal.getProposal(); + Role role = roleProposal.getRole(); StringBuilder sb = new StringBuilder(); sb.append("\n################################################################################\n"); - sb.append("We added a bonded role. ProposalTxId=").append(bondedRoleProposal.getTxId()) + sb.append("We added a bonded role. ProposalTxId=").append(roleProposal.getTxId()) .append("\nRole: ").append(role.getDisplayString()) .append("\n################################################################################\n"); log.info(sb.toString()); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java index 8989be584b9..5cb3e160c89 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java @@ -39,9 +39,9 @@ import bisq.core.dao.governance.proposal.param.ChangeParamValidator; import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; -import bisq.core.dao.governance.proposal.role.BondedRoleProposal; -import bisq.core.dao.governance.role.Role; +import bisq.core.dao.governance.proposal.role.RoleProposal; import bisq.core.dao.governance.role.BondedRoleType; +import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.voteresult.EvaluatedProposal; import bisq.core.dao.governance.voteresult.ProposalVoteResult; import bisq.core.dao.state.blockchain.Tx; @@ -470,10 +470,10 @@ public void applyProposalPayload(Proposal proposal) { comboBoxValueTextField.setText(paramComboBox.getConverter().toString(changeParamProposal.getParam())); checkNotNull(paramValueTextField, "paramValueTextField must not be null"); paramValueTextField.setText(bsqFormatter.formatParamValue(changeParamProposal.getParam(), changeParamProposal.getParamValue())); - } else if (proposal instanceof BondedRoleProposal) { - BondedRoleProposal bondedRoleProposal = (BondedRoleProposal) proposal; + } else if (proposal instanceof RoleProposal) { + RoleProposal roleProposal = (RoleProposal) proposal; checkNotNull(bondedRoleTypeComboBox, "bondedRoleComboBox must not be null"); - Role role = bondedRoleProposal.getRole(); + Role role = roleProposal.getRole(); bondedRoleTypeComboBox.getSelectionModel().select(role.getBondedRoleType()); comboBoxValueTextField.setText(bondedRoleTypeComboBox.getConverter().toString(role.getBondedRoleType())); requiredBondForRoleTextField.setText(bsqFormatter.formatCoin(Coin.valueOf(role.getBondedRoleType().getRequiredBond()))); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java index 14c6e097537..427a3c95b65 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java @@ -27,7 +27,7 @@ import bisq.core.dao.governance.proposal.param.ChangeParamProposal; import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; -import bisq.core.dao.governance.proposal.role.BondedRoleProposal; +import bisq.core.dao.governance.proposal.role.RoleProposal; import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.voteresult.EvaluatedProposal; import bisq.core.locale.CurrencyUtil; @@ -119,8 +119,8 @@ public String getDetails() { ChangeParamProposal changeParamProposal = (ChangeParamProposal) proposal; return changeParamProposal.getParam().getDisplayString(); case BONDED_ROLE: - BondedRoleProposal bondedRoleProposal = (BondedRoleProposal) proposal; - Role role = bondedRoleProposal.getRole(); + RoleProposal roleProposal = (RoleProposal) proposal; + Role role = roleProposal.getRole(); return Res.get("dao.bond.bondedRoleType." + role.getBondedRoleType().name()); case CONFISCATE_BOND: ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) proposal; From ee83a896edc9c22ca55c005a51047a5186ec6e1e Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 15:37:22 -0500 Subject: [PATCH 09/27] Add ImmutableDaoStateVo interface Add ImmutableDaoStateVo interface to mark the objects used in the daoState as immutable. --- .../bisq/core/dao/governance/role/Role.java | 3 +++ .../core/dao/state/ImmutableDaoStateVo.java | 24 +++++++++++++++++++ .../core/dao/state/blockchain/BaseBlock.java | 4 +++- .../core/dao/state/blockchain/BaseTx.java | 4 +++- .../dao/state/blockchain/BaseTxOutput.java | 4 +++- .../bisq/core/dao/state/blockchain/Block.java | 5 +++- .../dao/state/blockchain/PubKeyScript.java | 6 ++++- .../bisq/core/dao/state/blockchain/Tx.java | 6 ++++- .../core/dao/state/blockchain/TxInput.java | 4 +++- .../core/dao/state/blockchain/TxOutput.java | 4 +++- 10 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 core/src/main/java/bisq/core/dao/state/ImmutableDaoStateVo.java diff --git a/core/src/main/java/bisq/core/dao/governance/role/Role.java b/core/src/main/java/bisq/core/dao/governance/role/Role.java index 39c4700d3bd..082c60c5f6c 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/Role.java +++ b/core/src/main/java/bisq/core/dao/governance/role/Role.java @@ -37,6 +37,9 @@ import javax.annotation.concurrent.Immutable; +/** + * Immutable data for a role. Is stored in the DaoState as part of the evaluated proposals. + */ @Immutable @Slf4j @Value diff --git a/core/src/main/java/bisq/core/dao/state/ImmutableDaoStateVo.java b/core/src/main/java/bisq/core/dao/state/ImmutableDaoStateVo.java new file mode 100644 index 00000000000..35c6fc4dffd --- /dev/null +++ b/core/src/main/java/bisq/core/dao/state/ImmutableDaoStateVo.java @@ -0,0 +1,24 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.state; + +/** + * Market interface for objects which are stored in the daoState and therefore they need to be immutable. + */ +public interface ImmutableDaoStateVo { +} diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java b/core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java index ebc6c4b4f7f..f98261b564c 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import io.bisq.generated.protobuffer.PB; import java.util.Optional; @@ -32,7 +34,7 @@ */ @Immutable @Data -public abstract class BaseBlock { +public abstract class BaseBlock implements ImmutableDaoStateVo { protected final int height; protected final long time; // in ms protected final String hash; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java b/core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java index 2503f07bb13..6329a055204 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import io.bisq.generated.protobuffer.PB; import com.google.common.collect.ImmutableList; @@ -40,7 +42,7 @@ @Slf4j @Getter @EqualsAndHashCode -public abstract class BaseTx { +public abstract class BaseTx implements ImmutableDaoStateVo { protected final String txVersion; protected final String id; protected final int blockHeight; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java b/core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java index e66e9f06e0e..08c1f18f130 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.util.JsonExclude; import bisq.common.util.Utilities; @@ -38,7 +40,7 @@ @Slf4j @Immutable @Data -public abstract class BaseTxOutput { +public abstract class BaseTxOutput implements ImmutableDaoStateVo { protected final int index; protected final long value; protected final String txId; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/Block.java b/core/src/main/java/bisq/core/dao/state/blockchain/Block.java index 64f01e3f9e4..d69dd26998e 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/Block.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/Block.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.persistable.PersistablePayload; import io.bisq.generated.protobuffer.PB; @@ -33,10 +35,11 @@ /** * The Block which gets persisted in the DaoState. During parsing transactions can be * added to the txs list, therefore it is not an immutable list. + * // TODO make it fully immutable */ @EqualsAndHashCode(callSuper = true) @Value -public final class Block extends BaseBlock implements PersistablePayload { +public final class Block extends BaseBlock implements PersistablePayload, ImmutableDaoStateVo { private final List txs; public Block(int height, long time, String hash, String previousBlockHash) { diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java b/core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java index 23f672afe74..743f957424d 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.persistable.PersistablePayload; import io.bisq.generated.protobuffer.PB; @@ -30,10 +32,12 @@ import lombok.Value; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; +@Immutable @Value @AllArgsConstructor -public class PubKeyScript implements PersistablePayload { +public class PubKeyScript implements PersistablePayload, ImmutableDaoStateVo { private final int reqSigs; private final ScriptType scriptType; @Nullable diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/Tx.java b/core/src/main/java/bisq/core/dao/state/blockchain/Tx.java index 0871253ff8b..a5ac1261aa5 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/Tx.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/Tx.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.persistable.PersistablePayload; import io.bisq.generated.protobuffer.PB; @@ -31,13 +33,15 @@ import lombok.Value; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; /** * Immutable class for a Bsq transaction. * Gets persisted. */ +@Immutable @Value -public final class Tx extends BaseTx implements PersistablePayload { +public final class Tx extends BaseTx implements PersistablePayload, ImmutableDaoStateVo { // Created after parsing of a tx is completed. We store only the immutable tx in the block. public static Tx fromTempTx(TempTx tempTx) { ImmutableList txOutputs = ImmutableList.copyOf(tempTx.getTempTxOutputs().stream() diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxInput.java b/core/src/main/java/bisq/core/dao/state/blockchain/TxInput.java index 23d0c399a89..b40f4a172fc 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxInput.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/TxInput.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.persistable.PersistablePayload; import io.bisq.generated.protobuffer.PB; @@ -38,7 +40,7 @@ @Value @EqualsAndHashCode @Slf4j -public final class TxInput implements PersistablePayload { +public final class TxInput implements PersistablePayload, ImmutableDaoStateVo { public static TxInput clone(TxInput txInput) { return new TxInput(txInput.getConnectedTxOutputTxId(), diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java b/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java index cd6e04ad577..6c35e88be38 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.persistable.PersistablePayload; import io.bisq.generated.protobuffer.PB; @@ -34,7 +36,7 @@ * Gets persisted. */ @Data -public class TxOutput extends BaseTxOutput implements PersistablePayload { +public class TxOutput extends BaseTxOutput implements PersistablePayload, ImmutableDaoStateVo { public static TxOutput fromTempOutput(TempTxOutput tempTxOutput) { return new TxOutput(tempTxOutput.getIndex(), tempTxOutput.getValue(), From bf1ae98a6daf39913a91506f1c4d49cd6d099e01 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 16:10:29 -0500 Subject: [PATCH 10/27] Add ImmutableDaoStateVo interface to all objects used in daoState --- .../java/bisq/core/dao/governance/ballot/Ballot.java | 5 ++++- .../bisq/core/dao/governance/ballot/BallotList.java | 6 +++++- .../bisq/core/dao/governance/ballot/vote/Vote.java | 6 +++++- .../java/bisq/core/dao/governance/merit/Merit.java | 6 +++++- .../bisq/core/dao/governance/merit/MeritList.java | 6 +++++- .../bisq/core/dao/governance/proposal/Proposal.java | 3 ++- .../proposal/compensation/CompensationProposal.java | 3 ++- .../confiscatebond/ConfiscateBondProposal.java | 3 ++- .../governance/proposal/generic/GenericProposal.java | 3 ++- .../proposal/param/ChangeParamProposal.java | 3 ++- .../proposal/reimbursement/ReimbursementProposal.java | 3 ++- .../proposal/removeAsset/RemoveAssetProposal.java | 3 ++- .../dao/governance/proposal/role/RoleProposal.java | 3 ++- .../voteresult/DecryptedBallotsWithMerits.java | 6 +++++- .../dao/governance/voteresult/EvaluatedProposal.java | 6 +++++- .../dao/governance/voteresult/ProposalVoteResult.java | 6 +++++- .../bisq/core/dao/state/blockchain/BaseBlock.java | 4 +--- .../java/bisq/core/dao/state/blockchain/BaseTx.java | 4 +--- .../bisq/core/dao/state/blockchain/BaseTxOutput.java | 4 +--- .../java/bisq/core/dao/state/blockchain/Block.java | 11 +++++++---- .../bisq/core/dao/state/blockchain/OpReturnType.java | 8 ++++++-- .../bisq/core/dao/state/blockchain/ScriptType.java | 7 ++++++- .../bisq/core/dao/state/blockchain/SpentInfo.java | 8 ++++++-- .../java/bisq/core/dao/state/blockchain/TxOutput.java | 2 ++ .../bisq/core/dao/state/blockchain/TxOutputKey.java | 11 ++++++++++- .../bisq/core/dao/state/blockchain/TxOutputType.java | 7 ++++++- .../java/bisq/core/dao/state/blockchain/TxType.java | 6 +++++- .../java/bisq/core/dao/state/governance/Issuance.java | 4 +++- .../bisq/core/dao/state/governance/IssuanceType.java | 7 ++++++- .../bisq/core/dao/state/governance/ParamChange.java | 4 +++- .../main/java/bisq/core/dao/state/period/Cycle.java | 4 +++- .../java/bisq/core/dao/state/period/DaoPhase.java | 7 +++++-- 32 files changed, 126 insertions(+), 43 deletions(-) diff --git a/core/src/main/java/bisq/core/dao/governance/ballot/Ballot.java b/core/src/main/java/bisq/core/dao/governance/ballot/Ballot.java index 3f70b338765..68752c59cde 100644 --- a/core/src/main/java/bisq/core/dao/governance/ballot/Ballot.java +++ b/core/src/main/java/bisq/core/dao/governance/ballot/Ballot.java @@ -21,6 +21,7 @@ import bisq.core.dao.governance.ballot.vote.Vote; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.common.proto.persistable.PersistablePayload; @@ -33,6 +34,7 @@ import lombok.extern.slf4j.Slf4j; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; /** * Base class for all ballots like compensation request, generic request, remove asset ballots and @@ -41,10 +43,11 @@ * * One proposal has about 278 bytes */ +@Immutable @Slf4j @Getter @EqualsAndHashCode -public final class Ballot implements PersistablePayload, ConsensusCritical { +public final class Ballot implements PersistablePayload, ConsensusCritical, ImmutableDaoStateVo { protected final Proposal proposal; @Nullable diff --git a/core/src/main/java/bisq/core/dao/governance/ballot/BallotList.java b/core/src/main/java/bisq/core/dao/governance/ballot/BallotList.java index f650e71eab5..101033303fc 100644 --- a/core/src/main/java/bisq/core/dao/governance/ballot/BallotList.java +++ b/core/src/main/java/bisq/core/dao/governance/ballot/BallotList.java @@ -18,6 +18,7 @@ package bisq.core.dao.governance.ballot; import bisq.core.dao.governance.ConsensusCritical; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.common.proto.persistable.PersistableList; @@ -29,11 +30,14 @@ import lombok.EqualsAndHashCode; +import javax.annotation.concurrent.Immutable; + /** * PersistableEnvelope wrapper for list of ballots. */ +@Immutable @EqualsAndHashCode(callSuper = true) -public class BallotList extends PersistableList implements ConsensusCritical { +public class BallotList extends PersistableList implements ConsensusCritical, ImmutableDaoStateVo { public BallotList(List list) { super(list); diff --git a/core/src/main/java/bisq/core/dao/governance/ballot/vote/Vote.java b/core/src/main/java/bisq/core/dao/governance/ballot/vote/Vote.java index 26d4b412713..8ee2f96c7c2 100644 --- a/core/src/main/java/bisq/core/dao/governance/ballot/vote/Vote.java +++ b/core/src/main/java/bisq/core/dao/governance/ballot/vote/Vote.java @@ -18,6 +18,7 @@ package bisq.core.dao.governance.ballot.vote; import bisq.core.dao.governance.ConsensusCritical; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.common.proto.network.NetworkPayload; import bisq.common.proto.persistable.PersistablePayload; @@ -28,8 +29,11 @@ import lombok.Value; +import javax.annotation.concurrent.Immutable; + +@Immutable @Value -public class Vote implements PersistablePayload, NetworkPayload, ConsensusCritical { +public class Vote implements PersistablePayload, NetworkPayload, ConsensusCritical, ImmutableDaoStateVo { private boolean accepted; public Vote(boolean accepted) { diff --git a/core/src/main/java/bisq/core/dao/governance/merit/Merit.java b/core/src/main/java/bisq/core/dao/governance/merit/Merit.java index d0633ec7db2..20a53c13a39 100644 --- a/core/src/main/java/bisq/core/dao/governance/merit/Merit.java +++ b/core/src/main/java/bisq/core/dao/governance/merit/Merit.java @@ -18,6 +18,7 @@ package bisq.core.dao.governance.merit; import bisq.core.dao.governance.ConsensusCritical; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.core.dao.state.governance.Issuance; import bisq.common.proto.network.NetworkPayload; @@ -31,8 +32,11 @@ import lombok.EqualsAndHashCode; import lombok.Getter; +import javax.annotation.concurrent.Immutable; + +@Immutable @EqualsAndHashCode -public class Merit implements PersistablePayload, NetworkPayload, ConsensusCritical { +public class Merit implements PersistablePayload, NetworkPayload, ConsensusCritical, ImmutableDaoStateVo { @Getter private final Issuance issuance; @Getter diff --git a/core/src/main/java/bisq/core/dao/governance/merit/MeritList.java b/core/src/main/java/bisq/core/dao/governance/merit/MeritList.java index 7332257bf24..debeba02a84 100644 --- a/core/src/main/java/bisq/core/dao/governance/merit/MeritList.java +++ b/core/src/main/java/bisq/core/dao/governance/merit/MeritList.java @@ -18,6 +18,7 @@ package bisq.core.dao.governance.merit; import bisq.core.dao.governance.ConsensusCritical; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.common.proto.persistable.PersistableList; @@ -31,10 +32,13 @@ import lombok.EqualsAndHashCode; +import javax.annotation.concurrent.Immutable; + // We don't persist that list but use it only for encoding the MeritList list // to PB bytes in the blindVote. +@Immutable @EqualsAndHashCode(callSuper = true) -public class MeritList extends PersistableList implements ConsensusCritical { +public class MeritList extends PersistableList implements ConsensusCritical, ImmutableDaoStateVo { public MeritList(List list) { super(list); diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java index 9db55016894..bcf1f2242e3 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java @@ -25,6 +25,7 @@ import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; import bisq.core.dao.governance.proposal.role.RoleProposal; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; @@ -51,7 +52,7 @@ @Slf4j @Getter @EqualsAndHashCode -public abstract class Proposal implements PersistablePayload, NetworkPayload, ConsensusCritical { +public abstract class Proposal implements PersistablePayload, NetworkPayload, ConsensusCritical, ImmutableDaoStateVo { protected final String name; protected final String link; protected final byte version; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposal.java index 5fc6d3a3048..7e5cda722bf 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposal.java @@ -21,6 +21,7 @@ import bisq.core.dao.governance.proposal.IssuanceProposal; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; @@ -44,7 +45,7 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class CompensationProposal extends Proposal implements IssuanceProposal { +public final class CompensationProposal extends Proposal implements IssuanceProposal, ImmutableDaoStateVo { private final long requestedBsq; private final String bsqAddress; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposal.java index e66b61b7e8a..c344a0fb5de 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposal.java @@ -19,6 +19,7 @@ import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; @@ -41,7 +42,7 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class ConfiscateBondProposal extends Proposal { +public final class ConfiscateBondProposal extends Proposal implements ImmutableDaoStateVo { private final byte[] hash; ConfiscateBondProposal(String name, diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposal.java index 706cca27cd3..a13215e1850 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposal.java @@ -19,6 +19,7 @@ import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; @@ -38,7 +39,7 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class GenericProposal extends Proposal { +public final class GenericProposal extends Proposal implements ImmutableDaoStateVo { GenericProposal(String name, String link) { diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java index 74483113046..c1a65bc3d92 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java @@ -19,6 +19,7 @@ import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; @@ -37,7 +38,7 @@ @Immutable @Slf4j @Value -public final class ChangeParamProposal extends Proposal { +public final class ChangeParamProposal extends Proposal implements ImmutableDaoStateVo { private final Param param; private final String paramValue; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposal.java index 2a1b0075c1c..f51611fcf0f 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposal.java @@ -21,6 +21,7 @@ import bisq.core.dao.governance.proposal.IssuanceProposal; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; @@ -44,7 +45,7 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class ReimbursementProposal extends Proposal implements IssuanceProposal { +public final class ReimbursementProposal extends Proposal implements IssuanceProposal, ImmutableDaoStateVo { private final long requestedBsq; private final String bsqAddress; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposal.java index 5f497aa022c..ca513de20e7 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposal.java @@ -19,6 +19,7 @@ import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; @@ -38,7 +39,7 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class RemoveAssetProposal extends Proposal { +public final class RemoveAssetProposal extends Proposal implements ImmutableDaoStateVo { private final String tickerSymbol; RemoveAssetProposal(String name, diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposal.java b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposal.java index 53f322246ec..ef801baca64 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposal.java @@ -20,6 +20,7 @@ import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; import bisq.core.dao.governance.role.Role; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; @@ -39,7 +40,7 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class RoleProposal extends Proposal { +public final class RoleProposal extends Proposal implements ImmutableDaoStateVo { private final Role role; RoleProposal(Role role) { diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/DecryptedBallotsWithMerits.java b/core/src/main/java/bisq/core/dao/governance/voteresult/DecryptedBallotsWithMerits.java index 6b6dd730d4a..25e65765f24 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/DecryptedBallotsWithMerits.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/DecryptedBallotsWithMerits.java @@ -23,6 +23,7 @@ import bisq.core.dao.governance.merit.MeritConsensus; import bisq.core.dao.governance.merit.MeritList; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.common.proto.persistable.PersistablePayload; import bisq.common.util.Utilities; @@ -36,12 +37,15 @@ import lombok.Value; import lombok.extern.slf4j.Slf4j; +import javax.annotation.concurrent.Immutable; + /** * Holds all data from a decrypted vote item. */ +@Immutable @Slf4j @Value -public class DecryptedBallotsWithMerits implements PersistablePayload { +public class DecryptedBallotsWithMerits implements PersistablePayload, ImmutableDaoStateVo { private final byte[] hashOfBlindVoteList; private final String blindVoteTxId; private final String voteRevealTxId; diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/EvaluatedProposal.java b/core/src/main/java/bisq/core/dao/governance/voteresult/EvaluatedProposal.java index 2982f7cde7f..1b219dc4c8b 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/EvaluatedProposal.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/EvaluatedProposal.java @@ -18,6 +18,7 @@ package bisq.core.dao.governance.voteresult; import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.common.proto.persistable.PersistablePayload; @@ -25,8 +26,11 @@ import lombok.Value; +import javax.annotation.concurrent.Immutable; + +@Immutable @Value -public class EvaluatedProposal implements PersistablePayload { +public class EvaluatedProposal implements PersistablePayload, ImmutableDaoStateVo { private final boolean isAccepted; private final ProposalVoteResult proposalVoteResult; diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/ProposalVoteResult.java b/core/src/main/java/bisq/core/dao/governance/voteresult/ProposalVoteResult.java index 14b0d3172d8..2ff4c372beb 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/ProposalVoteResult.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/ProposalVoteResult.java @@ -18,6 +18,7 @@ package bisq.core.dao.governance.voteresult; import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.state.ImmutableDaoStateVo; import bisq.common.proto.persistable.PersistablePayload; @@ -26,11 +27,14 @@ import lombok.Value; import lombok.extern.slf4j.Slf4j; +import javax.annotation.concurrent.Immutable; + import static com.google.common.base.Preconditions.checkArgument; +@Immutable @Value @Slf4j -public class ProposalVoteResult implements PersistablePayload { +public class ProposalVoteResult implements PersistablePayload, ImmutableDaoStateVo { private final Proposal proposal; private final long stakeOfAcceptedVotes; private final long stakeOfRejectedVotes; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java b/core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java index f98261b564c..ebc6c4b4f7f 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java @@ -17,8 +17,6 @@ package bisq.core.dao.state.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; - import io.bisq.generated.protobuffer.PB; import java.util.Optional; @@ -34,7 +32,7 @@ */ @Immutable @Data -public abstract class BaseBlock implements ImmutableDaoStateVo { +public abstract class BaseBlock { protected final int height; protected final long time; // in ms protected final String hash; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java b/core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java index 6329a055204..2503f07bb13 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java @@ -17,8 +17,6 @@ package bisq.core.dao.state.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; - import io.bisq.generated.protobuffer.PB; import com.google.common.collect.ImmutableList; @@ -42,7 +40,7 @@ @Slf4j @Getter @EqualsAndHashCode -public abstract class BaseTx implements ImmutableDaoStateVo { +public abstract class BaseTx { protected final String txVersion; protected final String id; protected final int blockHeight; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java b/core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java index 08c1f18f130..e66e9f06e0e 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java @@ -17,8 +17,6 @@ package bisq.core.dao.state.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; - import bisq.common.util.JsonExclude; import bisq.common.util.Utilities; @@ -40,7 +38,7 @@ @Slf4j @Immutable @Data -public abstract class BaseTxOutput implements ImmutableDaoStateVo { +public abstract class BaseTxOutput { protected final int index; protected final long value; protected final String txId; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/Block.java b/core/src/main/java/bisq/core/dao/state/blockchain/Block.java index d69dd26998e..aad0ee530c4 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/Block.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/Block.java @@ -17,8 +17,6 @@ package bisq.core.dao.state.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; - import bisq.common.proto.persistable.PersistablePayload; import io.bisq.generated.protobuffer.PB; @@ -35,11 +33,16 @@ /** * The Block which gets persisted in the DaoState. During parsing transactions can be * added to the txs list, therefore it is not an immutable list. - * // TODO make it fully immutable + * + * It is difficult to make the block immutable by using the same pattern we use with Tx or TxOutput because we add the + * block at the beginning of the parsing to the daoState and add transactions during parsing. We need to have the state + * updated during parsing. If we would set then after the parsing the immutable block we might have inconsistent data. + * There might be a way to do it but it comes with high complexity and risks so for now we prefer to have that known + * issue with not being fully immutable at that level. */ @EqualsAndHashCode(callSuper = true) @Value -public final class Block extends BaseBlock implements PersistablePayload, ImmutableDaoStateVo { +public final class Block extends BaseBlock implements PersistablePayload { private final List txs; public Block(int height, long time, String hash, String previousBlockHash) { diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/OpReturnType.java b/core/src/main/java/bisq/core/dao/state/blockchain/OpReturnType.java index b9ce6970029..bea29be71c3 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/OpReturnType.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/OpReturnType.java @@ -17,16 +17,20 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import java.util.Arrays; import java.util.Optional; import lombok.Getter; +import javax.annotation.concurrent.Immutable; + /** * Provides byte constants for distinguishing the type of a DAO transaction used in the OP_RETURN data. */ - -public enum OpReturnType { +@Immutable +public enum OpReturnType implements ImmutableDaoStateVo { //TODO add undefined ? PROPOSAL((byte) 0x10), COMPENSATION_REQUEST((byte) 0x11), diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/ScriptType.java b/core/src/main/java/bisq/core/dao/state/blockchain/ScriptType.java index 523f9928f5c..7758fb9ff73 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/ScriptType.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/ScriptType.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.ProtoUtil; import io.bisq.generated.protobuffer.PB; @@ -29,11 +31,14 @@ import lombok.AllArgsConstructor; import lombok.ToString; +import javax.annotation.concurrent.Immutable; + @ToString +@Immutable @AllArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -public enum ScriptType { +public enum ScriptType implements ImmutableDaoStateVo { // https://github.com/bitcoin/bitcoin/blob/master/src/script/standard.cpp PUB_KEY("pubkey"), diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/SpentInfo.java b/core/src/main/java/bisq/core/dao/state/blockchain/SpentInfo.java index c5a6852901d..0dfb5c5738b 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/SpentInfo.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/SpentInfo.java @@ -17,15 +17,19 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.persistable.PersistablePayload; import io.bisq.generated.protobuffer.PB; import lombok.Value; -// Only used for json export +import javax.annotation.concurrent.Immutable; + +@Immutable @Value -public final class SpentInfo implements PersistablePayload { +public final class SpentInfo implements PersistablePayload, ImmutableDaoStateVo { private final long blockHeight; // Spending tx private final String txId; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java b/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java index 6c35e88be38..efd030bfac9 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java @@ -28,6 +28,7 @@ import lombok.Data; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; /** * Contains immutable BSQ specific data (TxOutputType) and is used to get @@ -35,6 +36,7 @@ * TempTxOutput get converted to immutable TxOutput after tx parsing is completed. * Gets persisted. */ +@Immutable @Data public class TxOutput extends BaseTxOutput implements PersistablePayload, ImmutableDaoStateVo { public static TxOutput fromTempOutput(TempTxOutput tempTxOutput) { diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputKey.java b/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputKey.java index 2b0648750c3..75ef199f726 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputKey.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputKey.java @@ -17,10 +17,19 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import lombok.Value; +import javax.annotation.concurrent.Immutable; + +/** + * Convenience object for identifying a TxOutput. + * Used as key in maps in the daoState. + */ +@Immutable @Value -public final class TxOutputKey { +public final class TxOutputKey implements ImmutableDaoStateVo { private final String txId; private final int index; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputType.java b/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputType.java index 531d82f1876..e97d42adcec 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputType.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputType.java @@ -17,11 +17,16 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.ProtoUtil; import io.bisq.generated.protobuffer.PB; -public enum TxOutputType { +import javax.annotation.concurrent.Immutable; + +@Immutable +public enum TxOutputType implements ImmutableDaoStateVo { UNDEFINED_OUTPUT, GENESIS_OUTPUT, BSQ_OUTPUT, diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxType.java b/core/src/main/java/bisq/core/dao/state/blockchain/TxType.java index 8b3ab45db50..081442e41ae 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxType.java +++ b/core/src/main/java/bisq/core/dao/state/blockchain/TxType.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.blockchain; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.ProtoUtil; import io.bisq.generated.protobuffer.PB; @@ -24,8 +26,10 @@ import lombok.Getter; import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; -public enum TxType { +@Immutable +public enum TxType implements ImmutableDaoStateVo { UNDEFINED_TX_TYPE(false, false), UNVERIFIED(false, false), INVALID(false, false), diff --git a/core/src/main/java/bisq/core/dao/state/governance/Issuance.java b/core/src/main/java/bisq/core/dao/state/governance/Issuance.java index 4fed7f7afe6..86e3807e6fc 100644 --- a/core/src/main/java/bisq/core/dao/state/governance/Issuance.java +++ b/core/src/main/java/bisq/core/dao/state/governance/Issuance.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.governance; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.ProtoUtil; import bisq.common.proto.network.NetworkPayload; import bisq.common.proto.persistable.PersistablePayload; @@ -36,7 +38,7 @@ */ @Immutable @Value -public class Issuance implements PersistablePayload, NetworkPayload { +public class Issuance implements PersistablePayload, NetworkPayload, ImmutableDaoStateVo { private final String txId; // comp. request txId private final int chainHeight; // of issuance (first block of result phase) private final long amount; diff --git a/core/src/main/java/bisq/core/dao/state/governance/IssuanceType.java b/core/src/main/java/bisq/core/dao/state/governance/IssuanceType.java index 99778e50e1f..7a58ecf4437 100644 --- a/core/src/main/java/bisq/core/dao/state/governance/IssuanceType.java +++ b/core/src/main/java/bisq/core/dao/state/governance/IssuanceType.java @@ -17,7 +17,12 @@ package bisq.core.dao.state.governance; -public enum IssuanceType { +import bisq.core.dao.state.ImmutableDaoStateVo; + +import javax.annotation.concurrent.Immutable; + +@Immutable +public enum IssuanceType implements ImmutableDaoStateVo { UNDEFINED, COMPENSATION, REIMBURSEMENT diff --git a/core/src/main/java/bisq/core/dao/state/governance/ParamChange.java b/core/src/main/java/bisq/core/dao/state/governance/ParamChange.java index 73890af0dce..0a0d2670c7a 100644 --- a/core/src/main/java/bisq/core/dao/state/governance/ParamChange.java +++ b/core/src/main/java/bisq/core/dao/state/governance/ParamChange.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.governance; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.persistable.PersistablePayload; import io.bisq.generated.protobuffer.PB; @@ -30,7 +32,7 @@ */ @Immutable @Value -public class ParamChange implements PersistablePayload { +public class ParamChange implements PersistablePayload, ImmutableDaoStateVo { // We use the enum name instead of the enum to be more flexible with changes at updates private final String paramName; private final String value; diff --git a/core/src/main/java/bisq/core/dao/state/period/Cycle.java b/core/src/main/java/bisq/core/dao/state/period/Cycle.java index 8056aa99083..57d6720f50c 100644 --- a/core/src/main/java/bisq/core/dao/state/period/Cycle.java +++ b/core/src/main/java/bisq/core/dao/state/period/Cycle.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.period; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.persistable.PersistablePayload; import io.bisq.generated.protobuffer.PB; @@ -36,7 +38,7 @@ */ @Immutable @Value -public class Cycle implements PersistablePayload { +public class Cycle implements PersistablePayload, ImmutableDaoStateVo { // List is ordered according to the Phase enum. private final ImmutableList daoPhaseList; private final int heightOfFirstBlock; diff --git a/core/src/main/java/bisq/core/dao/state/period/DaoPhase.java b/core/src/main/java/bisq/core/dao/state/period/DaoPhase.java index c81d3c5958e..e5d9a48e6e1 100644 --- a/core/src/main/java/bisq/core/dao/state/period/DaoPhase.java +++ b/core/src/main/java/bisq/core/dao/state/period/DaoPhase.java @@ -17,6 +17,8 @@ package bisq.core.dao.state.period; +import bisq.core.dao.state.ImmutableDaoStateVo; + import bisq.common.proto.persistable.PersistablePayload; import io.bisq.generated.protobuffer.PB; @@ -33,7 +35,7 @@ */ @Immutable @Value -public class DaoPhase implements PersistablePayload { +public class DaoPhase implements PersistablePayload, ImmutableDaoStateVo { /** * Enum for phase of a cycle. @@ -41,7 +43,8 @@ public class DaoPhase implements PersistablePayload { * We don't want to use a enum with the duration as field because the duration can change by voting and enums * should be considered immutable. */ - public enum Phase { + @Immutable + public enum Phase implements ImmutableDaoStateVo { UNDEFINED, PROPOSAL, BREAK1, From 8dabd555c873d0a56bb64d76fdce93cab4661a25 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 16:13:24 -0500 Subject: [PATCH 11/27] Move service classes out of daostate package - we want to have only those classes in the daoState package which are stored in the daoState and immutable --- core/src/main/java/bisq/core/dao/DaoFacade.java | 2 +- core/src/main/java/bisq/core/dao/DaoModule.java | 4 ++-- core/src/main/java/bisq/core/dao/DaoSetup.java | 2 +- .../core/dao/governance/ballot/BallotListPresentation.java | 2 +- .../bisq/core/dao/governance/ballot/BallotListService.java | 2 +- .../core/dao/governance/blindvote/BlindVoteValidator.java | 2 +- .../core/dao/governance/blindvote/MyBlindVoteListService.java | 2 +- .../core/dao/governance/proposal/MyProposalListService.java | 2 +- .../bisq/core/dao/governance/proposal/ProposalService.java | 2 +- .../bisq/core/dao/governance/proposal/ProposalValidator.java | 2 +- .../proposal/compensation/CompensationValidator.java | 2 +- .../proposal/confiscatebond/ConfiscateBondValidator.java | 2 +- .../governance/proposal/generic/GenericProposalValidator.java | 2 +- .../dao/governance/proposal/param/ChangeParamValidator.java | 2 +- .../proposal/reimbursement/ReimbursementValidator.java | 2 +- .../governance/proposal/removeAsset/RemoveAssetValidator.java | 2 +- .../bisq/core/dao/governance/proposal/role/RoleValidator.java | 2 +- .../core/dao/governance/voteresult/VoteResultConsensus.java | 2 +- .../core/dao/governance/voteresult/VoteResultService.java | 2 +- .../dao/governance/voteresult/issuance/IssuanceService.java | 2 +- .../core/dao/governance/votereveal/VoteRevealService.java | 2 +- core/src/main/java/bisq/core/dao/node/parser/TxParser.java | 2 +- .../java/bisq/core/dao/{state => }/period/CycleService.java | 4 +++- .../java/bisq/core/dao/{state => }/period/PeriodService.java | 4 +++- core/src/main/java/bisq/core/dao/state/period/Cycle.java | 2 +- core/src/main/java/bisq/core/provider/fee/FeeService.java | 2 +- .../desktop/main/dao/governance/result/VoteResultView.java | 2 +- 27 files changed, 32 insertions(+), 28 deletions(-) rename core/src/main/java/bisq/core/dao/{state => }/period/CycleService.java (98%) rename core/src/main/java/bisq/core/dao/{state => }/period/PeriodService.java (97%) diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index db5e523a73d..d906566d92d 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -52,6 +52,7 @@ import bisq.core.dao.governance.role.BondedRole; import bisq.core.dao.governance.role.BondedRolesService; import bisq.core.dao.governance.role.Role; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateStorageService; @@ -63,7 +64,6 @@ import bisq.core.dao.state.governance.IssuanceType; import bisq.core.dao.state.governance.Param; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import bisq.asset.Asset; diff --git a/core/src/main/java/bisq/core/dao/DaoModule.java b/core/src/main/java/bisq/core/dao/DaoModule.java index 653b00b449e..e961efcee53 100644 --- a/core/src/main/java/bisq/core/dao/DaoModule.java +++ b/core/src/main/java/bisq/core/dao/DaoModule.java @@ -66,13 +66,13 @@ import bisq.core.dao.node.lite.network.LiteNodeNetworkService; import bisq.core.dao.node.parser.BlockParser; import bisq.core.dao.node.parser.TxParser; +import bisq.core.dao.period.CycleService; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoState; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateSnapshotService; import bisq.core.dao.state.DaoStateStorageService; import bisq.core.dao.state.GenesisTxInfo; -import bisq.core.dao.state.period.CycleService; -import bisq.core.dao.state.period.PeriodService; import bisq.common.app.AppModule; diff --git a/core/src/main/java/bisq/core/dao/DaoSetup.java b/core/src/main/java/bisq/core/dao/DaoSetup.java index cbeedb8b24b..d6120ea1343 100644 --- a/core/src/main/java/bisq/core/dao/DaoSetup.java +++ b/core/src/main/java/bisq/core/dao/DaoSetup.java @@ -27,8 +27,8 @@ import bisq.core.dao.node.BsqNode; import bisq.core.dao.node.BsqNodeProvider; import bisq.core.dao.node.json.ExportJsonFilesService; +import bisq.core.dao.period.CycleService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.period.CycleService; import bisq.common.handlers.ErrorMessageHandler; diff --git a/core/src/main/java/bisq/core/dao/governance/ballot/BallotListPresentation.java b/core/src/main/java/bisq/core/dao/governance/ballot/BallotListPresentation.java index f1f205d3daa..cca4da9a84b 100644 --- a/core/src/main/java/bisq/core/dao/governance/ballot/BallotListPresentation.java +++ b/core/src/main/java/bisq/core/dao/governance/ballot/BallotListPresentation.java @@ -18,10 +18,10 @@ package bisq.core.dao.governance.ballot; import bisq.core.dao.governance.proposal.ProposalValidator; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.period.PeriodService; import com.google.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/ballot/BallotListService.java b/core/src/main/java/bisq/core/dao/governance/ballot/BallotListService.java index e0081c0f383..450a0733800 100644 --- a/core/src/main/java/bisq/core/dao/governance/ballot/BallotListService.java +++ b/core/src/main/java/bisq/core/dao/governance/ballot/BallotListService.java @@ -23,7 +23,7 @@ import bisq.core.dao.governance.proposal.ProposalService; import bisq.core.dao.governance.proposal.ProposalValidator; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalPayload; -import bisq.core.dao.state.period.PeriodService; +import bisq.core.dao.period.PeriodService; import bisq.common.proto.persistable.PersistedDataHost; import bisq.common.storage.Storage; diff --git a/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteValidator.java b/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteValidator.java index 06df49fa291..65f57e734e8 100644 --- a/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteValidator.java @@ -18,10 +18,10 @@ package bisq.core.dao.governance.blindvote; import bisq.core.dao.exceptions.ValidationException; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java b/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java index f8bbf4e937f..3a00c22438b 100644 --- a/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java +++ b/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java @@ -38,12 +38,12 @@ import bisq.core.dao.governance.proposal.MyProposalListService; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.compensation.CompensationProposal; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.governance.IssuanceType; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import bisq.network.p2p.P2PService; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java b/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java index 2ac5efeac83..48514a4177e 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java @@ -23,12 +23,12 @@ import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsManager; import bisq.core.dao.governance.proposal.storage.temp.TempProposalPayload; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import bisq.network.p2p.P2PService; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalService.java index 64d44a710a2..11572e4425e 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalService.java @@ -23,11 +23,11 @@ import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStorageService; import bisq.core.dao.governance.proposal.storage.temp.TempProposalPayload; import bisq.core.dao.governance.proposal.storage.temp.TempProposalStorageService; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import bisq.network.p2p.P2PService; import bisq.network.p2p.storage.HashMapChangedListener; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalValidator.java index 4325362cd02..5fbec0f885c 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalValidator.java @@ -20,11 +20,11 @@ import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.proposal.compensation.CompensationProposal; import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationValidator.java index 86dc856d377..f2a4e289fb8 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationValidator.java @@ -20,8 +20,8 @@ import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalValidator; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.period.PeriodService; import org.bitcoinj.core.Coin; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondValidator.java index 520e2d84daa..54d46829d14 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondValidator.java @@ -20,8 +20,8 @@ import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalValidator; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.period.PeriodService; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalValidator.java index eac86dbdd05..cbf7732a765 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalValidator.java @@ -20,8 +20,8 @@ import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalValidator; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.period.PeriodService; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamValidator.java index da4793ba843..196ae8900fd 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamValidator.java @@ -21,9 +21,9 @@ import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalValidator; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.governance.Param; -import bisq.core.dao.state.period.PeriodService; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.validation.BtcAddressValidator; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementValidator.java index 996e1750f1a..3ba812ad70f 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementValidator.java @@ -20,8 +20,8 @@ import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalValidator; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.period.PeriodService; import org.bitcoinj.core.Coin; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetValidator.java index b3bafdf92ad..495ffc1bc4e 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetValidator.java @@ -20,8 +20,8 @@ import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalValidator; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.period.PeriodService; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleValidator.java index 5c31fa18f51..ce331f4ec3c 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleValidator.java @@ -21,8 +21,8 @@ import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalValidator; import bisq.core.dao.governance.role.Role; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.period.PeriodService; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultConsensus.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultConsensus.java index 776beadda2a..5fa1808f038 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultConsensus.java @@ -18,6 +18,7 @@ package bisq.core.dao.governance.voteresult; import bisq.core.dao.governance.blindvote.VoteWithProposalTxIdList; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxInput; @@ -25,7 +26,6 @@ import bisq.core.dao.state.blockchain.TxOutputType; import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import bisq.common.crypto.Encryption; import bisq.common.util.Utilities; diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java index 1fdf7dd785a..036710fcac5 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java @@ -42,6 +42,7 @@ import bisq.core.dao.governance.voteresult.issuance.IssuanceService; import bisq.core.dao.governance.votereveal.VoteRevealConsensus; import bisq.core.dao.governance.votereveal.VoteRevealService; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Block; @@ -50,7 +51,6 @@ import bisq.core.dao.state.governance.ConfiscateBond; import bisq.core.dao.state.governance.ParamChange; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import bisq.core.locale.CurrencyUtil; import bisq.network.p2p.storage.P2PDataStorage; diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/issuance/IssuanceService.java b/core/src/main/java/bisq/core/dao/governance/voteresult/issuance/IssuanceService.java index 1e1bf3e5e7a..47aad2ab66c 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/issuance/IssuanceService.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/issuance/IssuanceService.java @@ -20,6 +20,7 @@ import bisq.core.dao.governance.proposal.IssuanceProposal; import bisq.core.dao.governance.proposal.compensation.CompensationProposal; import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Tx; import bisq.core.dao.state.blockchain.TxInput; @@ -27,7 +28,6 @@ import bisq.core.dao.state.governance.Issuance; import bisq.core.dao.state.governance.IssuanceType; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java b/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java index 20dbe9ca556..246d59ffa97 100644 --- a/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java +++ b/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java @@ -33,12 +33,12 @@ import bisq.core.dao.governance.blindvote.storage.BlindVotePayload; import bisq.core.dao.governance.myvote.MyVote; import bisq.core.dao.governance.myvote.MyVoteListService; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.blockchain.TxOutput; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import bisq.network.p2p.P2PService; diff --git a/core/src/main/java/bisq/core/dao/node/parser/TxParser.java b/core/src/main/java/bisq/core/dao/node/parser/TxParser.java index 52894b3a126..332ce3cfa62 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/TxParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/TxParser.java @@ -17,6 +17,7 @@ package bisq.core.dao.node.parser; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.OpReturnType; import bisq.core.dao.state.blockchain.RawTx; @@ -30,7 +31,6 @@ import bisq.core.dao.state.blockchain.TxType; import bisq.core.dao.state.governance.Param; import bisq.core.dao.state.period.DaoPhase; -import bisq.core.dao.state.period.PeriodService; import org.bitcoinj.core.Coin; diff --git a/core/src/main/java/bisq/core/dao/state/period/CycleService.java b/core/src/main/java/bisq/core/dao/period/CycleService.java similarity index 98% rename from core/src/main/java/bisq/core/dao/state/period/CycleService.java rename to core/src/main/java/bisq/core/dao/period/CycleService.java index 083a9e326eb..4a2496f7da7 100644 --- a/core/src/main/java/bisq/core/dao/state/period/CycleService.java +++ b/core/src/main/java/bisq/core/dao/period/CycleService.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.period; +package bisq.core.dao.period; import bisq.core.dao.DaoSetupService; import bisq.core.dao.state.DaoStateListener; @@ -23,6 +23,8 @@ import bisq.core.dao.state.GenesisTxInfo; import bisq.core.dao.state.blockchain.Block; import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.period.Cycle; +import bisq.core.dao.state.period.DaoPhase; import com.google.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/state/period/PeriodService.java b/core/src/main/java/bisq/core/dao/period/PeriodService.java similarity index 97% rename from core/src/main/java/bisq/core/dao/state/period/PeriodService.java rename to core/src/main/java/bisq/core/dao/period/PeriodService.java index ce52bbef4ac..abc133600b9 100644 --- a/core/src/main/java/bisq/core/dao/state/period/PeriodService.java +++ b/core/src/main/java/bisq/core/dao/period/PeriodService.java @@ -15,10 +15,12 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.period; +package bisq.core.dao.period; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.period.Cycle; +import bisq.core.dao.state.period.DaoPhase; import com.google.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/state/period/Cycle.java b/core/src/main/java/bisq/core/dao/state/period/Cycle.java index 57d6720f50c..2d2f05cfc73 100644 --- a/core/src/main/java/bisq/core/dao/state/period/Cycle.java +++ b/core/src/main/java/bisq/core/dao/state/period/Cycle.java @@ -48,7 +48,7 @@ public class Cycle implements PersistablePayload, ImmutableDaoStateVo { // Constructor /////////////////////////////////////////////////////////////////////////////////////////// - Cycle(int heightOfFirstBlock, ImmutableList daoPhaseList) { + public Cycle(int heightOfFirstBlock, ImmutableList daoPhaseList) { this.heightOfFirstBlock = heightOfFirstBlock; this.daoPhaseList = daoPhaseList; } diff --git a/core/src/main/java/bisq/core/provider/fee/FeeService.java b/core/src/main/java/bisq/core/provider/fee/FeeService.java index 609173455cd..9320ba1a209 100644 --- a/core/src/main/java/bisq/core/provider/fee/FeeService.java +++ b/core/src/main/java/bisq/core/provider/fee/FeeService.java @@ -18,9 +18,9 @@ package bisq.core.provider.fee; import bisq.core.app.BisqEnvironment; +import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.governance.Param; -import bisq.core.dao.state.period.PeriodService; import bisq.common.UserThread; import bisq.common.handlers.FaultHandler; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java index 699fbecadc4..507a9680d3c 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java @@ -36,10 +36,10 @@ import bisq.core.dao.governance.voteresult.DecryptedBallotsWithMerits; import bisq.core.dao.governance.voteresult.EvaluatedProposal; import bisq.core.dao.governance.voteresult.VoteResultService; +import bisq.core.dao.period.CycleService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.period.CycleService; import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; From a3e01759b01585e5fd8a2d93428ad14c89a2ac4d Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 17:11:39 -0500 Subject: [PATCH 12/27] Moving classes That was a big commit with restructuring the packages and classes. Motivation was to isolate the daoState value objects so it is more clear which data are help in the daoState. As it was hard to keep an overview and easy to add mutable data I think that makes it more safe overall. I am aware that the downside to take out domain models from the domain packages is not so nice. Also moved blockchain models to parser and full node packages. --- .../core/app/misc/AppSetupWithP2PAndDAO.java | 2 +- .../bisq/core/btc/wallet/BsqCoinSelector.java | 2 +- .../core/btc/wallet/BsqWalletService.java | 8 +- .../core/btc/wallet/NonBsqCoinSelector.java | 2 +- .../main/java/bisq/core/dao/DaoFacade.java | 42 ++--- .../main/java/bisq/core/dao/DaoModule.java | 16 +- .../src/main/java/bisq/core/dao/DaoSetup.java | 4 +- .../dao/exceptions/ValidationException.java | 2 +- .../ballot/BallotListPresentation.java | 5 +- .../governance/ballot/BallotListService.java | 6 +- .../blindvote/BlindVoteConsensus.java | 10 +- .../blindvote/BlindVoteListService.java | 2 +- .../blindvote/BlindVoteValidator.java | 6 +- .../blindvote/MyBlindVoteListService.java | 18 +-- .../blindvote/VoteWithProposalTxId.java | 2 +- .../governance/{role => bond}/BondedRole.java | 4 +- .../{role => bond}/BondedRolesService.java | 16 +- .../bond}/ConfiscateBond.java | 2 +- .../bonding/BondingConsensus.java | 8 +- .../bonding/bond/BondWithHash.java | 2 +- .../bonding/bond/BondedReputation.java | 2 +- .../bonding/bond/BondedReputationList.java | 2 +- .../bonding/bond/BondedReputationService.java | 10 +- .../bonding/lockup/LockupService.java | 10 +- .../bonding/lockup/LockupType.java | 2 +- .../bonding/unlock/UnlockService.java | 4 +- .../dao/governance/merit/MeritConsensus.java | 7 +- .../core/dao/governance/myvote/MyVote.java | 4 +- .../governance/myvote/MyVoteListService.java | 4 +- .../param}/Param.java | 2 +- .../param}/ParamType.java | 2 +- .../{ => governance}/period/CycleService.java | 10 +- .../period/PeriodService.java | 8 +- .../proposal/BaseProposalService.java | 3 +- .../governance/proposal/MyProposalList.java | 1 + .../proposal/MyProposalListService.java | 9 +- .../proposal/ProposalConsensus.java | 3 +- .../proposal/ProposalListPresentation.java | 3 +- .../governance/proposal/ProposalService.java | 7 +- .../proposal/ProposalValidator.java | 13 +- .../proposal/ProposalWithTransaction.java | 2 + .../compensation/CompensationConsensus.java | 2 +- .../CompensationProposalService.java | 5 +- .../compensation/CompensationValidator.java | 5 +- .../ConfiscateBondProposalService.java | 1 + .../ConfiscateBondValidator.java | 5 +- .../generic/GenericProposalService.java | 1 + .../generic/GenericProposalValidator.java | 5 +- .../param/ChangeParamInputValidator.java | 2 +- .../param/ChangeParamProposalService.java | 3 +- .../proposal/param/ChangeParamValidator.java | 7 +- .../reimbursement/ReimbursementConsensus.java | 2 +- .../ReimbursementProposalService.java | 5 +- .../reimbursement/ReimbursementValidator.java | 5 +- .../RemoveAssetProposalService.java | 7 +- .../removeAsset/RemoveAssetValidator.java | 5 +- .../proposal/role/RoleProposalService.java | 3 +- .../proposal/role/RoleValidator.java | 7 +- .../storage/appendonly/ProposalPayload.java | 2 +- .../storage/temp/TempProposalPayload.java | 2 +- .../voteresult/VoteResultConsensus.java | 14 +- .../voteresult/VoteResultException.java | 2 +- .../voteresult/VoteResultService.java | 39 ++--- .../voteresult/issuance/IssuanceService.java | 18 +-- .../votereveal/VoteRevealConsensus.java | 2 +- .../votereveal/VoteRevealService.java | 8 +- .../main/java/bisq/core/dao/node/BsqNode.java | 2 +- .../ExportJsonFilesService.java | 14 +- .../node/{json => explorer}/JsonBlock.java | 2 +- .../node/{json => explorer}/JsonBlocks.java | 2 +- .../{json => explorer}/JsonScriptPubKey.java | 4 +- .../{json => explorer}/JsonSpentInfo.java | 4 +- .../dao/node/{json => explorer}/JsonTx.java | 2 +- .../node/{json => explorer}/JsonTxInput.java | 2 +- .../node/{json => explorer}/JsonTxOutput.java | 2 +- .../{json => explorer}/JsonTxOutputType.java | 2 +- .../node/{json => explorer}/JsonTxType.java | 2 +- .../core/dao/node/explorer/package-info.java | 22 +++ .../bisq/core/dao/node/full/FullNode.java | 4 +- .../blockchain => node/full}/RawBlock.java | 15 +- .../blockchain => node/full}/RawTx.java | 18 ++- .../blockchain => node/full}/RawTxOutput.java | 20 ++- .../bisq/core/dao/node/full/RpcService.java | 7 +- .../full/network/FullNodeNetworkService.java | 4 +- .../full/network/GetBlocksRequestHandler.java | 4 +- .../bisq/core/dao/node/lite/LiteNode.java | 2 +- .../dao/node/messages/GetBlocksResponse.java | 2 +- .../messages/NewBlockBroadcastMessage.java | 2 +- .../core/dao/node/parser/BlockParser.java | 6 +- .../core/dao/node/parser/GenesisTxParser.java | 12 +- .../core/dao/node/parser/OpReturnParser.java | 9 +- .../blockchain => node/parser}/TempTx.java | 9 +- .../parser}/TempTxOutput.java | 9 +- .../core/dao/node/parser/TxInputParser.java | 8 +- .../core/dao/node/parser/TxOutputParser.java | 9 +- .../bisq/core/dao/node/parser/TxParser.java | 24 ++- .../BlockNotConnectingException.java | 2 +- .../exceptions/InvalidBlockException.java | 4 +- .../bisq/core/dao/state/DaoStateListener.java | 2 +- .../bisq/core/dao/state/DaoStateService.java | 39 ++--- .../dao/state/DaoStateSnapshotService.java | 3 +- .../dao/state/DaoStateStorageService.java | 4 +- .../bisq/core/dao/state/DaoStateStore.java | 2 + .../core/dao/state/{ => model}/DaoState.java | 43 ++--- .../ImmutableDaoStateModel.java} | 6 +- .../{ => model}/blockchain/BaseBlock.java | 10 +- .../state/{ => model}/blockchain/BaseTx.java | 20 +-- .../{ => model}/blockchain/BaseTxOutput.java | 22 +-- .../state/{ => model}/blockchain/Block.java | 6 +- .../{ => model}/blockchain/OpReturnType.java | 6 +- .../{ => model}/blockchain/PubKeyScript.java | 6 +- .../{ => model}/blockchain/ScriptType.java | 6 +- .../{ => model}/blockchain/SpentInfo.java | 6 +- .../dao/state/{ => model}/blockchain/Tx.java | 7 +- .../state/{ => model}/blockchain/TxInput.java | 6 +- .../{ => model}/blockchain/TxOutput.java | 7 +- .../{ => model}/blockchain/TxOutputKey.java | 6 +- .../{ => model}/blockchain/TxOutputType.java | 6 +- .../state/{ => model}/blockchain/TxType.java | 6 +- .../state/model/blockchain/package-info.java | 22 +++ .../dao/state/model/governance/Ballot.java | 115 ++++++++++++++ .../state/model/governance/BallotList.java | 80 ++++++++++ .../model/governance}/BondedRoleType.java | 2 +- .../governance}/ChangeParamProposal.java | 19 ++- .../governance}/CompensationProposal.java | 19 ++- .../governance}/ConfiscateBondProposal.java | 17 +- .../{period => model/governance}/Cycle.java | 6 +- .../governance}/DaoPhase.java | 8 +- .../DecryptedBallotsWithMerits.java | 10 +- .../model/governance}/EvaluatedProposal.java | 9 +- .../model/governance}/GenericProposal.java | 15 +- .../{ => model}/governance/Issuance.java | 6 +- .../{ => model}/governance/IssuanceType.java | 6 +- .../dao/state/model/governance/Merit.java | 78 +++++++++ .../model/governance}/MeritList.java | 6 +- .../{ => model}/governance/ParamChange.java | 6 +- .../model/governance}/Proposal.java | 18 +-- .../model/governance/ProposalVoteResult.java | 119 ++++++++++++++ .../governance}/ReimbursementProposal.java | 19 ++- .../governance}/RemoveAssetProposal.java | 17 +- .../core/dao/state/model/governance/Role.java | 149 ++++++++++++++++++ .../model/governance}/RoleProposal.java | 14 +- .../core/dao/state/model/governance/Vote.java | 57 +++++++ .../state/model/governance/package-info.java | 22 +++ .../core/dao/state/model/package-info.java | 25 +++ .../CorePersistenceProtoResolver.java | 4 +- .../bisq/core/provider/fee/FeeService.java | 4 +- .../core/setup/CorePersistedDataHost.java | 2 +- .../java/bisq/core/util/BsqFormatter.java | 2 +- .../core/dao/node/full/BlockParserTest.java | 6 +- .../dao/node/parser/GenesisTxParserTest.java | 11 +- .../core/dao/state/DaoStateServiceTest.java | 3 +- .../components/SeparatedPhaseBars.java | 2 +- .../main/dao/bonding/BondingViewUtils.java | 12 +- .../main/dao/bonding/lockup/LockupView.java | 8 +- .../bonding/roles/BondedRoleTypeWindow.java | 2 +- .../bonding/roles/BondedRolesListItem.java | 6 +- .../dao/bonding/roles/BondedRolesView.java | 4 +- .../dao/bonding/unlock/LockupTxListItem.java | 16 +- .../main/dao/bonding/unlock/UnlockView.java | 6 +- .../main/dao/governance/GovernanceView.java | 2 +- .../main/dao/governance/PhasesView.java | 4 +- .../main/dao/governance/ProposalDisplay.java | 32 ++-- .../dashboard/GovernanceDashboardView.java | 4 +- .../dao/governance/make/MakeProposalView.java | 10 +- .../proposals/ProposalsListItem.java | 8 +- .../governance/proposals/ProposalsView.java | 12 +- .../dao/governance/result/CycleListItem.java | 2 +- .../governance/result/ProposalListItem.java | 22 +-- .../dao/governance/result/ResultsOfCycle.java | 10 +- .../dao/governance/result/VoteListItem.java | 6 +- .../dao/governance/result/VoteResultView.java | 12 +- .../wallet/dashboard/BsqDashboardView.java | 4 +- .../main/dao/wallet/tx/BsqTxListItem.java | 2 +- .../desktop/main/dao/wallet/tx/BsqTxView.java | 6 +- .../transactions/TransactionsListItem.java | 2 +- 176 files changed, 1346 insertions(+), 617 deletions(-) rename core/src/main/java/bisq/core/dao/governance/{role => bond}/BondedRole.java (94%) rename core/src/main/java/bisq/core/dao/governance/{role => bond}/BondedRolesService.java (95%) rename core/src/main/java/bisq/core/dao/{state/governance => governance/bond}/ConfiscateBond.java (97%) rename core/src/main/java/bisq/core/dao/{ => governance}/bonding/BondingConsensus.java (93%) rename core/src/main/java/bisq/core/dao/{ => governance}/bonding/bond/BondWithHash.java (94%) rename core/src/main/java/bisq/core/dao/{ => governance}/bonding/bond/BondedReputation.java (98%) rename core/src/main/java/bisq/core/dao/{ => governance}/bonding/bond/BondedReputationList.java (98%) rename core/src/main/java/bisq/core/dao/{ => governance}/bonding/bond/BondedReputationService.java (96%) rename core/src/main/java/bisq/core/dao/{ => governance}/bonding/lockup/LockupService.java (94%) rename core/src/main/java/bisq/core/dao/{ => governance}/bonding/lockup/LockupType.java (96%) rename core/src/main/java/bisq/core/dao/{ => governance}/bonding/unlock/UnlockService.java (97%) rename core/src/main/java/bisq/core/dao/{state/governance => governance/param}/Param.java (99%) rename core/src/main/java/bisq/core/dao/{state/governance => governance/param}/ParamType.java (95%) rename core/src/main/java/bisq/core/dao/{ => governance}/period/CycleService.java (96%) rename core/src/main/java/bisq/core/dao/{ => governance}/period/PeriodService.java (96%) rename core/src/main/java/bisq/core/dao/node/{json => explorer}/ExportJsonFilesService.java (96%) rename core/src/main/java/bisq/core/dao/node/{json => explorer}/JsonBlock.java (96%) rename core/src/main/java/bisq/core/dao/node/{json => explorer}/JsonBlocks.java (95%) rename core/src/main/java/bisq/core/dao/node/{json => explorer}/JsonScriptPubKey.java (92%) rename core/src/main/java/bisq/core/dao/node/{json => explorer}/JsonSpentInfo.java (91%) rename core/src/main/java/bisq/core/dao/node/{json => explorer}/JsonTx.java (98%) rename core/src/main/java/bisq/core/dao/node/{json => explorer}/JsonTxInput.java (96%) rename core/src/main/java/bisq/core/dao/node/{json => explorer}/JsonTxOutput.java (98%) rename core/src/main/java/bisq/core/dao/node/{json => explorer}/JsonTxOutputType.java (97%) rename core/src/main/java/bisq/core/dao/node/{json => explorer}/JsonTxType.java (97%) create mode 100644 core/src/main/java/bisq/core/dao/node/explorer/package-info.java rename core/src/main/java/bisq/core/dao/{state/blockchain => node/full}/RawBlock.java (92%) rename core/src/main/java/bisq/core/dao/{state/blockchain => node/full}/RawTx.java (91%) rename core/src/main/java/bisq/core/dao/{state/blockchain => node/full}/RawTxOutput.java (85%) rename core/src/main/java/bisq/core/dao/{state/blockchain => node/parser}/TempTx.java (93%) rename core/src/main/java/bisq/core/dao/{state/blockchain => node/parser}/TempTxOutput.java (92%) rename core/src/main/java/bisq/core/dao/state/{ => model}/DaoState.java (90%) rename core/src/main/java/bisq/core/dao/state/{ImmutableDaoStateVo.java => model/ImmutableDaoStateModel.java} (83%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/BaseBlock.java (87%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/BaseTx.java (86%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/BaseTxOutput.java (85%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/Block.java (96%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/OpReturnType.java (90%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/PubKeyScript.java (96%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/ScriptType.java (94%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/SpentInfo.java (94%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/Tx.java (97%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/TxInput.java (96%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/TxOutput.java (96%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/TxOutputKey.java (88%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/TxOutputType.java (91%) rename core/src/main/java/bisq/core/dao/state/{ => model}/blockchain/TxType.java (92%) create mode 100644 core/src/main/java/bisq/core/dao/state/model/blockchain/package-info.java create mode 100644 core/src/main/java/bisq/core/dao/state/model/governance/Ballot.java create mode 100644 core/src/main/java/bisq/core/dao/state/model/governance/BallotList.java rename core/src/main/java/bisq/core/dao/{governance/role => state/model/governance}/BondedRoleType.java (98%) rename core/src/main/java/bisq/core/dao/{governance/proposal/param => state/model/governance}/ChangeParamProposal.java (92%) rename core/src/main/java/bisq/core/dao/{governance/proposal/compensation => state/model/governance}/CompensationProposal.java (91%) rename core/src/main/java/bisq/core/dao/{governance/proposal/confiscatebond => state/model/governance}/ConfiscateBondProposal.java (90%) rename core/src/main/java/bisq/core/dao/state/{period => model/governance}/Cycle.java (97%) rename core/src/main/java/bisq/core/dao/state/{period => model/governance}/DaoPhase.java (94%) rename core/src/main/java/bisq/core/dao/{governance/voteresult => state/model/governance}/DecryptedBallotsWithMerits.java (93%) rename core/src/main/java/bisq/core/dao/{governance/voteresult => state/model/governance}/EvaluatedProposal.java (91%) rename core/src/main/java/bisq/core/dao/{governance/proposal/generic => state/model/governance}/GenericProposal.java (90%) rename core/src/main/java/bisq/core/dao/state/{ => model}/governance/Issuance.java (96%) rename core/src/main/java/bisq/core/dao/state/{ => model}/governance/IssuanceType.java (82%) create mode 100644 core/src/main/java/bisq/core/dao/state/model/governance/Merit.java rename core/src/main/java/bisq/core/dao/{governance/merit => state/model/governance}/MeritList.java (94%) rename core/src/main/java/bisq/core/dao/state/{ => model}/governance/ParamChange.java (94%) rename core/src/main/java/bisq/core/dao/{governance/proposal => state/model/governance}/Proposal.java (86%) create mode 100644 core/src/main/java/bisq/core/dao/state/model/governance/ProposalVoteResult.java rename core/src/main/java/bisq/core/dao/{governance/proposal/reimbursement => state/model/governance}/ReimbursementProposal.java (91%) rename core/src/main/java/bisq/core/dao/{governance/proposal/removeAsset => state/model/governance}/RemoveAssetProposal.java (90%) create mode 100644 core/src/main/java/bisq/core/dao/state/model/governance/Role.java rename core/src/main/java/bisq/core/dao/{governance/proposal/role => state/model/governance}/RoleProposal.java (91%) create mode 100644 core/src/main/java/bisq/core/dao/state/model/governance/Vote.java create mode 100644 core/src/main/java/bisq/core/dao/state/model/governance/package-info.java create mode 100644 core/src/main/java/bisq/core/dao/state/model/package-info.java diff --git a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java index 282c4fa1a75..e45c235dfab 100644 --- a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java +++ b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java @@ -19,10 +19,10 @@ import bisq.core.dao.DaoOptionKeys; import bisq.core.dao.DaoSetup; -import bisq.core.dao.bonding.bond.BondedReputationService; import bisq.core.dao.governance.asset.AssetService; import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; +import bisq.core.dao.governance.bonding.bond.BondedReputationService; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.proposal.MyProposalListService; import bisq.core.filter.FilterManager; diff --git a/core/src/main/java/bisq/core/btc/wallet/BsqCoinSelector.java b/core/src/main/java/bisq/core/btc/wallet/BsqCoinSelector.java index 72bae194ab6..f81fd3b7ed7 100644 --- a/core/src/main/java/bisq/core/btc/wallet/BsqCoinSelector.java +++ b/core/src/main/java/bisq/core/btc/wallet/BsqCoinSelector.java @@ -18,7 +18,7 @@ package bisq.core.btc.wallet; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.TxOutputKey; +import bisq.core.dao.state.model.blockchain.TxOutputKey; import org.bitcoinj.core.TransactionOutput; diff --git a/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java b/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java index 42d3ae398ea..7bd348897eb 100644 --- a/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java +++ b/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java @@ -25,10 +25,10 @@ import bisq.core.btc.setup.WalletsSetup; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxOutputKey; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxOutputKey; import bisq.core.provider.fee.FeeService; import bisq.core.user.Preferences; diff --git a/core/src/main/java/bisq/core/btc/wallet/NonBsqCoinSelector.java b/core/src/main/java/bisq/core/btc/wallet/NonBsqCoinSelector.java index 2a1201cfe71..40ad176ed49 100644 --- a/core/src/main/java/bisq/core/btc/wallet/NonBsqCoinSelector.java +++ b/core/src/main/java/bisq/core/btc/wallet/NonBsqCoinSelector.java @@ -18,7 +18,7 @@ package bisq.core.btc.wallet; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.TxOutputKey; +import bisq.core.dao.state.model.blockchain.TxOutputKey; import org.bitcoinj.core.Transaction; import org.bitcoinj.core.TransactionConfidence; diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index d906566d92d..5518ce6b63d 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -19,23 +19,24 @@ import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.WalletException; -import bisq.core.dao.bonding.bond.BondWithHash; -import bisq.core.dao.bonding.bond.BondedReputation; -import bisq.core.dao.bonding.bond.BondedReputationService; -import bisq.core.dao.bonding.lockup.LockupService; -import bisq.core.dao.bonding.lockup.LockupType; -import bisq.core.dao.bonding.unlock.UnlockService; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.ballot.Ballot; import bisq.core.dao.governance.ballot.BallotListPresentation; import bisq.core.dao.governance.ballot.BallotListService; -import bisq.core.dao.governance.ballot.vote.Vote; import bisq.core.dao.governance.blindvote.BlindVoteConsensus; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; +import bisq.core.dao.governance.bond.BondedRole; +import bisq.core.dao.governance.bond.BondedRolesService; +import bisq.core.dao.governance.bonding.bond.BondWithHash; +import bisq.core.dao.governance.bonding.bond.BondedReputation; +import bisq.core.dao.governance.bonding.bond.BondedReputationService; +import bisq.core.dao.governance.bonding.lockup.LockupService; +import bisq.core.dao.governance.bonding.lockup.LockupType; +import bisq.core.dao.governance.bonding.unlock.UnlockService; import bisq.core.dao.governance.myvote.MyVote; import bisq.core.dao.governance.myvote.MyVoteListService; +import bisq.core.dao.governance.param.Param; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.MyProposalListService; -import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalConsensus; import bisq.core.dao.governance.proposal.ProposalListPresentation; import bisq.core.dao.governance.proposal.ProposalWithTransaction; @@ -49,21 +50,20 @@ import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposalService; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalService; import bisq.core.dao.governance.proposal.role.RoleProposalService; -import bisq.core.dao.governance.role.BondedRole; -import bisq.core.dao.governance.role.BondedRolesService; -import bisq.core.dao.governance.role.Role; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateStorageService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxOutputKey; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.IssuanceType; -import bisq.core.dao.state.governance.Param; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxOutputKey; +import bisq.core.dao.state.model.blockchain.TxType; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.DaoPhase; +import bisq.core.dao.state.model.governance.IssuanceType; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.Role; +import bisq.core.dao.state.model.governance.Vote; import bisq.asset.Asset; diff --git a/core/src/main/java/bisq/core/dao/DaoModule.java b/core/src/main/java/bisq/core/dao/DaoModule.java index e961efcee53..99bc45fdb9a 100644 --- a/core/src/main/java/bisq/core/dao/DaoModule.java +++ b/core/src/main/java/bisq/core/dao/DaoModule.java @@ -17,9 +17,6 @@ package bisq.core.dao; -import bisq.core.dao.bonding.bond.BondedReputationService; -import bisq.core.dao.bonding.lockup.LockupService; -import bisq.core.dao.bonding.unlock.UnlockService; import bisq.core.dao.governance.asset.AssetService; import bisq.core.dao.governance.ballot.BallotListPresentation; import bisq.core.dao.governance.ballot.BallotListService; @@ -29,7 +26,13 @@ import bisq.core.dao.governance.blindvote.network.RepublishGovernanceDataHandler; import bisq.core.dao.governance.blindvote.storage.BlindVoteStorageService; import bisq.core.dao.governance.blindvote.storage.BlindVoteStore; +import bisq.core.dao.governance.bond.BondedRolesService; +import bisq.core.dao.governance.bonding.bond.BondedReputationService; +import bisq.core.dao.governance.bonding.lockup.LockupService; +import bisq.core.dao.governance.bonding.unlock.UnlockService; import bisq.core.dao.governance.myvote.MyVoteListService; +import bisq.core.dao.governance.period.CycleService; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.MyProposalListService; import bisq.core.dao.governance.proposal.ProposalListPresentation; import bisq.core.dao.governance.proposal.ProposalService; @@ -52,27 +55,24 @@ import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStore; import bisq.core.dao.governance.proposal.storage.temp.TempProposalStorageService; import bisq.core.dao.governance.proposal.storage.temp.TempProposalStore; -import bisq.core.dao.governance.role.BondedRolesService; import bisq.core.dao.governance.voteresult.MissingDataRequestService; import bisq.core.dao.governance.voteresult.VoteResultService; import bisq.core.dao.governance.voteresult.issuance.IssuanceService; import bisq.core.dao.governance.votereveal.VoteRevealService; import bisq.core.dao.node.BsqNodeProvider; +import bisq.core.dao.node.explorer.ExportJsonFilesService; import bisq.core.dao.node.full.FullNode; import bisq.core.dao.node.full.RpcService; import bisq.core.dao.node.full.network.FullNodeNetworkService; -import bisq.core.dao.node.json.ExportJsonFilesService; import bisq.core.dao.node.lite.LiteNode; import bisq.core.dao.node.lite.network.LiteNodeNetworkService; import bisq.core.dao.node.parser.BlockParser; import bisq.core.dao.node.parser.TxParser; -import bisq.core.dao.period.CycleService; -import bisq.core.dao.period.PeriodService; -import bisq.core.dao.state.DaoState; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateSnapshotService; import bisq.core.dao.state.DaoStateStorageService; import bisq.core.dao.state.GenesisTxInfo; +import bisq.core.dao.state.model.DaoState; import bisq.common.app.AppModule; diff --git a/core/src/main/java/bisq/core/dao/DaoSetup.java b/core/src/main/java/bisq/core/dao/DaoSetup.java index d6120ea1343..d277b6aafa2 100644 --- a/core/src/main/java/bisq/core/dao/DaoSetup.java +++ b/core/src/main/java/bisq/core/dao/DaoSetup.java @@ -20,14 +20,14 @@ import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.BlindVoteListService; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; +import bisq.core.dao.governance.period.CycleService; import bisq.core.dao.governance.proposal.ProposalService; import bisq.core.dao.governance.voteresult.MissingDataRequestService; import bisq.core.dao.governance.voteresult.VoteResultService; import bisq.core.dao.governance.votereveal.VoteRevealService; import bisq.core.dao.node.BsqNode; import bisq.core.dao.node.BsqNodeProvider; -import bisq.core.dao.node.json.ExportJsonFilesService; -import bisq.core.dao.period.CycleService; +import bisq.core.dao.node.explorer.ExportJsonFilesService; import bisq.core.dao.state.DaoStateService; import bisq.common.handlers.ErrorMessageHandler; diff --git a/core/src/main/java/bisq/core/dao/exceptions/ValidationException.java b/core/src/main/java/bisq/core/dao/exceptions/ValidationException.java index ee2f3e73117..9869254fa9b 100644 --- a/core/src/main/java/bisq/core/dao/exceptions/ValidationException.java +++ b/core/src/main/java/bisq/core/dao/exceptions/ValidationException.java @@ -1,6 +1,6 @@ package bisq.core.dao.exceptions; -import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.Tx; import org.bitcoinj.core.Coin; diff --git a/core/src/main/java/bisq/core/dao/governance/ballot/BallotListPresentation.java b/core/src/main/java/bisq/core/dao/governance/ballot/BallotListPresentation.java index cca4da9a84b..b37a90ccef4 100644 --- a/core/src/main/java/bisq/core/dao/governance/ballot/BallotListPresentation.java +++ b/core/src/main/java/bisq/core/dao/governance/ballot/BallotListPresentation.java @@ -17,11 +17,12 @@ package bisq.core.dao.governance.ballot; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.ProposalValidator; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.Ballot; import com.google.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/ballot/BallotListService.java b/core/src/main/java/bisq/core/dao/governance/ballot/BallotListService.java index 450a0733800..cc8ef54734c 100644 --- a/core/src/main/java/bisq/core/dao/governance/ballot/BallotListService.java +++ b/core/src/main/java/bisq/core/dao/governance/ballot/BallotListService.java @@ -19,11 +19,13 @@ import bisq.core.app.BisqEnvironment; import bisq.core.dao.DaoSetupService; -import bisq.core.dao.governance.ballot.vote.Vote; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.ProposalService; import bisq.core.dao.governance.proposal.ProposalValidator; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalPayload; -import bisq.core.dao.period.PeriodService; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.BallotList; +import bisq.core.dao.state.model.governance.Vote; import bisq.common.proto.persistable.PersistedDataHost; import bisq.common.storage.Storage; diff --git a/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteConsensus.java b/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteConsensus.java index 0d54e8f725a..a61bc00bc5b 100644 --- a/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteConsensus.java @@ -17,13 +17,13 @@ package bisq.core.dao.governance.blindvote; -import bisq.core.dao.governance.ballot.Ballot; -import bisq.core.dao.governance.ballot.BallotList; import bisq.core.dao.governance.ballot.BallotListService; -import bisq.core.dao.governance.merit.MeritList; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.OpReturnType; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.blockchain.OpReturnType; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.BallotList; +import bisq.core.dao.state.model.governance.MeritList; import bisq.common.app.Version; import bisq.common.crypto.CryptoException; diff --git a/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteListService.java b/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteListService.java index 0775e859628..6d92cc292f4 100644 --- a/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteListService.java +++ b/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteListService.java @@ -23,7 +23,7 @@ import bisq.core.dao.governance.blindvote.storage.BlindVoteStorageService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Block; import bisq.network.p2p.P2PService; import bisq.network.p2p.storage.payload.PersistableNetworkPayload; diff --git a/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteValidator.java b/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteValidator.java index 65f57e734e8..9e4eb4c419b 100644 --- a/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/blindvote/BlindVoteValidator.java @@ -18,10 +18,10 @@ package bisq.core.dao.governance.blindvote; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.period.PeriodService; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.governance.DaoPhase; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java b/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java index 3a00c22438b..b9b55d40b77 100644 --- a/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java +++ b/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java @@ -28,22 +28,22 @@ import bisq.core.btc.wallet.WalletsManager; import bisq.core.dao.DaoSetupService; import bisq.core.dao.exceptions.PublishToP2PNetworkException; -import bisq.core.dao.governance.ballot.BallotList; import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.storage.BlindVotePayload; -import bisq.core.dao.governance.merit.Merit; import bisq.core.dao.governance.merit.MeritConsensus; -import bisq.core.dao.governance.merit.MeritList; import bisq.core.dao.governance.myvote.MyVoteListService; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.MyProposalListService; -import bisq.core.dao.governance.proposal.Proposal; -import bisq.core.dao.governance.proposal.compensation.CompensationProposal; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.governance.IssuanceType; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.BallotList; +import bisq.core.dao.state.model.governance.CompensationProposal; +import bisq.core.dao.state.model.governance.DaoPhase; +import bisq.core.dao.state.model.governance.IssuanceType; +import bisq.core.dao.state.model.governance.Merit; +import bisq.core.dao.state.model.governance.MeritList; +import bisq.core.dao.state.model.governance.Proposal; import bisq.network.p2p.P2PService; diff --git a/core/src/main/java/bisq/core/dao/governance/blindvote/VoteWithProposalTxId.java b/core/src/main/java/bisq/core/dao/governance/blindvote/VoteWithProposalTxId.java index 6201b8f338a..5e98471b5c4 100644 --- a/core/src/main/java/bisq/core/dao/governance/blindvote/VoteWithProposalTxId.java +++ b/core/src/main/java/bisq/core/dao/governance/blindvote/VoteWithProposalTxId.java @@ -17,7 +17,7 @@ package bisq.core.dao.governance.blindvote; -import bisq.core.dao.governance.ballot.vote.Vote; +import bisq.core.dao.state.model.governance.Vote; import bisq.common.proto.persistable.PersistablePayload; diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java b/core/src/main/java/bisq/core/dao/governance/bond/BondedRole.java similarity index 94% rename from core/src/main/java/bisq/core/dao/governance/role/BondedRole.java rename to core/src/main/java/bisq/core/dao/governance/bond/BondedRole.java index 441449d2f7c..eecfc8af126 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRole.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondedRole.java @@ -15,7 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.role; +package bisq.core.dao.governance.bond; + +import bisq.core.dao.state.model.governance.Role; import lombok.Getter; import lombok.Setter; diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java b/core/src/main/java/bisq/core/dao/governance/bond/BondedRolesService.java similarity index 95% rename from core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java rename to core/src/main/java/bisq/core/dao/governance/bond/BondedRolesService.java index 127405db385..50d7d4adf8b 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRolesService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondedRolesService.java @@ -15,16 +15,18 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.role; +package bisq.core.dao.governance.bond; -import bisq.core.dao.bonding.BondingConsensus; -import bisq.core.dao.governance.proposal.role.RoleProposal; +import bisq.core.dao.governance.bonding.BondingConsensus; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.BaseTxOutput; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.SpentInfo; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.state.model.blockchain.BaseTxOutput; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.SpentInfo; +import bisq.core.dao.state.model.blockchain.TxType; +import bisq.core.dao.state.model.governance.BondedRoleType; +import bisq.core.dao.state.model.governance.Role; +import bisq.core.dao.state.model.governance.RoleProposal; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/state/governance/ConfiscateBond.java b/core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java similarity index 97% rename from core/src/main/java/bisq/core/dao/state/governance/ConfiscateBond.java rename to core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java index 1a8a68d3d0e..867140a2321 100644 --- a/core/src/main/java/bisq/core/dao/state/governance/ConfiscateBond.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.governance; +package bisq.core.dao.governance.bond; import bisq.common.proto.persistable.PersistablePayload; diff --git a/core/src/main/java/bisq/core/dao/bonding/BondingConsensus.java b/core/src/main/java/bisq/core/dao/governance/bonding/BondingConsensus.java similarity index 93% rename from core/src/main/java/bisq/core/dao/bonding/BondingConsensus.java rename to core/src/main/java/bisq/core/dao/governance/bonding/BondingConsensus.java index 51fafdadb0a..1c1c33390e6 100644 --- a/core/src/main/java/bisq/core/dao/bonding/BondingConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/bonding/BondingConsensus.java @@ -15,11 +15,11 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.bonding; +package bisq.core.dao.governance.bonding; -import bisq.core.dao.bonding.bond.BondWithHash; -import bisq.core.dao.bonding.lockup.LockupType; -import bisq.core.dao.state.blockchain.OpReturnType; +import bisq.core.dao.governance.bonding.bond.BondWithHash; +import bisq.core.dao.governance.bonding.lockup.LockupType; +import bisq.core.dao.state.model.blockchain.OpReturnType; import bisq.common.app.Version; import bisq.common.util.Utilities; diff --git a/core/src/main/java/bisq/core/dao/bonding/bond/BondWithHash.java b/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondWithHash.java similarity index 94% rename from core/src/main/java/bisq/core/dao/bonding/bond/BondWithHash.java rename to core/src/main/java/bisq/core/dao/governance/bonding/bond/BondWithHash.java index 27d08273e8e..12c91d5accb 100644 --- a/core/src/main/java/bisq/core/dao/bonding/bond/BondWithHash.java +++ b/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondWithHash.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.bonding.bond; +package bisq.core.dao.governance.bonding.bond; public interface BondWithHash { byte[] getHash(); diff --git a/core/src/main/java/bisq/core/dao/bonding/bond/BondedReputation.java b/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputation.java similarity index 98% rename from core/src/main/java/bisq/core/dao/bonding/bond/BondedReputation.java rename to core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputation.java index 1134c00e1eb..13c6f2f4590 100644 --- a/core/src/main/java/bisq/core/dao/bonding/bond/BondedReputation.java +++ b/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputation.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.bonding.bond; +package bisq.core.dao.governance.bonding.bond; import bisq.core.locale.Res; diff --git a/core/src/main/java/bisq/core/dao/bonding/bond/BondedReputationList.java b/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationList.java similarity index 98% rename from core/src/main/java/bisq/core/dao/bonding/bond/BondedReputationList.java rename to core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationList.java index 65f78621e5e..aff6d349f43 100644 --- a/core/src/main/java/bisq/core/dao/bonding/bond/BondedReputationList.java +++ b/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationList.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.bonding.bond; +package bisq.core.dao.governance.bonding.bond; import bisq.common.proto.persistable.PersistableList; diff --git a/core/src/main/java/bisq/core/dao/bonding/bond/BondedReputationService.java b/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationService.java similarity index 96% rename from core/src/main/java/bisq/core/dao/bonding/bond/BondedReputationService.java rename to core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationService.java index 6f3383e5490..0d4bfa96c9d 100644 --- a/core/src/main/java/bisq/core/dao/bonding/bond/BondedReputationService.java +++ b/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationService.java @@ -15,15 +15,15 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.bonding.bond; +package bisq.core.dao.governance.bonding.bond; import bisq.core.app.BisqEnvironment; -import bisq.core.dao.bonding.BondingConsensus; +import bisq.core.dao.governance.bonding.BondingConsensus; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.SpentInfo; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.SpentInfo; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.proto.persistable.PersistedDataHost; import bisq.common.storage.Storage; diff --git a/core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java b/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupService.java similarity index 94% rename from core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java rename to core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupService.java index cd5b26dd7a1..43617bb2ebc 100644 --- a/core/src/main/java/bisq/core/dao/bonding/lockup/LockupService.java +++ b/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupService.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.bonding.lockup; +package bisq.core.dao.governance.bonding.lockup; import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.TxBroadcastException; @@ -25,10 +25,10 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsManager; -import bisq.core.dao.bonding.BondingConsensus; -import bisq.core.dao.bonding.bond.BondWithHash; -import bisq.core.dao.governance.role.Role; -import bisq.core.dao.governance.role.BondedRolesService; +import bisq.core.dao.governance.bond.BondedRolesService; +import bisq.core.dao.governance.bonding.BondingConsensus; +import bisq.core.dao.governance.bonding.bond.BondWithHash; +import bisq.core.dao.state.model.governance.Role; import bisq.common.handlers.ExceptionHandler; import bisq.common.handlers.ResultHandler; diff --git a/core/src/main/java/bisq/core/dao/bonding/lockup/LockupType.java b/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupType.java similarity index 96% rename from core/src/main/java/bisq/core/dao/bonding/lockup/LockupType.java rename to core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupType.java index 0f3de3ba79e..cebc0084d68 100644 --- a/core/src/main/java/bisq/core/dao/bonding/lockup/LockupType.java +++ b/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupType.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.bonding.lockup; +package bisq.core.dao.governance.bonding.lockup; import bisq.core.locale.Res; diff --git a/core/src/main/java/bisq/core/dao/bonding/unlock/UnlockService.java b/core/src/main/java/bisq/core/dao/governance/bonding/unlock/UnlockService.java similarity index 97% rename from core/src/main/java/bisq/core/dao/bonding/unlock/UnlockService.java rename to core/src/main/java/bisq/core/dao/governance/bonding/unlock/UnlockService.java index 881ad7422af..9a9a9af27fc 100644 --- a/core/src/main/java/bisq/core/dao/bonding/unlock/UnlockService.java +++ b/core/src/main/java/bisq/core/dao/governance/bonding/unlock/UnlockService.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.bonding.unlock; +package bisq.core.dao.governance.bonding.unlock; import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.TxBroadcastException; @@ -26,7 +26,7 @@ import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsManager; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxOutput; import bisq.common.handlers.ExceptionHandler; import bisq.common.handlers.ResultHandler; diff --git a/core/src/main/java/bisq/core/dao/governance/merit/MeritConsensus.java b/core/src/main/java/bisq/core/dao/governance/merit/MeritConsensus.java index 1e2cf06b3f0..c48398c379f 100644 --- a/core/src/main/java/bisq/core/dao/governance/merit/MeritConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/merit/MeritConsensus.java @@ -19,9 +19,10 @@ import bisq.core.dao.governance.voteresult.VoteResultException; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.governance.Issuance; -import bisq.core.dao.state.governance.IssuanceType; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.governance.Issuance; +import bisq.core.dao.state.model.governance.IssuanceType; +import bisq.core.dao.state.model.governance.MeritList; import bisq.common.crypto.Encryption; import bisq.common.util.Utilities; diff --git a/core/src/main/java/bisq/core/dao/governance/myvote/MyVote.java b/core/src/main/java/bisq/core/dao/governance/myvote/MyVote.java index f3b94be0416..92c3ac8d925 100644 --- a/core/src/main/java/bisq/core/dao/governance/myvote/MyVote.java +++ b/core/src/main/java/bisq/core/dao/governance/myvote/MyVote.java @@ -17,12 +17,12 @@ package bisq.core.dao.governance.myvote; -import bisq.core.dao.governance.ballot.BallotList; import bisq.core.dao.governance.blindvote.BlindVote; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; import bisq.core.dao.governance.merit.MeritConsensus; -import bisq.core.dao.governance.merit.MeritList; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.BallotList; +import bisq.core.dao.state.model.governance.MeritList; import bisq.common.crypto.Encryption; import bisq.common.proto.persistable.PersistablePayload; diff --git a/core/src/main/java/bisq/core/dao/governance/myvote/MyVoteListService.java b/core/src/main/java/bisq/core/dao/governance/myvote/MyVoteListService.java index 3bef645897a..8e13a9633be 100644 --- a/core/src/main/java/bisq/core/dao/governance/myvote/MyVoteListService.java +++ b/core/src/main/java/bisq/core/dao/governance/myvote/MyVoteListService.java @@ -18,11 +18,11 @@ package bisq.core.dao.governance.myvote; import bisq.core.app.BisqEnvironment; -import bisq.core.dao.governance.ballot.Ballot; -import bisq.core.dao.governance.ballot.BallotList; import bisq.core.dao.governance.blindvote.BlindVote; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.BallotList; import bisq.common.crypto.Encryption; import bisq.common.proto.persistable.PersistedDataHost; diff --git a/core/src/main/java/bisq/core/dao/state/governance/Param.java b/core/src/main/java/bisq/core/dao/governance/param/Param.java similarity index 99% rename from core/src/main/java/bisq/core/dao/state/governance/Param.java rename to core/src/main/java/bisq/core/dao/governance/param/Param.java index 91017a4645a..550ebd2e6e9 100644 --- a/core/src/main/java/bisq/core/dao/state/governance/Param.java +++ b/core/src/main/java/bisq/core/dao/governance/param/Param.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.governance; +package bisq.core.dao.governance.param; import bisq.core.app.BisqEnvironment; import bisq.core.locale.Res; diff --git a/core/src/main/java/bisq/core/dao/state/governance/ParamType.java b/core/src/main/java/bisq/core/dao/governance/param/ParamType.java similarity index 95% rename from core/src/main/java/bisq/core/dao/state/governance/ParamType.java rename to core/src/main/java/bisq/core/dao/governance/param/ParamType.java index 4508d2e5148..5e89b7a427c 100644 --- a/core/src/main/java/bisq/core/dao/state/governance/ParamType.java +++ b/core/src/main/java/bisq/core/dao/governance/param/ParamType.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.governance; +package bisq.core.dao.governance.param; public enum ParamType { UNDEFINED, diff --git a/core/src/main/java/bisq/core/dao/period/CycleService.java b/core/src/main/java/bisq/core/dao/governance/period/CycleService.java similarity index 96% rename from core/src/main/java/bisq/core/dao/period/CycleService.java rename to core/src/main/java/bisq/core/dao/governance/period/CycleService.java index 4a2496f7da7..44587e90436 100644 --- a/core/src/main/java/bisq/core/dao/period/CycleService.java +++ b/core/src/main/java/bisq/core/dao/governance/period/CycleService.java @@ -15,16 +15,16 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.period; +package bisq.core.dao.governance.period; import bisq.core.dao.DaoSetupService; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.GenesisTxInfo; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.governance.Param; -import bisq.core.dao.state.period.Cycle; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.Cycle; +import bisq.core.dao.state.model.governance.DaoPhase; import com.google.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/period/PeriodService.java b/core/src/main/java/bisq/core/dao/governance/period/PeriodService.java similarity index 96% rename from core/src/main/java/bisq/core/dao/period/PeriodService.java rename to core/src/main/java/bisq/core/dao/governance/period/PeriodService.java index abc133600b9..e8db5b24b23 100644 --- a/core/src/main/java/bisq/core/dao/period/PeriodService.java +++ b/core/src/main/java/bisq/core/dao/governance/period/PeriodService.java @@ -15,12 +15,12 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.period; +package bisq.core.dao.governance.period; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.period.Cycle; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.governance.Cycle; +import bisq.core.dao.state.model.governance.DaoPhase; import com.google.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalService.java index 3ff3c1da541..36e56d1ca2a 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalService.java @@ -23,7 +23,8 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.OpReturnType; +import bisq.core.dao.state.model.blockchain.OpReturnType; +import bisq.core.dao.state.model.governance.Proposal; import bisq.common.app.Version; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalList.java b/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalList.java index 3f17be64147..5f1931a269d 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalList.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalList.java @@ -18,6 +18,7 @@ package bisq.core.dao.governance.proposal; import bisq.core.dao.governance.ConsensusCritical; +import bisq.core.dao.state.model.governance.Proposal; import bisq.common.proto.persistable.PersistableList; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java b/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java index 48514a4177e..98ddd3a7396 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java @@ -22,13 +22,14 @@ import bisq.core.btc.exceptions.TxMalleabilityException; import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsManager; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.storage.temp.TempProposalPayload; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.governance.DaoPhase; +import bisq.core.dao.state.model.governance.Proposal; import bisq.network.p2p.P2PService; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalConsensus.java b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalConsensus.java index 8c64b7719ff..067086faf8f 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalConsensus.java @@ -17,8 +17,9 @@ package bisq.core.dao.governance.proposal; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.governance.Proposal; import bisq.common.crypto.Hash; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalListPresentation.java b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalListPresentation.java index 6099d01225b..32deec4cbc1 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalListPresentation.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalListPresentation.java @@ -21,7 +21,8 @@ import bisq.core.dao.governance.proposal.storage.appendonly.ProposalPayload; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.Proposal; import org.bitcoinj.core.TransactionConfidence; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalService.java index 11572e4425e..a3bb38cc204 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalService.java @@ -19,15 +19,16 @@ import bisq.core.dao.DaoOptionKeys; import bisq.core.dao.DaoSetupService; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalPayload; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStorageService; import bisq.core.dao.governance.proposal.storage.temp.TempProposalPayload; import bisq.core.dao.governance.proposal.storage.temp.TempProposalStorageService; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.DaoPhase; +import bisq.core.dao.state.model.governance.Proposal; import bisq.network.p2p.P2PService; import bisq.network.p2p.storage.HashMapChangedListener; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalValidator.java index 5fbec0f885c..4434339d808 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalValidator.java @@ -18,13 +18,14 @@ package bisq.core.dao.governance.proposal; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.compensation.CompensationProposal; -import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; -import bisq.core.dao.period.PeriodService; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxType; +import bisq.core.dao.state.model.governance.CompensationProposal; +import bisq.core.dao.state.model.governance.DaoPhase; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.ReimbursementProposal; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalWithTransaction.java b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalWithTransaction.java index 585a9d79637..99d53336ade 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/ProposalWithTransaction.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/ProposalWithTransaction.java @@ -17,6 +17,8 @@ package bisq.core.dao.governance.proposal; +import bisq.core.dao.state.model.governance.Proposal; + import org.bitcoinj.core.Transaction; import lombok.Value; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationConsensus.java b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationConsensus.java index 56994666c32..ced36309e27 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationConsensus.java @@ -17,8 +17,8 @@ package bisq.core.dao.governance.proposal.compensation; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.governance.Param; import org.bitcoinj.core.Coin; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposalService.java index 911794a5a87..e78dce8598c 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposalService.java @@ -23,12 +23,13 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.proposal.BaseProposalService; -import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalConsensus; import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.OpReturnType; +import bisq.core.dao.state.model.blockchain.OpReturnType; +import bisq.core.dao.state.model.governance.CompensationProposal; +import bisq.core.dao.state.model.governance.Proposal; import bisq.common.app.Version; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationValidator.java index f2a4e289fb8..ef91bc06a7d 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationValidator.java @@ -18,10 +18,11 @@ package bisq.core.dao.governance.proposal.compensation; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.ProposalValidator; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.CompensationProposal; +import bisq.core.dao.state.model.governance.Proposal; import org.bitcoinj.core.Coin; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalService.java index 976719fee18..5dc238d98ff 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalService.java @@ -24,6 +24,7 @@ import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.ConfiscateBondProposal; import org.bitcoinj.core.InsufficientMoneyException; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondValidator.java index 54d46829d14..d6d79670be2 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondValidator.java @@ -18,10 +18,11 @@ package bisq.core.dao.governance.proposal.confiscatebond; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.ProposalValidator; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.ConfiscateBondProposal; +import bisq.core.dao.state.model.governance.Proposal; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalService.java index 00410754d2c..1acea786359 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalService.java @@ -24,6 +24,7 @@ import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.GenericProposal; import org.bitcoinj.core.InsufficientMoneyException; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalValidator.java index cbf7732a765..0ce069647b3 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposalValidator.java @@ -18,10 +18,11 @@ package bisq.core.dao.governance.proposal.generic; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.ProposalValidator; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.GenericProposal; +import bisq.core.dao.state.model.governance.Proposal; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamInputValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamInputValidator.java index 348c195bb3e..72ad23671a6 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamInputValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamInputValidator.java @@ -17,7 +17,7 @@ package bisq.core.dao.governance.proposal.param; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.governance.param.Param; import bisq.core.util.validation.InputValidator; public class ChangeParamInputValidator extends InputValidator { diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposalService.java index a93aaf60103..a166e01b9e5 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposalService.java @@ -20,11 +20,12 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.exceptions.ValidationException; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.BaseProposalService; import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.governance.ChangeParamProposal; import org.bitcoinj.core.InsufficientMoneyException; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamValidator.java index 196ae8900fd..f0023c30c8b 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamValidator.java @@ -19,11 +19,12 @@ import bisq.core.btc.wallet.Restrictions; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.param.Param; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.ProposalValidator; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.governance.ChangeParamProposal; +import bisq.core.dao.state.model.governance.Proposal; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.validation.BtcAddressValidator; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementConsensus.java b/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementConsensus.java index 67f6b8c6bea..2c7bce08e0c 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementConsensus.java @@ -17,8 +17,8 @@ package bisq.core.dao.governance.proposal.reimbursement; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.governance.Param; import org.bitcoinj.core.Coin; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposalService.java index c80f3ebe5f3..5f2d7c3f1ff 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposalService.java @@ -23,12 +23,13 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.proposal.BaseProposalService; -import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalConsensus; import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.OpReturnType; +import bisq.core.dao.state.model.blockchain.OpReturnType; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.ReimbursementProposal; import bisq.common.app.Version; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementValidator.java index 3ba812ad70f..632c85a2e7b 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementValidator.java @@ -18,10 +18,11 @@ package bisq.core.dao.governance.proposal.reimbursement; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.ProposalValidator; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.ReimbursementProposal; import org.bitcoinj.core.Coin; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposalService.java index d0902c66202..4ba9b913b7e 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposalService.java @@ -24,6 +24,9 @@ import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.RemoveAssetProposal; + +import bisq.asset.Asset; import org.bitcoinj.core.InsufficientMoneyException; @@ -31,10 +34,6 @@ import lombok.extern.slf4j.Slf4j; - - -import bisq.asset.Asset; - /** * Creates RemoveAssetProposal and transaction. */ diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetValidator.java index 495ffc1bc4e..4a638ef64e6 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetValidator.java @@ -18,10 +18,11 @@ package bisq.core.dao.governance.proposal.removeAsset; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.ProposalValidator; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.RemoveAssetProposal; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposalService.java index 14222b827df..6609ec9bded 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposalService.java @@ -23,8 +23,9 @@ import bisq.core.dao.governance.proposal.BaseProposalService; import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; -import bisq.core.dao.governance.role.Role; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.Role; +import bisq.core.dao.state.model.governance.RoleProposal; import org.bitcoinj.core.InsufficientMoneyException; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleValidator.java b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleValidator.java index ce331f4ec3c..a57d6f6d6a6 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleValidator.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleValidator.java @@ -18,11 +18,12 @@ package bisq.core.dao.governance.proposal.role; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.ProposalValidator; -import bisq.core.dao.governance.role.Role; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.Role; +import bisq.core.dao.state.model.governance.RoleProposal; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/storage/appendonly/ProposalPayload.java b/core/src/main/java/bisq/core/dao/governance/proposal/storage/appendonly/ProposalPayload.java index 7aa55a96c02..45bdc837b84 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/storage/appendonly/ProposalPayload.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/storage/appendonly/ProposalPayload.java @@ -18,7 +18,7 @@ package bisq.core.dao.governance.proposal.storage.appendonly; import bisq.core.dao.governance.ConsensusCritical; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.state.model.governance.Proposal; import bisq.network.p2p.storage.payload.CapabilityRequiringPayload; import bisq.network.p2p.storage.payload.PersistableNetworkPayload; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/storage/temp/TempProposalPayload.java b/core/src/main/java/bisq/core/dao/governance/proposal/storage/temp/TempProposalPayload.java index ce92299e11d..e8b510e5b5b 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/storage/temp/TempProposalPayload.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/storage/temp/TempProposalPayload.java @@ -17,7 +17,7 @@ package bisq.core.dao.governance.proposal.storage.temp; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.state.model.governance.Proposal; import bisq.network.p2p.storage.payload.CapabilityRequiringPayload; import bisq.network.p2p.storage.payload.ExpirablePayload; diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultConsensus.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultConsensus.java index 5fa1808f038..32aa2db5b6e 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultConsensus.java @@ -18,14 +18,14 @@ package bisq.core.dao.governance.voteresult; import bisq.core.dao.governance.blindvote.VoteWithProposalTxIdList; -import bisq.core.dao.period.PeriodService; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxInput; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxOutputType; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxInput; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxOutputType; +import bisq.core.dao.state.model.blockchain.TxType; +import bisq.core.dao.state.model.governance.DaoPhase; import bisq.common.crypto.Encryption; import bisq.common.util.Utilities; diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultException.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultException.java index 04ea068b795..7e2814b3dee 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultException.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultException.java @@ -17,7 +17,7 @@ package bisq.core.dao.governance.voteresult; -import bisq.core.dao.governance.ballot.Ballot; +import bisq.core.dao.state.model.governance.Ballot; import java.util.List; diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java index 036710fcac5..d185f5ec6d4 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java @@ -19,38 +19,41 @@ import bisq.core.dao.DaoSetupService; import bisq.core.dao.governance.asset.AssetService; -import bisq.core.dao.governance.ballot.Ballot; -import bisq.core.dao.governance.ballot.BallotList; import bisq.core.dao.governance.ballot.BallotListService; -import bisq.core.dao.governance.ballot.vote.Vote; import bisq.core.dao.governance.blindvote.BlindVote; import bisq.core.dao.governance.blindvote.BlindVoteConsensus; import bisq.core.dao.governance.blindvote.BlindVoteListService; import bisq.core.dao.governance.blindvote.VoteWithProposalTxId; import bisq.core.dao.governance.blindvote.VoteWithProposalTxIdList; +import bisq.core.dao.governance.bond.BondedRolesService; +import bisq.core.dao.governance.bond.ConfiscateBond; import bisq.core.dao.governance.merit.MeritConsensus; -import bisq.core.dao.governance.merit.MeritList; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.IssuanceProposal; -import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalListPresentation; -import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposal; -import bisq.core.dao.governance.proposal.param.ChangeParamProposal; -import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; -import bisq.core.dao.governance.proposal.role.RoleProposal; -import bisq.core.dao.governance.role.BondedRolesService; -import bisq.core.dao.governance.role.Role; import bisq.core.dao.governance.voteresult.issuance.IssuanceService; import bisq.core.dao.governance.votereveal.VoteRevealConsensus; import bisq.core.dao.governance.votereveal.VoteRevealService; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.governance.ConfiscateBond; -import bisq.core.dao.state.governance.ParamChange; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.BallotList; +import bisq.core.dao.state.model.governance.ChangeParamProposal; +import bisq.core.dao.state.model.governance.ConfiscateBondProposal; +import bisq.core.dao.state.model.governance.DaoPhase; +import bisq.core.dao.state.model.governance.DecryptedBallotsWithMerits; +import bisq.core.dao.state.model.governance.EvaluatedProposal; +import bisq.core.dao.state.model.governance.MeritList; +import bisq.core.dao.state.model.governance.ParamChange; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.ProposalVoteResult; +import bisq.core.dao.state.model.governance.RemoveAssetProposal; +import bisq.core.dao.state.model.governance.Role; +import bisq.core.dao.state.model.governance.RoleProposal; +import bisq.core.dao.state.model.governance.Vote; import bisq.core.locale.CurrencyUtil; import bisq.network.p2p.storage.P2PDataStorage; diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/issuance/IssuanceService.java b/core/src/main/java/bisq/core/dao/governance/voteresult/issuance/IssuanceService.java index 47aad2ab66c..77157f9e002 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/issuance/IssuanceService.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/issuance/IssuanceService.java @@ -17,17 +17,17 @@ package bisq.core.dao.governance.voteresult.issuance; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.IssuanceProposal; -import bisq.core.dao.governance.proposal.compensation.CompensationProposal; -import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; -import bisq.core.dao.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxInput; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.governance.Issuance; -import bisq.core.dao.state.governance.IssuanceType; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxInput; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.governance.CompensationProposal; +import bisq.core.dao.state.model.governance.DaoPhase; +import bisq.core.dao.state.model.governance.Issuance; +import bisq.core.dao.state.model.governance.IssuanceType; +import bisq.core.dao.state.model.governance.ReimbursementProposal; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealConsensus.java b/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealConsensus.java index 6569925dd5c..19993205fe2 100644 --- a/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealConsensus.java @@ -18,7 +18,7 @@ package bisq.core.dao.governance.votereveal; import bisq.core.dao.governance.blindvote.BlindVote; -import bisq.core.dao.state.blockchain.OpReturnType; +import bisq.core.dao.state.model.blockchain.OpReturnType; import bisq.common.app.Version; import bisq.common.crypto.Hash; diff --git a/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java b/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java index 246d59ffa97..4dba0cff0db 100644 --- a/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java +++ b/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java @@ -33,12 +33,12 @@ import bisq.core.dao.governance.blindvote.storage.BlindVotePayload; import bisq.core.dao.governance.myvote.MyVote; import bisq.core.dao.governance.myvote.MyVoteListService; -import bisq.core.dao.period.PeriodService; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.governance.DaoPhase; import bisq.network.p2p.P2PService; diff --git a/core/src/main/java/bisq/core/dao/node/BsqNode.java b/core/src/main/java/bisq/core/dao/node/BsqNode.java index 658644afa04..5ae8386bee9 100644 --- a/core/src/main/java/bisq/core/dao/node/BsqNode.java +++ b/core/src/main/java/bisq/core/dao/node/BsqNode.java @@ -18,10 +18,10 @@ package bisq.core.dao.node; import bisq.core.dao.DaoSetupService; +import bisq.core.dao.node.full.RawBlock; import bisq.core.dao.node.parser.BlockParser; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateSnapshotService; -import bisq.core.dao.state.blockchain.RawBlock; import bisq.network.p2p.P2PService; import bisq.network.p2p.P2PServiceListener; diff --git a/core/src/main/java/bisq/core/dao/node/json/ExportJsonFilesService.java b/core/src/main/java/bisq/core/dao/node/explorer/ExportJsonFilesService.java similarity index 96% rename from core/src/main/java/bisq/core/dao/node/json/ExportJsonFilesService.java rename to core/src/main/java/bisq/core/dao/node/explorer/ExportJsonFilesService.java index 0f85caac4e2..3c3bb0a6d98 100644 --- a/core/src/main/java/bisq/core/dao/node/json/ExportJsonFilesService.java +++ b/core/src/main/java/bisq/core/dao/node/explorer/ExportJsonFilesService.java @@ -15,17 +15,17 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.node.json; +package bisq.core.dao.node.explorer; import bisq.core.dao.DaoOptionKeys; import bisq.core.dao.DaoSetupService; -import bisq.core.dao.state.DaoState; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.PubKeyScript; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.state.model.DaoState; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.PubKeyScript; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.storage.FileUtil; import bisq.common.storage.JsonFileManager; diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonBlock.java b/core/src/main/java/bisq/core/dao/node/explorer/JsonBlock.java similarity index 96% rename from core/src/main/java/bisq/core/dao/node/json/JsonBlock.java rename to core/src/main/java/bisq/core/dao/node/explorer/JsonBlock.java index 99227b404de..da93f0c0125 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonBlock.java +++ b/core/src/main/java/bisq/core/dao/node/explorer/JsonBlock.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.node.json; +package bisq.core.dao.node.explorer; import java.util.List; diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonBlocks.java b/core/src/main/java/bisq/core/dao/node/explorer/JsonBlocks.java similarity index 95% rename from core/src/main/java/bisq/core/dao/node/json/JsonBlocks.java rename to core/src/main/java/bisq/core/dao/node/explorer/JsonBlocks.java index a87a7e5b045..f896b1f2fa3 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonBlocks.java +++ b/core/src/main/java/bisq/core/dao/node/explorer/JsonBlocks.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.node.json; +package bisq.core.dao.node.explorer; import java.util.List; diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonScriptPubKey.java b/core/src/main/java/bisq/core/dao/node/explorer/JsonScriptPubKey.java similarity index 92% rename from core/src/main/java/bisq/core/dao/node/json/JsonScriptPubKey.java rename to core/src/main/java/bisq/core/dao/node/explorer/JsonScriptPubKey.java index a69ae8c3977..60cecb41dd7 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonScriptPubKey.java +++ b/core/src/main/java/bisq/core/dao/node/explorer/JsonScriptPubKey.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.node.json; +package bisq.core.dao.node.explorer; -import bisq.core.dao.state.blockchain.PubKeyScript; +import bisq.core.dao.state.model.blockchain.PubKeyScript; import java.util.List; diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonSpentInfo.java b/core/src/main/java/bisq/core/dao/node/explorer/JsonSpentInfo.java similarity index 91% rename from core/src/main/java/bisq/core/dao/node/json/JsonSpentInfo.java rename to core/src/main/java/bisq/core/dao/node/explorer/JsonSpentInfo.java index 119579c761a..0624fa5ac34 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonSpentInfo.java +++ b/core/src/main/java/bisq/core/dao/node/explorer/JsonSpentInfo.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.node.json; +package bisq.core.dao.node.explorer; -import bisq.core.dao.state.blockchain.SpentInfo; +import bisq.core.dao.state.model.blockchain.SpentInfo; import lombok.Value; diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonTx.java b/core/src/main/java/bisq/core/dao/node/explorer/JsonTx.java similarity index 98% rename from core/src/main/java/bisq/core/dao/node/json/JsonTx.java rename to core/src/main/java/bisq/core/dao/node/explorer/JsonTx.java index 3bff69de155..a23ff2413d1 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonTx.java +++ b/core/src/main/java/bisq/core/dao/node/explorer/JsonTx.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.node.json; +package bisq.core.dao.node.explorer; import bisq.common.app.Version; diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonTxInput.java b/core/src/main/java/bisq/core/dao/node/explorer/JsonTxInput.java similarity index 96% rename from core/src/main/java/bisq/core/dao/node/json/JsonTxInput.java rename to core/src/main/java/bisq/core/dao/node/explorer/JsonTxInput.java index 684d6031d89..6c7ea14222c 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonTxInput.java +++ b/core/src/main/java/bisq/core/dao/node/explorer/JsonTxInput.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.node.json; +package bisq.core.dao.node.explorer; import lombok.Value; diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonTxOutput.java b/core/src/main/java/bisq/core/dao/node/explorer/JsonTxOutput.java similarity index 98% rename from core/src/main/java/bisq/core/dao/node/json/JsonTxOutput.java rename to core/src/main/java/bisq/core/dao/node/explorer/JsonTxOutput.java index ddbd9ac68e1..a2cd3ea4b3e 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonTxOutput.java +++ b/core/src/main/java/bisq/core/dao/node/explorer/JsonTxOutput.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.node.json; +package bisq.core.dao.node.explorer; import bisq.common.app.Version; diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonTxOutputType.java b/core/src/main/java/bisq/core/dao/node/explorer/JsonTxOutputType.java similarity index 97% rename from core/src/main/java/bisq/core/dao/node/json/JsonTxOutputType.java rename to core/src/main/java/bisq/core/dao/node/explorer/JsonTxOutputType.java index 9ca86c19985..15bfab0f2c4 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonTxOutputType.java +++ b/core/src/main/java/bisq/core/dao/node/explorer/JsonTxOutputType.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.node.json; +package bisq.core.dao.node.explorer; import lombok.Getter; diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonTxType.java b/core/src/main/java/bisq/core/dao/node/explorer/JsonTxType.java similarity index 97% rename from core/src/main/java/bisq/core/dao/node/json/JsonTxType.java rename to core/src/main/java/bisq/core/dao/node/explorer/JsonTxType.java index 56d92336174..f0a47960b83 100644 --- a/core/src/main/java/bisq/core/dao/node/json/JsonTxType.java +++ b/core/src/main/java/bisq/core/dao/node/explorer/JsonTxType.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.node.json; +package bisq.core.dao.node.explorer; import lombok.Getter; diff --git a/core/src/main/java/bisq/core/dao/node/explorer/package-info.java b/core/src/main/java/bisq/core/dao/node/explorer/package-info.java new file mode 100644 index 00000000000..30fc3a6f49c --- /dev/null +++ b/core/src/main/java/bisq/core/dao/node/explorer/package-info.java @@ -0,0 +1,22 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +/** + * Contains classes which are only used for providing data to the BSQ explorer. + */ + +package bisq.core.dao.node.explorer; diff --git a/core/src/main/java/bisq/core/dao/node/full/FullNode.java b/core/src/main/java/bisq/core/dao/node/full/FullNode.java index 3834bab32e4..0c8e814277a 100644 --- a/core/src/main/java/bisq/core/dao/node/full/FullNode.java +++ b/core/src/main/java/bisq/core/dao/node/full/FullNode.java @@ -18,13 +18,13 @@ package bisq.core.dao.node.full; import bisq.core.dao.node.BsqNode; +import bisq.core.dao.node.explorer.ExportJsonFilesService; import bisq.core.dao.node.full.network.FullNodeNetworkService; -import bisq.core.dao.node.json.ExportJsonFilesService; import bisq.core.dao.node.parser.BlockParser; import bisq.core.dao.node.parser.exceptions.BlockNotConnectingException; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateSnapshotService; -import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Block; import bisq.network.p2p.P2PService; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/RawBlock.java b/core/src/main/java/bisq/core/dao/node/full/RawBlock.java similarity index 92% rename from core/src/main/java/bisq/core/dao/state/blockchain/RawBlock.java rename to core/src/main/java/bisq/core/dao/node/full/RawBlock.java index 6203296f11e..40101ed6655 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/RawBlock.java +++ b/core/src/main/java/bisq/core/dao/node/full/RawBlock.java @@ -15,7 +15,10 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.node.full; + +import bisq.core.dao.state.model.blockchain.BaseBlock; +import bisq.core.dao.state.model.blockchain.Block; import bisq.common.proto.network.NetworkPayload; @@ -54,11 +57,11 @@ public static RawBlock fromBlock(Block block) { private final ImmutableList rawTxs; - public RawBlock(int height, - long time, - String hash, - String previousBlockHash, - ImmutableList rawTxs) { + RawBlock(int height, + long time, + String hash, + String previousBlockHash, + ImmutableList rawTxs) { super(height, time, hash, diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/RawTx.java b/core/src/main/java/bisq/core/dao/node/full/RawTx.java similarity index 91% rename from core/src/main/java/bisq/core/dao/state/blockchain/RawTx.java rename to core/src/main/java/bisq/core/dao/node/full/RawTx.java index 49ad24543bf..187fd21ca71 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/RawTx.java +++ b/core/src/main/java/bisq/core/dao/node/full/RawTx.java @@ -15,7 +15,11 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.node.full; + +import bisq.core.dao.state.model.blockchain.BaseTx; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxInput; import bisq.common.app.Version; import bisq.common.proto.network.NetworkPayload; @@ -61,12 +65,12 @@ public static RawTx fromTx(Tx tx) { private final ImmutableList rawTxOutputs; // The RPC service is creating a RawTx. - public RawTx(String id, - int blockHeight, - String blockHash, - long time, - ImmutableList txInputs, - ImmutableList rawTxOutputs) { + RawTx(String id, + int blockHeight, + String blockHash, + long time, + ImmutableList txInputs, + ImmutableList rawTxOutputs) { super(Version.BSQ_TX_VERSION, id, blockHeight, diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/RawTxOutput.java b/core/src/main/java/bisq/core/dao/node/full/RawTxOutput.java similarity index 85% rename from core/src/main/java/bisq/core/dao/state/blockchain/RawTxOutput.java rename to core/src/main/java/bisq/core/dao/node/full/RawTxOutput.java index 68b22cef04b..02b23f658b9 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/RawTxOutput.java +++ b/core/src/main/java/bisq/core/dao/node/full/RawTxOutput.java @@ -15,7 +15,11 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.node.full; + +import bisq.core.dao.state.model.blockchain.BaseTxOutput; +import bisq.core.dao.state.model.blockchain.PubKeyScript; +import bisq.core.dao.state.model.blockchain.TxOutput; import bisq.common.proto.network.NetworkPayload; @@ -47,13 +51,13 @@ public static RawTxOutput fromTxOutput(TxOutput txOutput) { txOutput.getBlockHeight()); } - public RawTxOutput(int index, - long value, - String txId, - @Nullable PubKeyScript pubKeyScript, - @Nullable String address, - @Nullable byte[] opReturnData, - int blockHeight) { + RawTxOutput(int index, + long value, + String txId, + @Nullable PubKeyScript pubKeyScript, + @Nullable String address, + @Nullable byte[] opReturnData, + int blockHeight) { super(index, value, txId, diff --git a/core/src/main/java/bisq/core/dao/node/full/RpcService.java b/core/src/main/java/bisq/core/dao/node/full/RpcService.java index 6ca070c67a5..fe7b3de5284 100644 --- a/core/src/main/java/bisq/core/dao/node/full/RpcService.java +++ b/core/src/main/java/bisq/core/dao/node/full/RpcService.java @@ -19,11 +19,8 @@ import bisq.core.app.BisqEnvironment; import bisq.core.dao.DaoOptionKeys; -import bisq.core.dao.state.blockchain.PubKeyScript; -import bisq.core.dao.state.blockchain.RawBlock; -import bisq.core.dao.state.blockchain.RawTx; -import bisq.core.dao.state.blockchain.RawTxOutput; -import bisq.core.dao.state.blockchain.TxInput; +import bisq.core.dao.state.model.blockchain.PubKeyScript; +import bisq.core.dao.state.model.blockchain.TxInput; import bisq.core.user.Preferences; import bisq.common.UserThread; diff --git a/core/src/main/java/bisq/core/dao/node/full/network/FullNodeNetworkService.java b/core/src/main/java/bisq/core/dao/node/full/network/FullNodeNetworkService.java index 8c9fef8931c..d0d040cc86c 100644 --- a/core/src/main/java/bisq/core/dao/node/full/network/FullNodeNetworkService.java +++ b/core/src/main/java/bisq/core/dao/node/full/network/FullNodeNetworkService.java @@ -22,11 +22,11 @@ import bisq.core.dao.governance.blindvote.storage.BlindVotePayload; import bisq.core.dao.governance.proposal.ProposalService; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalPayload; +import bisq.core.dao.node.full.RawBlock; import bisq.core.dao.node.messages.GetBlocksRequest; import bisq.core.dao.node.messages.NewBlockBroadcastMessage; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.RawBlock; +import bisq.core.dao.state.model.blockchain.Block; import bisq.network.p2p.P2PService; import bisq.network.p2p.network.Connection; diff --git a/core/src/main/java/bisq/core/dao/node/full/network/GetBlocksRequestHandler.java b/core/src/main/java/bisq/core/dao/node/full/network/GetBlocksRequestHandler.java index 5b885fb8e40..e0c2a7482c4 100644 --- a/core/src/main/java/bisq/core/dao/node/full/network/GetBlocksRequestHandler.java +++ b/core/src/main/java/bisq/core/dao/node/full/network/GetBlocksRequestHandler.java @@ -17,11 +17,11 @@ package bisq.core.dao.node.full.network; +import bisq.core.dao.node.full.RawBlock; import bisq.core.dao.node.messages.GetBlocksRequest; import bisq.core.dao.node.messages.GetBlocksResponse; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.RawBlock; +import bisq.core.dao.state.model.blockchain.Block; import bisq.network.p2p.network.CloseConnectionReason; import bisq.network.p2p.network.Connection; diff --git a/core/src/main/java/bisq/core/dao/node/lite/LiteNode.java b/core/src/main/java/bisq/core/dao/node/lite/LiteNode.java index 1a4c1664ef8..89dd0ba3c31 100644 --- a/core/src/main/java/bisq/core/dao/node/lite/LiteNode.java +++ b/core/src/main/java/bisq/core/dao/node/lite/LiteNode.java @@ -18,6 +18,7 @@ package bisq.core.dao.node.lite; import bisq.core.dao.node.BsqNode; +import bisq.core.dao.node.full.RawBlock; import bisq.core.dao.node.lite.network.LiteNodeNetworkService; import bisq.core.dao.node.messages.GetBlocksResponse; import bisq.core.dao.node.messages.NewBlockBroadcastMessage; @@ -25,7 +26,6 @@ import bisq.core.dao.node.parser.exceptions.BlockNotConnectingException; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateSnapshotService; -import bisq.core.dao.state.blockchain.RawBlock; import bisq.network.p2p.P2PService; import bisq.network.p2p.network.Connection; diff --git a/core/src/main/java/bisq/core/dao/node/messages/GetBlocksResponse.java b/core/src/main/java/bisq/core/dao/node/messages/GetBlocksResponse.java index c8b244d2ef5..74d1923f155 100644 --- a/core/src/main/java/bisq/core/dao/node/messages/GetBlocksResponse.java +++ b/core/src/main/java/bisq/core/dao/node/messages/GetBlocksResponse.java @@ -17,7 +17,7 @@ package bisq.core.dao.node.messages; -import bisq.core.dao.state.blockchain.RawBlock; +import bisq.core.dao.node.full.RawBlock; import bisq.network.p2p.DirectMessage; import bisq.network.p2p.ExtendedDataSizePermission; diff --git a/core/src/main/java/bisq/core/dao/node/messages/NewBlockBroadcastMessage.java b/core/src/main/java/bisq/core/dao/node/messages/NewBlockBroadcastMessage.java index 0d565e508c3..fea0f3295fa 100644 --- a/core/src/main/java/bisq/core/dao/node/messages/NewBlockBroadcastMessage.java +++ b/core/src/main/java/bisq/core/dao/node/messages/NewBlockBroadcastMessage.java @@ -17,7 +17,7 @@ package bisq.core.dao.node.messages; -import bisq.core.dao.state.blockchain.RawBlock; +import bisq.core.dao.node.full.RawBlock; import bisq.network.p2p.storage.messages.BroadcastMessage; import bisq.network.p2p.storage.payload.CapabilityRequiringPayload; diff --git a/core/src/main/java/bisq/core/dao/node/parser/BlockParser.java b/core/src/main/java/bisq/core/dao/node/parser/BlockParser.java index 7b8f0206d51..f7e1904ca0c 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/BlockParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/BlockParser.java @@ -17,11 +17,11 @@ package bisq.core.dao.node.parser; +import bisq.core.dao.node.full.RawBlock; import bisq.core.dao.node.parser.exceptions.BlockNotConnectingException; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.RawBlock; -import bisq.core.dao.state.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Tx; import bisq.common.app.DevEnv; diff --git a/core/src/main/java/bisq/core/dao/node/parser/GenesisTxParser.java b/core/src/main/java/bisq/core/dao/node/parser/GenesisTxParser.java index 76808576fcf..ae4aea62c72 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/GenesisTxParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/GenesisTxParser.java @@ -17,15 +17,13 @@ package bisq.core.dao.node.parser; +import bisq.core.dao.node.full.RawTx; import bisq.core.dao.node.parser.exceptions.InvalidGenesisTxException; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.RawTx; -import bisq.core.dao.state.blockchain.TempTx; -import bisq.core.dao.state.blockchain.TempTxOutput; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxOutputType; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxOutputType; +import bisq.core.dao.state.model.blockchain.TxType; import org.bitcoinj.core.Coin; diff --git a/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java b/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java index 5b5a10db3cb..1723637d477 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java @@ -17,15 +17,14 @@ package bisq.core.dao.node.parser; -import bisq.core.dao.bonding.BondingConsensus; -import bisq.core.dao.bonding.lockup.LockupType; import bisq.core.dao.governance.blindvote.BlindVoteConsensus; +import bisq.core.dao.governance.bonding.BondingConsensus; +import bisq.core.dao.governance.bonding.lockup.LockupType; import bisq.core.dao.governance.proposal.ProposalConsensus; import bisq.core.dao.governance.voteresult.VoteResultConsensus; import bisq.core.dao.node.parser.exceptions.InvalidParsingConditionException; -import bisq.core.dao.state.blockchain.OpReturnType; -import bisq.core.dao.state.blockchain.TempTxOutput; -import bisq.core.dao.state.blockchain.TxOutputType; +import bisq.core.dao.state.model.blockchain.OpReturnType; +import bisq.core.dao.state.model.blockchain.TxOutputType; import bisq.common.util.Utilities; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TempTx.java b/core/src/main/java/bisq/core/dao/node/parser/TempTx.java similarity index 93% rename from core/src/main/java/bisq/core/dao/state/blockchain/TempTx.java rename to core/src/main/java/bisq/core/dao/node/parser/TempTx.java index a2282f3fe6c..a2e37ff2f22 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TempTx.java +++ b/core/src/main/java/bisq/core/dao/node/parser/TempTx.java @@ -15,7 +15,12 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.node.parser; + +import bisq.core.dao.node.full.RawTx; +import bisq.core.dao.state.model.blockchain.BaseTx; +import bisq.core.dao.state.model.blockchain.TxInput; +import bisq.core.dao.state.model.blockchain.TxType; import com.google.common.collect.ImmutableList; @@ -33,7 +38,7 @@ */ @Data public class TempTx extends BaseTx { - public static TempTx fromRawTx(RawTx rawTx) { + static TempTx fromRawTx(RawTx rawTx) { return new TempTx(rawTx.getTxVersion(), rawTx.getId(), rawTx.getBlockHeight(), diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TempTxOutput.java b/core/src/main/java/bisq/core/dao/node/parser/TempTxOutput.java similarity index 92% rename from core/src/main/java/bisq/core/dao/state/blockchain/TempTxOutput.java rename to core/src/main/java/bisq/core/dao/node/parser/TempTxOutput.java index 85f3c380772..0109dc656fc 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TempTxOutput.java +++ b/core/src/main/java/bisq/core/dao/node/parser/TempTxOutput.java @@ -15,7 +15,12 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.node.parser; + +import bisq.core.dao.node.full.RawTxOutput; +import bisq.core.dao.state.model.blockchain.BaseTxOutput; +import bisq.core.dao.state.model.blockchain.PubKeyScript; +import bisq.core.dao.state.model.blockchain.TxOutputType; import java.util.Objects; @@ -29,7 +34,7 @@ */ @Data public class TempTxOutput extends BaseTxOutput { - public static TempTxOutput fromRawTxOutput(RawTxOutput txOutput) { + static TempTxOutput fromRawTxOutput(RawTxOutput txOutput) { return new TempTxOutput(txOutput.getIndex(), txOutput.getValue(), txOutput.getTxId(), diff --git a/core/src/main/java/bisq/core/dao/node/parser/TxInputParser.java b/core/src/main/java/bisq/core/dao/node/parser/TxInputParser.java index 5fbee267cea..9fe65596209 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/TxInputParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/TxInputParser.java @@ -18,10 +18,10 @@ package bisq.core.dao.node.parser; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.SpentInfo; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxOutputKey; -import bisq.core.dao.state.blockchain.TxOutputType; +import bisq.core.dao.state.model.blockchain.SpentInfo; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxOutputKey; +import bisq.core.dao.state.model.blockchain.TxOutputType; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java b/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java index e264fde85a2..42a7906a37d 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java @@ -17,12 +17,11 @@ package bisq.core.dao.node.parser; -import bisq.core.dao.bonding.BondingConsensus; +import bisq.core.dao.governance.bonding.BondingConsensus; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.OpReturnType; -import bisq.core.dao.state.blockchain.TempTxOutput; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxOutputType; +import bisq.core.dao.state.model.blockchain.OpReturnType; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxOutputType; import com.google.common.annotations.VisibleForTesting; diff --git a/core/src/main/java/bisq/core/dao/node/parser/TxParser.java b/core/src/main/java/bisq/core/dao/node/parser/TxParser.java index 332ce3cfa62..fb22a62ebc5 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/TxParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/TxParser.java @@ -17,20 +17,18 @@ package bisq.core.dao.node.parser; -import bisq.core.dao.period.PeriodService; +import bisq.core.dao.governance.param.Param; +import bisq.core.dao.governance.period.PeriodService; +import bisq.core.dao.node.full.RawTx; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.OpReturnType; -import bisq.core.dao.state.blockchain.RawTx; -import bisq.core.dao.state.blockchain.TempTx; -import bisq.core.dao.state.blockchain.TempTxOutput; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxInput; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxOutputKey; -import bisq.core.dao.state.blockchain.TxOutputType; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.Param; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.OpReturnType; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxInput; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxOutputKey; +import bisq.core.dao.state.model.blockchain.TxOutputType; +import bisq.core.dao.state.model.blockchain.TxType; +import bisq.core.dao.state.model.governance.DaoPhase; import org.bitcoinj.core.Coin; diff --git a/core/src/main/java/bisq/core/dao/node/parser/exceptions/BlockNotConnectingException.java b/core/src/main/java/bisq/core/dao/node/parser/exceptions/BlockNotConnectingException.java index c51d9edb1b3..357257994e4 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/exceptions/BlockNotConnectingException.java +++ b/core/src/main/java/bisq/core/dao/node/parser/exceptions/BlockNotConnectingException.java @@ -17,7 +17,7 @@ package bisq.core.dao.node.parser.exceptions; -import bisq.core.dao.state.blockchain.RawBlock; +import bisq.core.dao.node.full.RawBlock; import lombok.Getter; diff --git a/core/src/main/java/bisq/core/dao/node/parser/exceptions/InvalidBlockException.java b/core/src/main/java/bisq/core/dao/node/parser/exceptions/InvalidBlockException.java index ab545a5428a..2d5262367a5 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/exceptions/InvalidBlockException.java +++ b/core/src/main/java/bisq/core/dao/node/parser/exceptions/InvalidBlockException.java @@ -17,8 +17,8 @@ package bisq.core.dao.node.parser.exceptions; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.RawBlock; +import bisq.core.dao.node.full.RawBlock; +import bisq.core.dao.state.model.blockchain.Block; import lombok.EqualsAndHashCode; import lombok.Value; diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateListener.java b/core/src/main/java/bisq/core/dao/state/DaoStateListener.java index 4bd05538d4f..f1204efde79 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateListener.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateListener.java @@ -17,7 +17,7 @@ package bisq.core.dao.state; -import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Block; public interface DaoStateListener { void onNewBlockHeight(int blockHeight); diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateService.java b/core/src/main/java/bisq/core/dao/state/DaoStateService.java index f94ce0f2ae7..7c05ed9d28d 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateService.java @@ -18,23 +18,24 @@ package bisq.core.dao.state; import bisq.core.dao.DaoSetupService; -import bisq.core.dao.bonding.BondingConsensus; -import bisq.core.dao.governance.voteresult.DecryptedBallotsWithMerits; -import bisq.core.dao.governance.voteresult.EvaluatedProposal; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.SpentInfo; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.blockchain.TxInput; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxOutputKey; -import bisq.core.dao.state.blockchain.TxOutputType; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.ConfiscateBond; -import bisq.core.dao.state.governance.Issuance; -import bisq.core.dao.state.governance.IssuanceType; -import bisq.core.dao.state.governance.Param; -import bisq.core.dao.state.governance.ParamChange; -import bisq.core.dao.state.period.Cycle; +import bisq.core.dao.governance.bond.ConfiscateBond; +import bisq.core.dao.governance.bonding.BondingConsensus; +import bisq.core.dao.governance.param.Param; +import bisq.core.dao.state.model.DaoState; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.SpentInfo; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.blockchain.TxInput; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxOutputKey; +import bisq.core.dao.state.model.blockchain.TxOutputType; +import bisq.core.dao.state.model.blockchain.TxType; +import bisq.core.dao.state.model.governance.Cycle; +import bisq.core.dao.state.model.governance.DecryptedBallotsWithMerits; +import bisq.core.dao.state.model.governance.EvaluatedProposal; +import bisq.core.dao.state.model.governance.Issuance; +import bisq.core.dao.state.model.governance.IssuanceType; +import bisq.core.dao.state.model.governance.ParamChange; import bisq.core.util.BsqFormatter; import org.bitcoinj.core.Coin; @@ -131,11 +132,11 @@ public void applySnapshot(DaoState snapshot) { } public DaoState getClone() { - return daoState.getClone(); + return DaoState.getClone(daoState); } DaoState getClone(DaoState snapshotCandidate) { - return daoState.getClone(snapshotCandidate); + return DaoState.getClone(snapshotCandidate); } diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateSnapshotService.java b/core/src/main/java/bisq/core/dao/state/DaoStateSnapshotService.java index 72726d9d1e6..b110665c237 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateSnapshotService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateSnapshotService.java @@ -17,7 +17,8 @@ package bisq.core.dao.state; -import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.model.DaoState; +import bisq.core.dao.state.model.blockchain.Block; import javax.inject.Inject; diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateStorageService.java b/core/src/main/java/bisq/core/dao/state/DaoStateStorageService.java index 4ec8f041cee..25ff8e405fb 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateStorageService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateStorageService.java @@ -17,6 +17,8 @@ package bisq.core.dao.state; +import bisq.core.dao.state.model.DaoState; + import bisq.network.p2p.storage.persistence.ResourceDataStoreService; import bisq.network.p2p.storage.persistence.StoreService; @@ -92,6 +94,6 @@ public void resetDaoState(Runnable resultHandler) { @Override protected DaoStateStore createStore() { - return new DaoStateStore(daoState.getClone()); + return new DaoStateStore(DaoState.getClone(daoState)); } } diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateStore.java b/core/src/main/java/bisq/core/dao/state/DaoStateStore.java index 34e4162f407..b6080a28a3b 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateStore.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateStore.java @@ -17,6 +17,8 @@ package bisq.core.dao.state; +import bisq.core.dao.state.model.DaoState; + import bisq.common.proto.persistable.PersistableEnvelope; import io.bisq.generated.protobuffer.PB; diff --git a/core/src/main/java/bisq/core/dao/state/DaoState.java b/core/src/main/java/bisq/core/dao/state/model/DaoState.java similarity index 90% rename from core/src/main/java/bisq/core/dao/state/DaoState.java rename to core/src/main/java/bisq/core/dao/state/model/DaoState.java index 5346d9b8647..f191d220c67 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoState.java +++ b/core/src/main/java/bisq/core/dao/state/model/DaoState.java @@ -15,17 +15,17 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state; - -import bisq.core.dao.governance.voteresult.DecryptedBallotsWithMerits; -import bisq.core.dao.governance.voteresult.EvaluatedProposal; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.SpentInfo; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxOutputKey; -import bisq.core.dao.state.governance.Issuance; -import bisq.core.dao.state.governance.ParamChange; -import bisq.core.dao.state.period.Cycle; +package bisq.core.dao.state.model; + +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.SpentInfo; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxOutputKey; +import bisq.core.dao.state.model.governance.Cycle; +import bisq.core.dao.state.model.governance.DecryptedBallotsWithMerits; +import bisq.core.dao.state.model.governance.EvaluatedProposal; +import bisq.core.dao.state.model.governance.Issuance; +import bisq.core.dao.state.model.governance.ParamChange; import bisq.common.proto.persistable.PersistablePayload; @@ -55,6 +55,15 @@ @Slf4j public class DaoState implements PersistablePayload { + /////////////////////////////////////////////////////////////////////////////////////////// + // Static + /////////////////////////////////////////////////////////////////////////////////////////// + + public static DaoState getClone(DaoState daoState) { + return DaoState.fromProto(daoState.getBsqStateBuilder().build()); + } + + /////////////////////////////////////////////////////////////////////////////////////////// // Fields /////////////////////////////////////////////////////////////////////////////////////////// @@ -205,18 +214,10 @@ public static DaoState fromProto(PB.BsqState proto) { /////////////////////////////////////////////////////////////////////////////////////////// - // Package scope access + // API /////////////////////////////////////////////////////////////////////////////////////////// - void setChainHeight(int chainHeight) { + public void setChainHeight(int chainHeight) { this.chainHeight = chainHeight; } - - DaoState getClone() { - return DaoState.fromProto(getBsqStateBuilder().build()); - } - - DaoState getClone(DaoState snapshotCandidate) { - return DaoState.fromProto(snapshotCandidate.getBsqStateBuilder().build()); - } } diff --git a/core/src/main/java/bisq/core/dao/state/ImmutableDaoStateVo.java b/core/src/main/java/bisq/core/dao/state/model/ImmutableDaoStateModel.java similarity index 83% rename from core/src/main/java/bisq/core/dao/state/ImmutableDaoStateVo.java rename to core/src/main/java/bisq/core/dao/state/model/ImmutableDaoStateModel.java index 35c6fc4dffd..010873ad6ff 100644 --- a/core/src/main/java/bisq/core/dao/state/ImmutableDaoStateVo.java +++ b/core/src/main/java/bisq/core/dao/state/model/ImmutableDaoStateModel.java @@ -15,10 +15,10 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state; +package bisq.core.dao.state.model; /** - * Market interface for objects which are stored in the daoState and therefore they need to be immutable. + * Marker interface for objects which are stored in the daoState and therefore they need to be immutable. */ -public interface ImmutableDaoStateVo { +public interface ImmutableDaoStateModel { } diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/BaseBlock.java similarity index 87% rename from core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/BaseBlock.java index ebc6c4b4f7f..7691f51328b 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/BaseBlock.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/BaseBlock.java @@ -15,7 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; + +import bisq.core.dao.state.model.ImmutableDaoStateModel; import io.bisq.generated.protobuffer.PB; @@ -32,14 +34,14 @@ */ @Immutable @Data -public abstract class BaseBlock { +public abstract class BaseBlock implements ImmutableDaoStateModel { protected final int height; protected final long time; // in ms protected final String hash; @Nullable // in case of first block in the blockchain protected final String previousBlockHash; - BaseBlock(int height, long time, String hash, String previousBlockHash) { + public BaseBlock(int height, long time, String hash, String previousBlockHash) { this.height = height; this.time = time; this.hash = hash; @@ -51,7 +53,7 @@ public abstract class BaseBlock { // PROTO BUFFER /////////////////////////////////////////////////////////////////////////////////////////// - PB.BaseBlock.Builder getBaseBlockBuilder() { + public PB.BaseBlock.Builder getBaseBlockBuilder() { PB.BaseBlock.Builder builder = PB.BaseBlock.newBuilder() .setHeight(height) .setTime(time) diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/BaseTx.java similarity index 86% rename from core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/BaseTx.java index 2503f07bb13..7e111b0e8d2 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTx.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/BaseTx.java @@ -15,7 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; + +import bisq.core.dao.state.model.ImmutableDaoStateModel; import io.bisq.generated.protobuffer.PB; @@ -40,7 +42,7 @@ @Slf4j @Getter @EqualsAndHashCode -public abstract class BaseTx { +public abstract class BaseTx implements ImmutableDaoStateModel { protected final String txVersion; protected final String id; protected final int blockHeight; @@ -53,12 +55,12 @@ public abstract class BaseTx { // PROTO BUFFER /////////////////////////////////////////////////////////////////////////////////////////// - BaseTx(String txVersion, - String id, - int blockHeight, - String blockHash, - long time, - ImmutableList txInputs) { + public BaseTx(String txVersion, + String id, + int blockHeight, + String blockHash, + long time, + ImmutableList txInputs) { this.txVersion = txVersion; this.id = id; this.blockHeight = blockHeight; @@ -67,7 +69,7 @@ public abstract class BaseTx { this.txInputs = txInputs; } - PB.BaseTx.Builder getBaseTxBuilder() { + public PB.BaseTx.Builder getBaseTxBuilder() { return PB.BaseTx.newBuilder() .setTxVersion(txVersion) .setId(id) diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/BaseTxOutput.java similarity index 85% rename from core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/BaseTxOutput.java index e66e9f06e0e..e8b5015ccf9 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/BaseTxOutput.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/BaseTxOutput.java @@ -15,7 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; + +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.util.JsonExclude; import bisq.common.util.Utilities; @@ -38,7 +40,7 @@ @Slf4j @Immutable @Data -public abstract class BaseTxOutput { +public abstract class BaseTxOutput implements ImmutableDaoStateModel { protected final int index; protected final long value; protected final String txId; @@ -53,13 +55,13 @@ public abstract class BaseTxOutput { protected final byte[] opReturnData; protected final int blockHeight; - BaseTxOutput(int index, - long value, - String txId, - @Nullable PubKeyScript pubKeyScript, - @Nullable String address, - @Nullable byte[] opReturnData, - int blockHeight) { + public BaseTxOutput(int index, + long value, + String txId, + @Nullable PubKeyScript pubKeyScript, + @Nullable String address, + @Nullable byte[] opReturnData, + int blockHeight) { this.index = index; this.value = value; this.txId = txId; @@ -75,7 +77,7 @@ public abstract class BaseTxOutput { // PROTO BUFFER /////////////////////////////////////////////////////////////////////////////////////////// - PB.BaseTxOutput.Builder getRawTxOutputBuilder() { + public PB.BaseTxOutput.Builder getRawTxOutputBuilder() { final PB.BaseTxOutput.Builder builder = PB.BaseTxOutput.newBuilder() .setIndex(index) .setValue(value) diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/Block.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/Block.java similarity index 96% rename from core/src/main/java/bisq/core/dao/state/blockchain/Block.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/Block.java index aad0ee530c4..511b5e20dde 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/Block.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/Block.java @@ -15,7 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; + +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; @@ -42,7 +44,7 @@ */ @EqualsAndHashCode(callSuper = true) @Value -public final class Block extends BaseBlock implements PersistablePayload { +public final class Block extends BaseBlock implements PersistablePayload, ImmutableDaoStateModel { private final List txs; public Block(int height, long time, String hash, String previousBlockHash) { diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/OpReturnType.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/OpReturnType.java similarity index 90% rename from core/src/main/java/bisq/core/dao/state/blockchain/OpReturnType.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/OpReturnType.java index bea29be71c3..d693f3c56bf 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/OpReturnType.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/OpReturnType.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import java.util.Arrays; import java.util.Optional; @@ -30,7 +30,7 @@ * Provides byte constants for distinguishing the type of a DAO transaction used in the OP_RETURN data. */ @Immutable -public enum OpReturnType implements ImmutableDaoStateVo { +public enum OpReturnType implements ImmutableDaoStateModel { //TODO add undefined ? PROPOSAL((byte) 0x10), COMPENSATION_REQUEST((byte) 0x11), diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/PubKeyScript.java similarity index 96% rename from core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/PubKeyScript.java index 743f957424d..40152888844 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/PubKeyScript.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/PubKeyScript.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; @@ -37,7 +37,7 @@ @Immutable @Value @AllArgsConstructor -public class PubKeyScript implements PersistablePayload, ImmutableDaoStateVo { +public class PubKeyScript implements PersistablePayload, ImmutableDaoStateModel { private final int reqSigs; private final ScriptType scriptType; @Nullable diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/ScriptType.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/ScriptType.java similarity index 94% rename from core/src/main/java/bisq/core/dao/state/blockchain/ScriptType.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/ScriptType.java index 7758fb9ff73..e41ce970153 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/ScriptType.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/ScriptType.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.ProtoUtil; @@ -38,7 +38,7 @@ @AllArgsConstructor @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -public enum ScriptType implements ImmutableDaoStateVo { +public enum ScriptType implements ImmutableDaoStateModel { // https://github.com/bitcoin/bitcoin/blob/master/src/script/standard.cpp PUB_KEY("pubkey"), diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/SpentInfo.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/SpentInfo.java similarity index 94% rename from core/src/main/java/bisq/core/dao/state/blockchain/SpentInfo.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/SpentInfo.java index 0dfb5c5738b..8c3f0033cc8 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/SpentInfo.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/SpentInfo.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; @@ -29,7 +29,7 @@ @Immutable @Value -public final class SpentInfo implements PersistablePayload, ImmutableDaoStateVo { +public final class SpentInfo implements PersistablePayload, ImmutableDaoStateModel { private final long blockHeight; // Spending tx private final String txId; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/Tx.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java similarity index 97% rename from core/src/main/java/bisq/core/dao/state/blockchain/Tx.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java index a5ac1261aa5..a5ce9023a43 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/Tx.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java @@ -15,9 +15,10 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.node.parser.TempTx; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; @@ -41,7 +42,7 @@ */ @Immutable @Value -public final class Tx extends BaseTx implements PersistablePayload, ImmutableDaoStateVo { +public final class Tx extends BaseTx implements PersistablePayload, ImmutableDaoStateModel { // Created after parsing of a tx is completed. We store only the immutable tx in the block. public static Tx fromTempTx(TempTx tempTx) { ImmutableList txOutputs = ImmutableList.copyOf(tempTx.getTempTxOutputs().stream() diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxInput.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/TxInput.java similarity index 96% rename from core/src/main/java/bisq/core/dao/state/blockchain/TxInput.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/TxInput.java index b40f4a172fc..ac1d676a7a7 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxInput.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/TxInput.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; @@ -40,7 +40,7 @@ @Value @EqualsAndHashCode @Slf4j -public final class TxInput implements PersistablePayload, ImmutableDaoStateVo { +public final class TxInput implements PersistablePayload, ImmutableDaoStateModel { public static TxInput clone(TxInput txInput) { return new TxInput(txInput.getConnectedTxOutputTxId(), diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/TxOutput.java similarity index 96% rename from core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/TxOutput.java index efd030bfac9..f25866e05e7 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/TxOutput.java @@ -15,9 +15,10 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.node.parser.TempTxOutput; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; @@ -38,7 +39,7 @@ */ @Immutable @Data -public class TxOutput extends BaseTxOutput implements PersistablePayload, ImmutableDaoStateVo { +public class TxOutput extends BaseTxOutput implements PersistablePayload, ImmutableDaoStateModel { public static TxOutput fromTempOutput(TempTxOutput tempTxOutput) { return new TxOutput(tempTxOutput.getIndex(), tempTxOutput.getValue(), diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputKey.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/TxOutputKey.java similarity index 88% rename from core/src/main/java/bisq/core/dao/state/blockchain/TxOutputKey.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/TxOutputKey.java index 75ef199f726..11ebec2a896 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputKey.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/TxOutputKey.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import lombok.Value; @@ -29,7 +29,7 @@ */ @Immutable @Value -public final class TxOutputKey implements ImmutableDaoStateVo { +public final class TxOutputKey implements ImmutableDaoStateModel { private final String txId; private final int index; diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputType.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/TxOutputType.java similarity index 91% rename from core/src/main/java/bisq/core/dao/state/blockchain/TxOutputType.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/TxOutputType.java index e97d42adcec..81532ed0540 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxOutputType.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/TxOutputType.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.ProtoUtil; @@ -26,7 +26,7 @@ import javax.annotation.concurrent.Immutable; @Immutable -public enum TxOutputType implements ImmutableDaoStateVo { +public enum TxOutputType implements ImmutableDaoStateModel { UNDEFINED_OUTPUT, GENESIS_OUTPUT, BSQ_OUTPUT, diff --git a/core/src/main/java/bisq/core/dao/state/blockchain/TxType.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/TxType.java similarity index 92% rename from core/src/main/java/bisq/core/dao/state/blockchain/TxType.java rename to core/src/main/java/bisq/core/dao/state/model/blockchain/TxType.java index 081442e41ae..cb6d7a0e3a4 100644 --- a/core/src/main/java/bisq/core/dao/state/blockchain/TxType.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/TxType.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.blockchain; +package bisq.core.dao.state.model.blockchain; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.ProtoUtil; @@ -29,7 +29,7 @@ import javax.annotation.concurrent.Immutable; @Immutable -public enum TxType implements ImmutableDaoStateVo { +public enum TxType implements ImmutableDaoStateModel { UNDEFINED_TX_TYPE(false, false), UNVERIFIED(false, false), INVALID(false, false), diff --git a/core/src/main/java/bisq/core/dao/state/model/blockchain/package-info.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/package-info.java new file mode 100644 index 00000000000..ce91db41337 --- /dev/null +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/package-info.java @@ -0,0 +1,22 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +/** + * Holds all blockchain specific data which are used in the daoState. + */ + +package bisq.core.dao.state.model.blockchain; diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/Ballot.java b/core/src/main/java/bisq/core/dao/state/model/governance/Ballot.java new file mode 100644 index 00000000000..5949d287faf --- /dev/null +++ b/core/src/main/java/bisq/core/dao/state/model/governance/Ballot.java @@ -0,0 +1,115 @@ +/* + * This file is part of Bisq. + * + * bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with bisq. If not, see . + */ + +package bisq.core.dao.state.model.governance; + +import bisq.core.dao.governance.ConsensusCritical; +import bisq.core.dao.governance.proposal.ProposalType; +import bisq.core.dao.state.model.ImmutableDaoStateModel; + +import bisq.common.proto.persistable.PersistablePayload; + +import io.bisq.generated.protobuffer.PB; + +import java.util.Optional; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +/** + * Base class for all ballots like compensation request, generic request, remove asset ballots and + * change param ballots. + * It contains the Proposal and the Vote. If a Proposal is ignored for voting the vote object is null. + * + * One proposal has about 278 bytes + */ +@Immutable +@Slf4j +@Getter +@EqualsAndHashCode +public final class Ballot implements PersistablePayload, ConsensusCritical, ImmutableDaoStateModel { + protected final Proposal proposal; + + @Nullable + protected Vote vote; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + + public Ballot(Proposal proposal) { + this(proposal, null); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + public Ballot(Proposal proposal, + @Nullable Vote vote) { + this.proposal = proposal; + this.vote = vote; + } + + @Override + public PB.Ballot toProtoMessage() { + final PB.Ballot.Builder builder = PB.Ballot.newBuilder() + .setProposal(proposal.getProposalBuilder()); + Optional.ofNullable(vote).ifPresent(e -> builder.setVote((PB.Vote) e.toProtoMessage())); + return builder.build(); + } + + public static Ballot fromProto(PB.Ballot proto) { + return new Ballot(Proposal.fromProto(proto.getProposal()), + proto.hasVote() ? Vote.fromProto(proto.getVote()) : null); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + public void setVote(@Nullable Vote vote) { + this.vote = vote; + } + + public ProposalType getType() { + return getProposal().getType(); + } + + public String getTxId() { + return proposal.getTxId(); + } + + public Optional getVoteAsOptional() { + return Optional.ofNullable(vote); + } + + @Override + public String toString() { + return "Ballot{" + + "\n proposal=" + proposal + + ",\n vote=" + vote + + "\n}"; + } +} diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/BallotList.java b/core/src/main/java/bisq/core/dao/state/model/governance/BallotList.java new file mode 100644 index 00000000000..1859e98fb47 --- /dev/null +++ b/core/src/main/java/bisq/core/dao/state/model/governance/BallotList.java @@ -0,0 +1,80 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.state.model.governance; + +import bisq.core.dao.governance.ConsensusCritical; +import bisq.core.dao.state.model.ImmutableDaoStateModel; + +import bisq.common.proto.persistable.PersistableList; + +import io.bisq.generated.protobuffer.PB; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import lombok.EqualsAndHashCode; + +import javax.annotation.concurrent.Immutable; + +/** + * PersistableEnvelope wrapper for list of ballots. + */ +@Immutable +@EqualsAndHashCode(callSuper = true) +public class BallotList extends PersistableList implements ConsensusCritical, ImmutableDaoStateModel { + + public BallotList(List list) { + super(list); + } + + public BallotList() { + super(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public PB.PersistableEnvelope toProtoMessage() { + return PB.PersistableEnvelope.newBuilder().setBallotList(getBuilder()).build(); + } + + public PB.BallotList.Builder getBuilder() { + return PB.BallotList.newBuilder() + .addAllBallot(getList().stream() + .map(Ballot::toProtoMessage) + .collect(Collectors.toList())); + } + + public static BallotList fromProto(PB.BallotList proto) { + return new BallotList(new ArrayList<>(proto.getBallotList().stream() + .map(Ballot::fromProto) + .collect(Collectors.toList()))); + } + + @Override + public String toString() { + return "List of UID's in BallotList: " + getList().stream() + .map(Ballot::getTxId) + .collect(Collectors.toList()); + } +} + diff --git a/core/src/main/java/bisq/core/dao/governance/role/BondedRoleType.java b/core/src/main/java/bisq/core/dao/state/model/governance/BondedRoleType.java similarity index 98% rename from core/src/main/java/bisq/core/dao/governance/role/BondedRoleType.java rename to core/src/main/java/bisq/core/dao/state/model/governance/BondedRoleType.java index 9e49280e0d9..97f0e580fb7 100644 --- a/core/src/main/java/bisq/core/dao/governance/role/BondedRoleType.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/BondedRoleType.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.role; +package bisq.core.dao.state.model.governance; import bisq.core.locale.Res; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java b/core/src/main/java/bisq/core/dao/state/model/governance/ChangeParamProposal.java similarity index 92% rename from core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java rename to core/src/main/java/bisq/core/dao/state/model/governance/ChangeParamProposal.java index c1a65bc3d92..b68c7877544 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposal.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/ChangeParamProposal.java @@ -15,13 +15,12 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.proposal.param; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.ProposalType; -import bisq.core.dao.state.ImmutableDaoStateVo; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.ImmutableDaoStateModel; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.app.Version; @@ -38,14 +37,14 @@ @Immutable @Slf4j @Value -public final class ChangeParamProposal extends Proposal implements ImmutableDaoStateVo { +public final class ChangeParamProposal extends Proposal implements ImmutableDaoStateModel { private final Param param; private final String paramValue; - ChangeParamProposal(String name, - String link, - Param param, - String paramValue) { + public ChangeParamProposal(String name, + String link, + Param param, + String paramValue) { this(name, link, param, diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposal.java b/core/src/main/java/bisq/core/dao/state/model/governance/CompensationProposal.java similarity index 91% rename from core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposal.java rename to core/src/main/java/bisq/core/dao/state/model/governance/CompensationProposal.java index 7e5cda722bf..13f42cbc286 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposal.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/CompensationProposal.java @@ -15,15 +15,14 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.proposal.compensation; +package bisq.core.dao.state.model.governance; import bisq.core.app.BisqEnvironment; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.IssuanceProposal; -import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; -import bisq.core.dao.state.ImmutableDaoStateVo; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.ImmutableDaoStateModel; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.app.Version; @@ -45,14 +44,14 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class CompensationProposal extends Proposal implements IssuanceProposal, ImmutableDaoStateVo { +public final class CompensationProposal extends Proposal implements IssuanceProposal, ImmutableDaoStateModel { private final long requestedBsq; private final String bsqAddress; - CompensationProposal(String name, - String link, - Coin requestedBsq, - String bsqAddress) { + public CompensationProposal(String name, + String link, + Coin requestedBsq, + String bsqAddress) { this(name, link, bsqAddress, diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposal.java b/core/src/main/java/bisq/core/dao/state/model/governance/ConfiscateBondProposal.java similarity index 90% rename from core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposal.java rename to core/src/main/java/bisq/core/dao/state/model/governance/ConfiscateBondProposal.java index c344a0fb5de..d5379a9e618 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposal.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/ConfiscateBondProposal.java @@ -15,13 +15,12 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.proposal.confiscatebond; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.ProposalType; -import bisq.core.dao.state.ImmutableDaoStateVo; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.ImmutableDaoStateModel; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.app.Version; import bisq.common.util.Utilities; @@ -42,12 +41,12 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class ConfiscateBondProposal extends Proposal implements ImmutableDaoStateVo { +public final class ConfiscateBondProposal extends Proposal implements ImmutableDaoStateModel { private final byte[] hash; - ConfiscateBondProposal(String name, - String link, - byte[] hash) { + public ConfiscateBondProposal(String name, + String link, + byte[] hash) { this(name, link, hash, diff --git a/core/src/main/java/bisq/core/dao/state/period/Cycle.java b/core/src/main/java/bisq/core/dao/state/model/governance/Cycle.java similarity index 97% rename from core/src/main/java/bisq/core/dao/state/period/Cycle.java rename to core/src/main/java/bisq/core/dao/state/model/governance/Cycle.java index 2d2f05cfc73..8e5e7971dfa 100644 --- a/core/src/main/java/bisq/core/dao/state/period/Cycle.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/Cycle.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.period; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; @@ -38,7 +38,7 @@ */ @Immutable @Value -public class Cycle implements PersistablePayload, ImmutableDaoStateVo { +public class Cycle implements PersistablePayload, ImmutableDaoStateModel { // List is ordered according to the Phase enum. private final ImmutableList daoPhaseList; private final int heightOfFirstBlock; diff --git a/core/src/main/java/bisq/core/dao/state/period/DaoPhase.java b/core/src/main/java/bisq/core/dao/state/model/governance/DaoPhase.java similarity index 94% rename from core/src/main/java/bisq/core/dao/state/period/DaoPhase.java rename to core/src/main/java/bisq/core/dao/state/model/governance/DaoPhase.java index e5d9a48e6e1..4594fd3466f 100644 --- a/core/src/main/java/bisq/core/dao/state/period/DaoPhase.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/DaoPhase.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.period; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; @@ -35,7 +35,7 @@ */ @Immutable @Value -public class DaoPhase implements PersistablePayload, ImmutableDaoStateVo { +public class DaoPhase implements PersistablePayload, ImmutableDaoStateModel { /** * Enum for phase of a cycle. @@ -44,7 +44,7 @@ public class DaoPhase implements PersistablePayload, ImmutableDaoStateVo { * should be considered immutable. */ @Immutable - public enum Phase implements ImmutableDaoStateVo { + public enum Phase implements ImmutableDaoStateModel { UNDEFINED, PROPOSAL, BREAK1, diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/DecryptedBallotsWithMerits.java b/core/src/main/java/bisq/core/dao/state/model/governance/DecryptedBallotsWithMerits.java similarity index 93% rename from core/src/main/java/bisq/core/dao/governance/voteresult/DecryptedBallotsWithMerits.java rename to core/src/main/java/bisq/core/dao/state/model/governance/DecryptedBallotsWithMerits.java index 25e65765f24..5f6708206c2 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/DecryptedBallotsWithMerits.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/DecryptedBallotsWithMerits.java @@ -15,15 +15,11 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.voteresult; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.governance.ballot.Ballot; -import bisq.core.dao.governance.ballot.BallotList; -import bisq.core.dao.governance.ballot.vote.Vote; import bisq.core.dao.governance.merit.MeritConsensus; -import bisq.core.dao.governance.merit.MeritList; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; import bisq.common.util.Utilities; @@ -45,7 +41,7 @@ @Immutable @Slf4j @Value -public class DecryptedBallotsWithMerits implements PersistablePayload, ImmutableDaoStateVo { +public class DecryptedBallotsWithMerits implements PersistablePayload, ImmutableDaoStateModel { private final byte[] hashOfBlindVoteList; private final String blindVoteTxId; private final String voteRevealTxId; diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/EvaluatedProposal.java b/core/src/main/java/bisq/core/dao/state/model/governance/EvaluatedProposal.java similarity index 91% rename from core/src/main/java/bisq/core/dao/governance/voteresult/EvaluatedProposal.java rename to core/src/main/java/bisq/core/dao/state/model/governance/EvaluatedProposal.java index 1b219dc4c8b..b91cf5d18b0 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/EvaluatedProposal.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/EvaluatedProposal.java @@ -15,10 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.voteresult; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.governance.proposal.Proposal; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; @@ -30,7 +29,7 @@ @Immutable @Value -public class EvaluatedProposal implements PersistablePayload, ImmutableDaoStateVo { +public class EvaluatedProposal implements PersistablePayload, ImmutableDaoStateModel { private final boolean isAccepted; private final ProposalVoteResult proposalVoteResult; @@ -38,7 +37,7 @@ public class EvaluatedProposal implements PersistablePayload, ImmutableDaoStateV private final long requiredQuorum; private final long requiredThreshold; - EvaluatedProposal(boolean isAccepted, ProposalVoteResult proposalVoteResult, long requiredQuorum, long requiredThreshold) { + public EvaluatedProposal(boolean isAccepted, ProposalVoteResult proposalVoteResult, long requiredQuorum, long requiredThreshold) { this.isAccepted = isAccepted; this.proposalVoteResult = proposalVoteResult; this.requiredQuorum = requiredQuorum; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposal.java b/core/src/main/java/bisq/core/dao/state/model/governance/GenericProposal.java similarity index 90% rename from core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposal.java rename to core/src/main/java/bisq/core/dao/state/model/governance/GenericProposal.java index a13215e1850..4af6afefaf2 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/generic/GenericProposal.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/GenericProposal.java @@ -15,13 +15,12 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.proposal.generic; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.ProposalType; -import bisq.core.dao.state.ImmutableDaoStateVo; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.ImmutableDaoStateModel; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.app.Version; @@ -39,10 +38,10 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class GenericProposal extends Proposal implements ImmutableDaoStateVo { +public final class GenericProposal extends Proposal implements ImmutableDaoStateModel { - GenericProposal(String name, - String link) { + public GenericProposal(String name, + String link) { this(name, link, Version.PROPOSAL, diff --git a/core/src/main/java/bisq/core/dao/state/governance/Issuance.java b/core/src/main/java/bisq/core/dao/state/model/governance/Issuance.java similarity index 96% rename from core/src/main/java/bisq/core/dao/state/governance/Issuance.java rename to core/src/main/java/bisq/core/dao/state/model/governance/Issuance.java index 86e3807e6fc..6fe359f63ec 100644 --- a/core/src/main/java/bisq/core/dao/state/governance/Issuance.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/Issuance.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.governance; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.ProtoUtil; import bisq.common.proto.network.NetworkPayload; @@ -38,7 +38,7 @@ */ @Immutable @Value -public class Issuance implements PersistablePayload, NetworkPayload, ImmutableDaoStateVo { +public class Issuance implements PersistablePayload, NetworkPayload, ImmutableDaoStateModel { private final String txId; // comp. request txId private final int chainHeight; // of issuance (first block of result phase) private final long amount; diff --git a/core/src/main/java/bisq/core/dao/state/governance/IssuanceType.java b/core/src/main/java/bisq/core/dao/state/model/governance/IssuanceType.java similarity index 82% rename from core/src/main/java/bisq/core/dao/state/governance/IssuanceType.java rename to core/src/main/java/bisq/core/dao/state/model/governance/IssuanceType.java index 7a58ecf4437..1d0b14224a6 100644 --- a/core/src/main/java/bisq/core/dao/state/governance/IssuanceType.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/IssuanceType.java @@ -15,14 +15,14 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.governance; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import javax.annotation.concurrent.Immutable; @Immutable -public enum IssuanceType implements ImmutableDaoStateVo { +public enum IssuanceType implements ImmutableDaoStateModel { UNDEFINED, COMPENSATION, REIMBURSEMENT diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/Merit.java b/core/src/main/java/bisq/core/dao/state/model/governance/Merit.java new file mode 100644 index 00000000000..5068c0d61b2 --- /dev/null +++ b/core/src/main/java/bisq/core/dao/state/model/governance/Merit.java @@ -0,0 +1,78 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.state.model.governance; + +import bisq.core.dao.governance.ConsensusCritical; +import bisq.core.dao.state.model.ImmutableDaoStateModel; + +import bisq.common.proto.network.NetworkPayload; +import bisq.common.proto.persistable.PersistablePayload; +import bisq.common.util.Utilities; + +import io.bisq.generated.protobuffer.PB; + +import com.google.protobuf.ByteString; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +import javax.annotation.concurrent.Immutable; + +@Immutable +@EqualsAndHashCode +public class Merit implements PersistablePayload, NetworkPayload, ConsensusCritical, ImmutableDaoStateModel { + @Getter + private final Issuance issuance; + @Getter + private final byte[] signature; + + public Merit(Issuance issuance, byte[] signature) { + this.issuance = issuance; + this.signature = signature; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public PB.Merit toProtoMessage() { + final PB.Merit.Builder builder = PB.Merit.newBuilder() + .setIssuance(issuance.toProtoMessage()) + .setSignature(ByteString.copyFrom(signature)); + return builder.build(); + } + + public static Merit fromProto(PB.Merit proto) { + return new Merit(Issuance.fromProto(proto.getIssuance()), + proto.getSignature().toByteArray()); + } + + public String getIssuanceTxId() { + return issuance.getTxId(); + } + + @Override + public String toString() { + return "Merit{" + + "\n issuance=" + issuance + + ",\n signature=" + Utilities.bytesAsHexString(signature) + + "\n}"; + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/merit/MeritList.java b/core/src/main/java/bisq/core/dao/state/model/governance/MeritList.java similarity index 94% rename from core/src/main/java/bisq/core/dao/governance/merit/MeritList.java rename to core/src/main/java/bisq/core/dao/state/model/governance/MeritList.java index debeba02a84..1ef0a26874a 100644 --- a/core/src/main/java/bisq/core/dao/governance/merit/MeritList.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/MeritList.java @@ -15,10 +15,10 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.merit; +package bisq.core.dao.state.model.governance; import bisq.core.dao.governance.ConsensusCritical; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistableList; @@ -38,7 +38,7 @@ // to PB bytes in the blindVote. @Immutable @EqualsAndHashCode(callSuper = true) -public class MeritList extends PersistableList implements ConsensusCritical, ImmutableDaoStateVo { +public class MeritList extends PersistableList implements ConsensusCritical, ImmutableDaoStateModel { public MeritList(List list) { super(list); diff --git a/core/src/main/java/bisq/core/dao/state/governance/ParamChange.java b/core/src/main/java/bisq/core/dao/state/model/governance/ParamChange.java similarity index 94% rename from core/src/main/java/bisq/core/dao/state/governance/ParamChange.java rename to core/src/main/java/bisq/core/dao/state/model/governance/ParamChange.java index 0a0d2670c7a..285a757ed4e 100644 --- a/core/src/main/java/bisq/core/dao/state/governance/ParamChange.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/ParamChange.java @@ -15,9 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.state.governance; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.state.ImmutableDaoStateVo; +import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.common.proto.persistable.PersistablePayload; @@ -32,7 +32,7 @@ */ @Immutable @Value -public class ParamChange implements PersistablePayload, ImmutableDaoStateVo { +public class ParamChange implements PersistablePayload, ImmutableDaoStateModel { // We use the enum name instead of the enum to be more flexible with changes at updates private final String paramName; private final String value; diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java b/core/src/main/java/bisq/core/dao/state/model/governance/Proposal.java similarity index 86% rename from core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java rename to core/src/main/java/bisq/core/dao/state/model/governance/Proposal.java index bcf1f2242e3..25baae5c3e7 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/Proposal.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/Proposal.java @@ -15,19 +15,13 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.proposal; +package bisq.core.dao.state.model.governance; import bisq.core.dao.governance.ConsensusCritical; -import bisq.core.dao.governance.proposal.compensation.CompensationProposal; -import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposal; -import bisq.core.dao.governance.proposal.generic.GenericProposal; -import bisq.core.dao.governance.proposal.param.ChangeParamProposal; -import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; -import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; -import bisq.core.dao.governance.proposal.role.RoleProposal; -import bisq.core.dao.state.ImmutableDaoStateVo; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.governance.param.Param; +import bisq.core.dao.governance.proposal.ProposalType; +import bisq.core.dao.state.model.ImmutableDaoStateModel; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.proto.ProtobufferRuntimeException; import bisq.common.proto.network.NetworkPayload; @@ -52,7 +46,7 @@ @Slf4j @Getter @EqualsAndHashCode -public abstract class Proposal implements PersistablePayload, NetworkPayload, ConsensusCritical, ImmutableDaoStateVo { +public abstract class Proposal implements PersistablePayload, NetworkPayload, ConsensusCritical, ImmutableDaoStateModel { protected final String name; protected final String link; protected final byte version; diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/ProposalVoteResult.java b/core/src/main/java/bisq/core/dao/state/model/governance/ProposalVoteResult.java new file mode 100644 index 00000000000..236be8d0fff --- /dev/null +++ b/core/src/main/java/bisq/core/dao/state/model/governance/ProposalVoteResult.java @@ -0,0 +1,119 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.state.model.governance; + +import bisq.core.dao.state.model.ImmutableDaoStateModel; + +import bisq.common.proto.persistable.PersistablePayload; + +import io.bisq.generated.protobuffer.PB; + +import lombok.Value; +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.concurrent.Immutable; + +import static com.google.common.base.Preconditions.checkArgument; + +@Immutable +@Value +@Slf4j +public class ProposalVoteResult implements PersistablePayload, ImmutableDaoStateModel { + private final Proposal proposal; + private final long stakeOfAcceptedVotes; + private final long stakeOfRejectedVotes; + private final int numAcceptedVotes; + private final int numRejectedVotes; + private final int numIgnoredVotes; + + public ProposalVoteResult(Proposal proposal, long stakeOfAcceptedVotes, long stakeOfRejectedVotes, + int numAcceptedVotes, int numRejectedVotes, int numIgnoredVotes) { + this.proposal = proposal; + this.stakeOfAcceptedVotes = stakeOfAcceptedVotes; + this.stakeOfRejectedVotes = stakeOfRejectedVotes; + this.numAcceptedVotes = numAcceptedVotes; + this.numRejectedVotes = numRejectedVotes; + this.numIgnoredVotes = numIgnoredVotes; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public PB.ProposalVoteResult toProtoMessage() { + PB.ProposalVoteResult.Builder builder = PB.ProposalVoteResult.newBuilder() + .setProposal(proposal.toProtoMessage()) + .setStakeOfAcceptedVotes(stakeOfAcceptedVotes) + .setStakeOfRejectedVotes(stakeOfRejectedVotes) + .setNumAcceptedVotes(numAcceptedVotes) + .setNumRejectedVotes(numRejectedVotes) + .setNumIgnoredVotes(numIgnoredVotes); + return builder.build(); + } + + public static ProposalVoteResult fromProto(PB.ProposalVoteResult proto) { + return new ProposalVoteResult(Proposal.fromProto(proto.getProposal()), + proto.getStakeOfAcceptedVotes(), + proto.getStakeOfRejectedVotes(), + proto.getNumAcceptedVotes(), + proto.getNumRejectedVotes(), + proto.getNumIgnoredVotes()); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + public int getNumActiveVotes() { + return numAcceptedVotes + numRejectedVotes; + } + + public long getQuorum() { + // Quorum is sum of all votes independent if accepted or rejected. + log.info("Quorum: proposalTxId: {}, totalStake: {}, stakeOfAcceptedVotes: {}, stakeOfRejectedVotes: {}", + proposal.getTxId(), getTotalStake(), stakeOfAcceptedVotes, stakeOfRejectedVotes); + return getTotalStake(); + } + + private long getTotalStake() { + return stakeOfAcceptedVotes + stakeOfRejectedVotes; + } + + public long getThreshold() { + checkArgument(stakeOfAcceptedVotes >= 0, "stakeOfAcceptedVotes must not be negative"); + checkArgument(stakeOfRejectedVotes >= 0, "stakeOfRejectedVotes must not be negative"); + if (stakeOfAcceptedVotes == 0) { + return 0; + } + return stakeOfAcceptedVotes * 10_000 / getTotalStake(); + } + + @Override + public String toString() { + return "ProposalVoteResult{" + + "\n proposal=" + proposal + + ",\n stakeOfAcceptedVotes=" + stakeOfAcceptedVotes + + ",\n stakeOfRejectedVotes=" + stakeOfRejectedVotes + + ",\n numAcceptedVotes=" + numAcceptedVotes + + ",\n numRejectedVotes=" + numRejectedVotes + + ",\n numIgnoredVotes=" + numIgnoredVotes + + "\n}"; + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposal.java b/core/src/main/java/bisq/core/dao/state/model/governance/ReimbursementProposal.java similarity index 91% rename from core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposal.java rename to core/src/main/java/bisq/core/dao/state/model/governance/ReimbursementProposal.java index f51611fcf0f..e2b3185c43c 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/ReimbursementProposal.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/ReimbursementProposal.java @@ -15,15 +15,14 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.proposal.reimbursement; +package bisq.core.dao.state.model.governance; import bisq.core.app.BisqEnvironment; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.IssuanceProposal; -import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.ProposalType; -import bisq.core.dao.state.ImmutableDaoStateVo; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.ImmutableDaoStateModel; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.app.Version; @@ -45,14 +44,14 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class ReimbursementProposal extends Proposal implements IssuanceProposal, ImmutableDaoStateVo { +public final class ReimbursementProposal extends Proposal implements IssuanceProposal, ImmutableDaoStateModel { private final long requestedBsq; private final String bsqAddress; - ReimbursementProposal(String name, - String link, - Coin requestedBsq, - String bsqAddress) { + public ReimbursementProposal(String name, + String link, + Coin requestedBsq, + String bsqAddress) { this(name, link, bsqAddress, diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposal.java b/core/src/main/java/bisq/core/dao/state/model/governance/RemoveAssetProposal.java similarity index 90% rename from core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposal.java rename to core/src/main/java/bisq/core/dao/state/model/governance/RemoveAssetProposal.java index ca513de20e7..47d32963265 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposal.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/RemoveAssetProposal.java @@ -15,13 +15,12 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.proposal.removeAsset; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.ProposalType; -import bisq.core.dao.state.ImmutableDaoStateVo; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.ImmutableDaoStateModel; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.app.Version; @@ -39,12 +38,12 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class RemoveAssetProposal extends Proposal implements ImmutableDaoStateVo { +public final class RemoveAssetProposal extends Proposal implements ImmutableDaoStateModel { private final String tickerSymbol; - RemoveAssetProposal(String name, - String link, - String tickerSymbol) { + public RemoveAssetProposal(String name, + String link, + String tickerSymbol) { this(name, link, tickerSymbol, diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/Role.java b/core/src/main/java/bisq/core/dao/state/model/governance/Role.java new file mode 100644 index 00000000000..567e0a269b2 --- /dev/null +++ b/core/src/main/java/bisq/core/dao/state/model/governance/Role.java @@ -0,0 +1,149 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.state.model.governance; + +import bisq.core.dao.governance.bonding.bond.BondWithHash; +import bisq.core.dao.state.model.ImmutableDaoStateModel; +import bisq.core.locale.Res; + +import bisq.common.crypto.Hash; +import bisq.common.proto.ProtoUtil; +import bisq.common.proto.network.NetworkPayload; +import bisq.common.proto.persistable.PersistablePayload; + +import io.bisq.generated.protobuffer.PB; + +import java.math.BigInteger; + +import java.util.Objects; +import java.util.UUID; + +import lombok.Value; +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.concurrent.Immutable; + +/** + * Immutable data for a role. Is stored in the DaoState as part of the evaluated proposals. + */ +@Immutable +@Slf4j +@Value +public final class Role implements PersistablePayload, NetworkPayload, BondWithHash, ImmutableDaoStateModel { + private final String uid; + private final String name; + private final String link; + private final BondedRoleType bondedRoleType; + + /** + * @param name Full name or nickname + * @param link Github account or forum account of user + * @param bondedRoleType BondedRoleType + */ + public Role(String name, + String link, + BondedRoleType bondedRoleType) { + this(UUID.randomUUID().toString(), + name, + link, + bondedRoleType + ); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + public Role(String uid, + String name, + String link, + BondedRoleType bondedRoleType) { + this.uid = uid; + this.name = name; + this.link = link; + this.bondedRoleType = bondedRoleType; + } + + @Override + public PB.Role toProtoMessage() { + PB.Role.Builder builder = PB.Role.newBuilder() + .setUid(uid) + .setName(name) + .setLink(link) + .setBondedRoleType(bondedRoleType.name()); + return builder.build(); + } + + public static Role fromProto(PB.Role proto) { + return new Role(proto.getUid(), + proto.getName(), + proto.getLink(), + ProtoUtil.enumFromProto(BondedRoleType.class, proto.getBondedRoleType())); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // BondWithHash implementation + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public byte[] getHash() { + // We use only the immutable data as input for hash + byte[] bytes = BigInteger.valueOf(hashCode()).toByteArray(); + return Hash.getSha256Ripemd160hash(bytes); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + public String getDisplayString() { + return Res.get("dao.bond.bondedRoleType." + bondedRoleType.name()) + ": " + name; + } + + // We use only the immutable data + // bondedRoleType must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Role that = (Role) o; + return Objects.equals(uid, that.uid) && + Objects.equals(name, that.name) && + Objects.equals(link, that.link) && + bondedRoleType.name().equals(that.bondedRoleType.name()); + } + + @Override + public int hashCode() { + return Objects.hash(uid, name, link, bondedRoleType.name()); + } + + @Override + public String toString() { + return "Role{" + + "\n uid='" + uid + '\'' + + ",\n name='" + name + '\'' + + ",\n link='" + link + '\'' + + ",\n bondedRoleType=" + bondedRoleType + + "\n}"; + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposal.java b/core/src/main/java/bisq/core/dao/state/model/governance/RoleProposal.java similarity index 91% rename from core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposal.java rename to core/src/main/java/bisq/core/dao/state/model/governance/RoleProposal.java index ef801baca64..7bf90de6cce 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/role/RoleProposal.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/RoleProposal.java @@ -15,14 +15,12 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.proposal.role; +package bisq.core.dao.state.model.governance; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.ProposalType; -import bisq.core.dao.governance.role.Role; -import bisq.core.dao.state.ImmutableDaoStateVo; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.ImmutableDaoStateModel; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.app.Version; @@ -40,10 +38,10 @@ @Slf4j @EqualsAndHashCode(callSuper = true) @Value -public final class RoleProposal extends Proposal implements ImmutableDaoStateVo { +public final class RoleProposal extends Proposal implements ImmutableDaoStateModel { private final Role role; - RoleProposal(Role role) { + public RoleProposal(Role role) { this(role.getName(), role.getLink(), role, diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/Vote.java b/core/src/main/java/bisq/core/dao/state/model/governance/Vote.java new file mode 100644 index 00000000000..eff5f0a1ced --- /dev/null +++ b/core/src/main/java/bisq/core/dao/state/model/governance/Vote.java @@ -0,0 +1,57 @@ +/* + * This file is part of Bisq. + * + * bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with bisq. If not, see . + */ + +package bisq.core.dao.state.model.governance; + +import bisq.core.dao.governance.ConsensusCritical; +import bisq.core.dao.state.model.ImmutableDaoStateModel; + +import bisq.common.proto.network.NetworkPayload; +import bisq.common.proto.persistable.PersistablePayload; + +import io.bisq.generated.protobuffer.PB; + +import com.google.protobuf.Message; + +import lombok.Value; + +import javax.annotation.concurrent.Immutable; + +@Immutable +@Value +public class Vote implements PersistablePayload, NetworkPayload, ConsensusCritical, ImmutableDaoStateModel { + private boolean accepted; + + public Vote(boolean accepted) { + this.accepted = accepted; + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public Message toProtoMessage() { + return PB.Vote.newBuilder() + .setAccepted(accepted) + .build(); + } + + public static Vote fromProto(PB.Vote proto) { + return new Vote(proto.getAccepted()); + } +} diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/package-info.java b/core/src/main/java/bisq/core/dao/state/model/governance/package-info.java new file mode 100644 index 00000000000..171cf8dc030 --- /dev/null +++ b/core/src/main/java/bisq/core/dao/state/model/governance/package-info.java @@ -0,0 +1,22 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +/** + * Contains all governance specific data used in the daoState. + */ + +package bisq.core.dao.state.model.governance; diff --git a/core/src/main/java/bisq/core/dao/state/model/package-info.java b/core/src/main/java/bisq/core/dao/state/model/package-info.java new file mode 100644 index 00000000000..7d344b2a1ce --- /dev/null +++ b/core/src/main/java/bisq/core/dao/state/model/package-info.java @@ -0,0 +1,25 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +/** + * This package contains all immutable model classes used in the daoState. DaoState is persisted and it can be seen as + * the immutable ledger of the Bisq DAO. + * We want to make very clear which data are contained here that's we we break up grouping by domains and moved all + * model classes here. + */ + +package bisq.core.dao.state.model; diff --git a/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java b/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java index bc930b806d4..202ebab2797 100644 --- a/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java +++ b/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java @@ -21,15 +21,15 @@ import bisq.core.btc.model.AddressEntryList; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.governance.asset.RemovedAssetsList; -import bisq.core.dao.governance.ballot.BallotList; import bisq.core.dao.governance.blindvote.MyBlindVoteList; import bisq.core.dao.governance.blindvote.storage.BlindVoteStore; -import bisq.core.dao.governance.merit.MeritList; import bisq.core.dao.governance.myvote.MyVoteList; import bisq.core.dao.governance.proposal.MyProposalList; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStore; import bisq.core.dao.governance.proposal.storage.temp.TempProposalStore; import bisq.core.dao.state.DaoStateStore; +import bisq.core.dao.state.model.governance.BallotList; +import bisq.core.dao.state.model.governance.MeritList; import bisq.core.payment.AccountAgeWitnessStore; import bisq.core.payment.PaymentAccountList; import bisq.core.proto.CoreProtoResolver; diff --git a/core/src/main/java/bisq/core/provider/fee/FeeService.java b/core/src/main/java/bisq/core/provider/fee/FeeService.java index 9320ba1a209..979796a967b 100644 --- a/core/src/main/java/bisq/core/provider/fee/FeeService.java +++ b/core/src/main/java/bisq/core/provider/fee/FeeService.java @@ -18,9 +18,9 @@ package bisq.core.provider.fee; import bisq.core.app.BisqEnvironment; -import bisq.core.dao.period.PeriodService; +import bisq.core.dao.governance.param.Param; +import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.governance.Param; import bisq.common.UserThread; import bisq.common.handlers.FaultHandler; diff --git a/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java b/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java index 7c118311589..d6672e86c12 100644 --- a/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java +++ b/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java @@ -20,10 +20,10 @@ import bisq.core.arbitration.DisputeManager; import bisq.core.btc.model.AddressEntryList; import bisq.core.dao.DaoOptionKeys; -import bisq.core.dao.bonding.bond.BondedReputationService; import bisq.core.dao.governance.asset.AssetService; import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; +import bisq.core.dao.governance.bonding.bond.BondedReputationService; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.proposal.MyProposalListService; import bisq.core.offer.OpenOfferManager; diff --git a/core/src/main/java/bisq/core/util/BsqFormatter.java b/core/src/main/java/bisq/core/util/BsqFormatter.java index ae6da2aeda4..7c9923150d9 100644 --- a/core/src/main/java/bisq/core/util/BsqFormatter.java +++ b/core/src/main/java/bisq/core/util/BsqFormatter.java @@ -19,7 +19,7 @@ import bisq.core.app.BisqEnvironment; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.governance.param.Param; import bisq.core.locale.Res; import bisq.core.provider.price.MarketPrice; import bisq.core.util.validation.BtcAddressValidator; diff --git a/core/src/test/java/bisq/core/dao/node/full/BlockParserTest.java b/core/src/test/java/bisq/core/dao/node/full/BlockParserTest.java index 1483cd7aaaf..502d7c35f75 100644 --- a/core/src/test/java/bisq/core/dao/node/full/BlockParserTest.java +++ b/core/src/test/java/bisq/core/dao/node/full/BlockParserTest.java @@ -21,10 +21,8 @@ import bisq.core.dao.node.parser.TxParser; import bisq.core.dao.node.parser.exceptions.BlockNotConnectingException; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.RawTx; -import bisq.core.dao.state.blockchain.RawTxOutput; -import bisq.core.dao.state.blockchain.TxInput; -import bisq.core.dao.state.blockchain.TxOutputKey; +import bisq.core.dao.state.model.blockchain.TxInput; +import bisq.core.dao.state.model.blockchain.TxOutputKey; import bisq.common.proto.persistable.PersistenceProtoResolver; diff --git a/core/src/test/java/bisq/core/dao/node/parser/GenesisTxParserTest.java b/core/src/test/java/bisq/core/dao/node/parser/GenesisTxParserTest.java index 1d6a99e52f6..62a591f3abe 100644 --- a/core/src/test/java/bisq/core/dao/node/parser/GenesisTxParserTest.java +++ b/core/src/test/java/bisq/core/dao/node/parser/GenesisTxParserTest.java @@ -17,13 +17,12 @@ package bisq.core.dao.node.parser; +import bisq.core.dao.node.full.RawTx; +import bisq.core.dao.node.full.RawTxOutput; import bisq.core.dao.node.parser.exceptions.InvalidGenesisTxException; -import bisq.core.dao.state.blockchain.RawTx; -import bisq.core.dao.state.blockchain.RawTxOutput; -import bisq.core.dao.state.blockchain.TempTx; -import bisq.core.dao.state.blockchain.TxInput; -import bisq.core.dao.state.blockchain.TxOutputType; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.state.model.blockchain.TxInput; +import bisq.core.dao.state.model.blockchain.TxOutputType; +import bisq.core.dao.state.model.blockchain.TxType; import org.bitcoinj.core.Coin; diff --git a/core/src/test/java/bisq/core/dao/state/DaoStateServiceTest.java b/core/src/test/java/bisq/core/dao/state/DaoStateServiceTest.java index f96a9c312ca..79c180652f7 100644 --- a/core/src/test/java/bisq/core/dao/state/DaoStateServiceTest.java +++ b/core/src/test/java/bisq/core/dao/state/DaoStateServiceTest.java @@ -17,7 +17,8 @@ package bisq.core.dao.state; -import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.model.DaoState; +import bisq.core.dao.state.model.blockchain.Block; import bisq.core.util.BsqFormatter; import org.junit.Assert; diff --git a/desktop/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java b/desktop/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java index d74283c2eee..e3794c5f460 100644 --- a/desktop/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java +++ b/desktop/src/main/java/bisq/desktop/components/SeparatedPhaseBars.java @@ -17,7 +17,7 @@ package bisq.desktop.components; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.governance.DaoPhase; import bisq.core.locale.Res; import javafx.scene.control.Label; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java index a79d2a31fab..7f4edd829f7 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java @@ -26,12 +26,12 @@ import bisq.core.btc.setup.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.bonding.bond.BondWithHash; -import bisq.core.dao.bonding.bond.BondedReputation; -import bisq.core.dao.bonding.lockup.LockupType; -import bisq.core.dao.governance.role.Role; -import bisq.core.dao.governance.role.BondedRoleType; -import bisq.core.dao.state.blockchain.TxOutput; +import bisq.core.dao.governance.bonding.bond.BondWithHash; +import bisq.core.dao.governance.bonding.bond.BondedReputation; +import bisq.core.dao.governance.bonding.lockup.LockupType; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.governance.BondedRoleType; +import bisq.core.dao.state.model.governance.Role; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index 1780ca9726f..fe4122b1d22 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -30,10 +30,10 @@ import bisq.core.btc.listeners.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.bonding.BondingConsensus; -import bisq.core.dao.bonding.lockup.LockupType; -import bisq.core.dao.governance.role.BondedRole; -import bisq.core.dao.governance.role.Role; +import bisq.core.dao.governance.bond.BondedRole; +import bisq.core.dao.governance.bonding.BondingConsensus; +import bisq.core.dao.governance.bonding.lockup.LockupType; +import bisq.core.dao.state.model.governance.Role; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; import bisq.core.util.validation.IntegerValidator; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java index cef95537a88..c0bab71276b 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java @@ -20,7 +20,7 @@ import bisq.desktop.main.overlays.Overlay; import bisq.desktop.util.FormBuilder; -import bisq.core.dao.governance.role.BondedRoleType; +import bisq.core.dao.state.model.governance.BondedRoleType; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java index 5f21eb0f6f0..e8aa1504c83 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java @@ -20,10 +20,10 @@ import bisq.desktop.components.AutoTooltipButton; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.role.BondedRole; -import bisq.core.dao.governance.role.Role; +import bisq.core.dao.governance.bond.BondedRole; import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.Role; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java index a13fb7676c0..895ca539502 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java @@ -28,9 +28,9 @@ import bisq.desktop.util.GUIUtil; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.role.BondedRoleType; import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.BondedRoleType; import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java index c619f371565..b2c94d321d1 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java @@ -25,14 +25,14 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.bonding.BondingConsensus; -import bisq.core.dao.bonding.lockup.LockupType; -import bisq.core.dao.governance.role.BondedRole; -import bisq.core.dao.governance.role.BondedRoleType; -import bisq.core.dao.governance.role.BondedRolesService; -import bisq.core.dao.state.blockchain.BaseTxOutput; -import bisq.core.dao.state.blockchain.TxOutput; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.governance.bond.BondedRole; +import bisq.core.dao.governance.bond.BondedRolesService; +import bisq.core.dao.governance.bonding.BondingConsensus; +import bisq.core.dao.governance.bonding.lockup.LockupType; +import bisq.core.dao.state.model.blockchain.BaseTxOutput; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxType; +import bisq.core.dao.state.model.governance.BondedRoleType; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index f343e4bd59c..93c6287ca84 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -30,10 +30,10 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.role.BondedRolesService; +import bisq.core.dao.governance.bond.BondedRolesService; import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/GovernanceView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/GovernanceView.java index ef0d2b6553c..e70a4e83862 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/GovernanceView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/GovernanceView.java @@ -33,7 +33,7 @@ import bisq.desktop.main.dao.governance.result.VoteResultView; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.governance.DaoPhase; import bisq.core.locale.Res; import javax.inject.Inject; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/PhasesView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/PhasesView.java index b68e9d82abc..60a7565dd49 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/PhasesView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/PhasesView.java @@ -22,8 +22,8 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.DaoPhase; import bisq.core.locale.Res; import javax.inject.Inject; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java index 5cb3e160c89..8ca4599aac1 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java @@ -27,25 +27,25 @@ import bisq.core.btc.BaseCurrencyNetwork; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.ballot.Ballot; -import bisq.core.dao.governance.ballot.vote.Vote; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.ProposalType; -import bisq.core.dao.governance.proposal.compensation.CompensationProposal; -import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposal; -import bisq.core.dao.governance.proposal.generic.GenericProposal; import bisq.core.dao.governance.proposal.param.ChangeParamInputValidator; -import bisq.core.dao.governance.proposal.param.ChangeParamProposal; import bisq.core.dao.governance.proposal.param.ChangeParamValidator; -import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; -import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; -import bisq.core.dao.governance.proposal.role.RoleProposal; -import bisq.core.dao.governance.role.BondedRoleType; -import bisq.core.dao.governance.role.Role; -import bisq.core.dao.governance.voteresult.EvaluatedProposal; -import bisq.core.dao.governance.voteresult.ProposalVoteResult; -import bisq.core.dao.state.blockchain.Tx; -import bisq.core.dao.state.governance.Param; +import bisq.core.dao.state.model.blockchain.Tx; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.BondedRoleType; +import bisq.core.dao.state.model.governance.ChangeParamProposal; +import bisq.core.dao.state.model.governance.CompensationProposal; +import bisq.core.dao.state.model.governance.ConfiscateBondProposal; +import bisq.core.dao.state.model.governance.EvaluatedProposal; +import bisq.core.dao.state.model.governance.GenericProposal; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.ProposalVoteResult; +import bisq.core.dao.state.model.governance.ReimbursementProposal; +import bisq.core.dao.state.model.governance.RemoveAssetProposal; +import bisq.core.dao.state.model.governance.Role; +import bisq.core.dao.state.model.governance.RoleProposal; +import bisq.core.dao.state.model.governance.Vote; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/dashboard/GovernanceDashboardView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/dashboard/GovernanceDashboardView.java index 68687376bf3..b9c3f8a32a7 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/dashboard/GovernanceDashboardView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/dashboard/GovernanceDashboardView.java @@ -25,8 +25,8 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.DaoPhase; import bisq.core.locale.Res; import bisq.core.util.BSFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java index e5743357ea7..25372fffdbe 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java @@ -32,16 +32,16 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.ProposalType; import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.governance.proposal.param.ChangeParamValidator; -import bisq.core.dao.governance.role.Role; import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.governance.Param; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.DaoPhase; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.Role; import bisq.core.locale.Res; import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsListItem.java index 349be97188c..39bb6e4475c 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsListItem.java @@ -20,10 +20,10 @@ import bisq.desktop.util.FormBuilder; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.ballot.Ballot; -import bisq.core.dao.governance.ballot.vote.Vote; -import bisq.core.dao.governance.proposal.Proposal; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.DaoPhase; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.Vote; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java index b0d437756e6..0936d322b33 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java @@ -39,16 +39,16 @@ import bisq.core.btc.listeners.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.ballot.Ballot; -import bisq.core.dao.governance.ballot.vote.Vote; import bisq.core.dao.governance.myvote.MyVote; -import bisq.core.dao.governance.proposal.Proposal; import bisq.core.dao.governance.proposal.param.ChangeParamValidator; -import bisq.core.dao.governance.voteresult.EvaluatedProposal; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.period.DaoPhase; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.DaoPhase; +import bisq.core.dao.state.model.governance.EvaluatedProposal; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.Vote; import bisq.core.locale.Res; import bisq.core.util.BSFormatter; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/CycleListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/CycleListItem.java index e30bab448e2..31c117f6495 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/CycleListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/CycleListItem.java @@ -18,8 +18,8 @@ package bisq.desktop.main.dao.governance.result; import bisq.core.dao.governance.proposal.IssuanceProposal; -import bisq.core.dao.governance.voteresult.EvaluatedProposal; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.EvaluatedProposal; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java index 427a3c95b65..c70316e2646 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ProposalListItem.java @@ -19,17 +19,17 @@ import bisq.desktop.util.FormBuilder; -import bisq.core.dao.governance.ballot.Ballot; -import bisq.core.dao.governance.ballot.vote.Vote; -import bisq.core.dao.governance.proposal.Proposal; -import bisq.core.dao.governance.proposal.compensation.CompensationProposal; -import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposal; -import bisq.core.dao.governance.proposal.param.ChangeParamProposal; -import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposal; -import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposal; -import bisq.core.dao.governance.proposal.role.RoleProposal; -import bisq.core.dao.governance.role.Role; -import bisq.core.dao.governance.voteresult.EvaluatedProposal; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.ChangeParamProposal; +import bisq.core.dao.state.model.governance.CompensationProposal; +import bisq.core.dao.state.model.governance.ConfiscateBondProposal; +import bisq.core.dao.state.model.governance.EvaluatedProposal; +import bisq.core.dao.state.model.governance.Proposal; +import bisq.core.dao.state.model.governance.ReimbursementProposal; +import bisq.core.dao.state.model.governance.RemoveAssetProposal; +import bisq.core.dao.state.model.governance.Role; +import bisq.core.dao.state.model.governance.RoleProposal; +import bisq.core.dao.state.model.governance.Vote; import bisq.core.locale.CurrencyUtil; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ResultsOfCycle.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ResultsOfCycle.java index 77d971d0271..e9c9df38533 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ResultsOfCycle.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/ResultsOfCycle.java @@ -17,12 +17,12 @@ package bisq.desktop.main.dao.governance.result; -import bisq.core.dao.governance.proposal.Proposal; -import bisq.core.dao.governance.voteresult.DecryptedBallotsWithMerits; -import bisq.core.dao.governance.voteresult.EvaluatedProposal; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.period.Cycle; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.Cycle; +import bisq.core.dao.state.model.governance.DecryptedBallotsWithMerits; +import bisq.core.dao.state.model.governance.EvaluatedProposal; +import bisq.core.dao.state.model.governance.Proposal; import java.util.List; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteListItem.java index 73dd8b490ac..924cf302078 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteListItem.java @@ -17,10 +17,10 @@ package bisq.desktop.main.dao.governance.result; -import bisq.core.dao.governance.ballot.Ballot; -import bisq.core.dao.governance.proposal.Proposal; -import bisq.core.dao.governance.voteresult.DecryptedBallotsWithMerits; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.DecryptedBallotsWithMerits; +import bisq.core.dao.state.model.governance.Proposal; import bisq.core.util.BsqFormatter; import bisq.common.util.Tuple2; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java index 507a9680d3c..8d72e11e27a 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/result/VoteResultView.java @@ -30,16 +30,16 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.ballot.Ballot; -import bisq.core.dao.governance.proposal.Proposal; +import bisq.core.dao.governance.period.CycleService; import bisq.core.dao.governance.proposal.ProposalService; -import bisq.core.dao.governance.voteresult.DecryptedBallotsWithMerits; -import bisq.core.dao.governance.voteresult.EvaluatedProposal; import bisq.core.dao.governance.voteresult.VoteResultService; -import bisq.core.dao.period.CycleService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.blockchain.Block; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.Ballot; +import bisq.core.dao.state.model.governance.DecryptedBallotsWithMerits; +import bisq.core.dao.state.model.governance.EvaluatedProposal; +import bisq.core.dao.state.model.governance.Proposal; import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java b/desktop/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java index 19717b280c4..da2192b74a0 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/wallet/dashboard/BsqDashboardView.java @@ -26,8 +26,8 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.governance.IssuanceType; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.governance.IssuanceType; import bisq.core.locale.Res; import bisq.core.monetary.Price; import bisq.core.provider.price.PriceFeedService; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java index 9c7b4f95351..ffc33774fc2 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxListItem.java @@ -23,7 +23,7 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java b/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java index e19b7c8c296..5da8bd90232 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/wallet/tx/BsqTxView.java @@ -33,9 +33,9 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.blockchain.Block; -import bisq.core.dao.state.blockchain.TxType; -import bisq.core.dao.state.governance.IssuanceType; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.TxType; +import bisq.core.dao.state.model.governance.IssuanceType; import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java index 44270ef0cb3..bb61ac5a116 100644 --- a/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/funds/transactions/TransactionsListItem.java @@ -26,7 +26,7 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.WalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.state.blockchain.TxType; +import bisq.core.dao.state.model.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.offer.Offer; import bisq.core.offer.OpenOffer; From f55fde05b610db4c84e51b5eb1d4e54ab68a2b32 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Thu, 1 Nov 2018 17:12:39 -0500 Subject: [PATCH 13/27] Moving classes That was a big commit with restructuring the packages and classes. Motivation was to isolate the daoState value objects so it is more clear which data are help in the daoState. As it was hard to keep an overview and easy to add mutable data I think that makes it more safe overall. I am aware that the downside to take out domain models from the domain packages is not so nice. Also moved blockchain models to parser and full node packages. --- .../core/dao/governance/ballot/Ballot.java | 117 ----------------- .../core/dao/governance/ballot/vote/Vote.java | 57 --------- .../bisq/core/dao/governance/merit/Merit.java | 79 ------------ .../voteresult/ProposalVoteResult.java | 120 ------------------ 4 files changed, 373 deletions(-) delete mode 100644 core/src/main/java/bisq/core/dao/governance/ballot/Ballot.java delete mode 100644 core/src/main/java/bisq/core/dao/governance/ballot/vote/Vote.java delete mode 100644 core/src/main/java/bisq/core/dao/governance/merit/Merit.java delete mode 100644 core/src/main/java/bisq/core/dao/governance/voteresult/ProposalVoteResult.java diff --git a/core/src/main/java/bisq/core/dao/governance/ballot/Ballot.java b/core/src/main/java/bisq/core/dao/governance/ballot/Ballot.java deleted file mode 100644 index 68752c59cde..00000000000 --- a/core/src/main/java/bisq/core/dao/governance/ballot/Ballot.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of Bisq. - * - * bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with bisq. If not, see . - */ - -package bisq.core.dao.governance.ballot; - -import bisq.core.dao.governance.ConsensusCritical; -import bisq.core.dao.governance.ballot.vote.Vote; -import bisq.core.dao.governance.proposal.Proposal; -import bisq.core.dao.governance.proposal.ProposalType; -import bisq.core.dao.state.ImmutableDaoStateVo; - -import bisq.common.proto.persistable.PersistablePayload; - -import io.bisq.generated.protobuffer.PB; - -import java.util.Optional; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -/** - * Base class for all ballots like compensation request, generic request, remove asset ballots and - * change param ballots. - * It contains the Proposal and the Vote. If a Proposal is ignored for voting the vote object is null. - * - * One proposal has about 278 bytes - */ -@Immutable -@Slf4j -@Getter -@EqualsAndHashCode -public final class Ballot implements PersistablePayload, ConsensusCritical, ImmutableDaoStateVo { - protected final Proposal proposal; - - @Nullable - protected Vote vote; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor - /////////////////////////////////////////////////////////////////////////////////////////// - - public Ballot(Proposal proposal) { - this(proposal, null); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER - /////////////////////////////////////////////////////////////////////////////////////////// - - public Ballot(Proposal proposal, - @Nullable Vote vote) { - this.proposal = proposal; - this.vote = vote; - } - - @Override - public PB.Ballot toProtoMessage() { - final PB.Ballot.Builder builder = PB.Ballot.newBuilder() - .setProposal(proposal.getProposalBuilder()); - Optional.ofNullable(vote).ifPresent(e -> builder.setVote((PB.Vote) e.toProtoMessage())); - return builder.build(); - } - - public static Ballot fromProto(PB.Ballot proto) { - return new Ballot(Proposal.fromProto(proto.getProposal()), - proto.hasVote() ? Vote.fromProto(proto.getVote()) : null); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // API - /////////////////////////////////////////////////////////////////////////////////////////// - - public void setVote(@Nullable Vote vote) { - this.vote = vote; - } - - public ProposalType getType() { - return getProposal().getType(); - } - - public String getTxId() { - return proposal.getTxId(); - } - - public Optional getVoteAsOptional() { - return Optional.ofNullable(vote); - } - - @Override - public String toString() { - return "Ballot{" + - "\n proposal=" + proposal + - ",\n vote=" + vote + - "\n}"; - } -} diff --git a/core/src/main/java/bisq/core/dao/governance/ballot/vote/Vote.java b/core/src/main/java/bisq/core/dao/governance/ballot/vote/Vote.java deleted file mode 100644 index 8ee2f96c7c2..00000000000 --- a/core/src/main/java/bisq/core/dao/governance/ballot/vote/Vote.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Bisq. - * - * bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with bisq. If not, see . - */ - -package bisq.core.dao.governance.ballot.vote; - -import bisq.core.dao.governance.ConsensusCritical; -import bisq.core.dao.state.ImmutableDaoStateVo; - -import bisq.common.proto.network.NetworkPayload; -import bisq.common.proto.persistable.PersistablePayload; - -import io.bisq.generated.protobuffer.PB; - -import com.google.protobuf.Message; - -import lombok.Value; - -import javax.annotation.concurrent.Immutable; - -@Immutable -@Value -public class Vote implements PersistablePayload, NetworkPayload, ConsensusCritical, ImmutableDaoStateVo { - private boolean accepted; - - public Vote(boolean accepted) { - this.accepted = accepted; - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public Message toProtoMessage() { - return PB.Vote.newBuilder() - .setAccepted(accepted) - .build(); - } - - public static Vote fromProto(PB.Vote proto) { - return new Vote(proto.getAccepted()); - } -} diff --git a/core/src/main/java/bisq/core/dao/governance/merit/Merit.java b/core/src/main/java/bisq/core/dao/governance/merit/Merit.java deleted file mode 100644 index 20a53c13a39..00000000000 --- a/core/src/main/java/bisq/core/dao/governance/merit/Merit.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.core.dao.governance.merit; - -import bisq.core.dao.governance.ConsensusCritical; -import bisq.core.dao.state.ImmutableDaoStateVo; -import bisq.core.dao.state.governance.Issuance; - -import bisq.common.proto.network.NetworkPayload; -import bisq.common.proto.persistable.PersistablePayload; -import bisq.common.util.Utilities; - -import io.bisq.generated.protobuffer.PB; - -import com.google.protobuf.ByteString; - -import lombok.EqualsAndHashCode; -import lombok.Getter; - -import javax.annotation.concurrent.Immutable; - -@Immutable -@EqualsAndHashCode -public class Merit implements PersistablePayload, NetworkPayload, ConsensusCritical, ImmutableDaoStateVo { - @Getter - private final Issuance issuance; - @Getter - private final byte[] signature; - - public Merit(Issuance issuance, byte[] signature) { - this.issuance = issuance; - this.signature = signature; - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public PB.Merit toProtoMessage() { - final PB.Merit.Builder builder = PB.Merit.newBuilder() - .setIssuance(issuance.toProtoMessage()) - .setSignature(ByteString.copyFrom(signature)); - return builder.build(); - } - - public static Merit fromProto(PB.Merit proto) { - return new Merit(Issuance.fromProto(proto.getIssuance()), - proto.getSignature().toByteArray()); - } - - public String getIssuanceTxId() { - return issuance.getTxId(); - } - - @Override - public String toString() { - return "Merit{" + - "\n issuance=" + issuance + - ",\n signature=" + Utilities.bytesAsHexString(signature) + - "\n}"; - } -} diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/ProposalVoteResult.java b/core/src/main/java/bisq/core/dao/governance/voteresult/ProposalVoteResult.java deleted file mode 100644 index 2ff4c372beb..00000000000 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/ProposalVoteResult.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.core.dao.governance.voteresult; - -import bisq.core.dao.governance.proposal.Proposal; -import bisq.core.dao.state.ImmutableDaoStateVo; - -import bisq.common.proto.persistable.PersistablePayload; - -import io.bisq.generated.protobuffer.PB; - -import lombok.Value; -import lombok.extern.slf4j.Slf4j; - -import javax.annotation.concurrent.Immutable; - -import static com.google.common.base.Preconditions.checkArgument; - -@Immutable -@Value -@Slf4j -public class ProposalVoteResult implements PersistablePayload, ImmutableDaoStateVo { - private final Proposal proposal; - private final long stakeOfAcceptedVotes; - private final long stakeOfRejectedVotes; - private final int numAcceptedVotes; - private final int numRejectedVotes; - private final int numIgnoredVotes; - - ProposalVoteResult(Proposal proposal, long stakeOfAcceptedVotes, long stakeOfRejectedVotes, - int numAcceptedVotes, int numRejectedVotes, int numIgnoredVotes) { - this.proposal = proposal; - this.stakeOfAcceptedVotes = stakeOfAcceptedVotes; - this.stakeOfRejectedVotes = stakeOfRejectedVotes; - this.numAcceptedVotes = numAcceptedVotes; - this.numRejectedVotes = numRejectedVotes; - this.numIgnoredVotes = numIgnoredVotes; - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public PB.ProposalVoteResult toProtoMessage() { - PB.ProposalVoteResult.Builder builder = PB.ProposalVoteResult.newBuilder() - .setProposal(proposal.toProtoMessage()) - .setStakeOfAcceptedVotes(stakeOfAcceptedVotes) - .setStakeOfRejectedVotes(stakeOfRejectedVotes) - .setNumAcceptedVotes(numAcceptedVotes) - .setNumRejectedVotes(numRejectedVotes) - .setNumIgnoredVotes(numIgnoredVotes); - return builder.build(); - } - - public static ProposalVoteResult fromProto(PB.ProposalVoteResult proto) { - return new ProposalVoteResult(Proposal.fromProto(proto.getProposal()), - proto.getStakeOfAcceptedVotes(), - proto.getStakeOfRejectedVotes(), - proto.getNumAcceptedVotes(), - proto.getNumRejectedVotes(), - proto.getNumIgnoredVotes()); - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // API - /////////////////////////////////////////////////////////////////////////////////////////// - - public int getNumActiveVotes() { - return numAcceptedVotes + numRejectedVotes; - } - - public long getQuorum() { - // Quorum is sum of all votes independent if accepted or rejected. - log.info("Quorum: proposalTxId: {}, totalStake: {}, stakeOfAcceptedVotes: {}, stakeOfRejectedVotes: {}", - proposal.getTxId(), getTotalStake(), stakeOfAcceptedVotes, stakeOfRejectedVotes); - return getTotalStake(); - } - - private long getTotalStake() { - return stakeOfAcceptedVotes + stakeOfRejectedVotes; - } - - public long getThreshold() { - checkArgument(stakeOfAcceptedVotes >= 0, "stakeOfAcceptedVotes must not be negative"); - checkArgument(stakeOfRejectedVotes >= 0, "stakeOfRejectedVotes must not be negative"); - if (stakeOfAcceptedVotes == 0) { - return 0; - } - return stakeOfAcceptedVotes * 10_000 / getTotalStake(); - } - - @Override - public String toString() { - return "ProposalVoteResult{" + - "\n proposal=" + proposal + - ",\n stakeOfAcceptedVotes=" + stakeOfAcceptedVotes + - ",\n stakeOfRejectedVotes=" + stakeOfRejectedVotes + - ",\n numAcceptedVotes=" + numAcceptedVotes + - ",\n numRejectedVotes=" + numRejectedVotes + - ",\n numIgnoredVotes=" + numIgnoredVotes + - "\n}"; - } -} From 10b14a69ccc7d6a179585b7974abc9ae62176e69 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 2 Nov 2018 11:41:54 -0500 Subject: [PATCH 14/27] Moving classes That was a big commit with restructuring the packages and classes. Motivation was to isolate the daoState value objects so it is more clear which data are help in the daoState. As it was hard to keep an overview and easy to add mutable data I think that makes it more safe overall. I am aware that the downside to take out domain models from the domain packages is not so nice. Also moved blockchain models to parser and full node packages. --- .../dao/governance/ballot/BallotList.java | 80 ---------- .../bisq/core/dao/governance/role/Role.java | 148 ------------------ 2 files changed, 228 deletions(-) delete mode 100644 core/src/main/java/bisq/core/dao/governance/ballot/BallotList.java delete mode 100644 core/src/main/java/bisq/core/dao/governance/role/Role.java diff --git a/core/src/main/java/bisq/core/dao/governance/ballot/BallotList.java b/core/src/main/java/bisq/core/dao/governance/ballot/BallotList.java deleted file mode 100644 index 101033303fc..00000000000 --- a/core/src/main/java/bisq/core/dao/governance/ballot/BallotList.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.core.dao.governance.ballot; - -import bisq.core.dao.governance.ConsensusCritical; -import bisq.core.dao.state.ImmutableDaoStateVo; - -import bisq.common.proto.persistable.PersistableList; - -import io.bisq.generated.protobuffer.PB; - -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import lombok.EqualsAndHashCode; - -import javax.annotation.concurrent.Immutable; - -/** - * PersistableEnvelope wrapper for list of ballots. - */ -@Immutable -@EqualsAndHashCode(callSuper = true) -public class BallotList extends PersistableList implements ConsensusCritical, ImmutableDaoStateVo { - - public BallotList(List list) { - super(list); - } - - BallotList() { - super(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public PB.PersistableEnvelope toProtoMessage() { - return PB.PersistableEnvelope.newBuilder().setBallotList(getBuilder()).build(); - } - - public PB.BallotList.Builder getBuilder() { - return PB.BallotList.newBuilder() - .addAllBallot(getList().stream() - .map(Ballot::toProtoMessage) - .collect(Collectors.toList())); - } - - public static BallotList fromProto(PB.BallotList proto) { - return new BallotList(new ArrayList<>(proto.getBallotList().stream() - .map(Ballot::fromProto) - .collect(Collectors.toList()))); - } - - @Override - public String toString() { - return "List of UID's in BallotList: " + getList().stream() - .map(Ballot::getTxId) - .collect(Collectors.toList()); - } -} - diff --git a/core/src/main/java/bisq/core/dao/governance/role/Role.java b/core/src/main/java/bisq/core/dao/governance/role/Role.java deleted file mode 100644 index 082c60c5f6c..00000000000 --- a/core/src/main/java/bisq/core/dao/governance/role/Role.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.core.dao.governance.role; - -import bisq.core.dao.bonding.bond.BondWithHash; -import bisq.core.locale.Res; - -import bisq.common.crypto.Hash; -import bisq.common.proto.ProtoUtil; -import bisq.common.proto.network.NetworkPayload; -import bisq.common.proto.persistable.PersistablePayload; - -import io.bisq.generated.protobuffer.PB; - -import java.math.BigInteger; - -import java.util.Objects; -import java.util.UUID; - -import lombok.Value; -import lombok.extern.slf4j.Slf4j; - -import javax.annotation.concurrent.Immutable; - -/** - * Immutable data for a role. Is stored in the DaoState as part of the evaluated proposals. - */ -@Immutable -@Slf4j -@Value -public final class Role implements PersistablePayload, NetworkPayload, BondWithHash { - private final String uid; - private final String name; - private final String link; - private final BondedRoleType bondedRoleType; - - /** - * @param name Full name or nickname - * @param link Github account or forum account of user - * @param bondedRoleType BondedRoleType - */ - public Role(String name, - String link, - BondedRoleType bondedRoleType) { - this(UUID.randomUUID().toString(), - name, - link, - bondedRoleType - ); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER - /////////////////////////////////////////////////////////////////////////////////////////// - - public Role(String uid, - String name, - String link, - BondedRoleType bondedRoleType) { - this.uid = uid; - this.name = name; - this.link = link; - this.bondedRoleType = bondedRoleType; - } - - @Override - public PB.Role toProtoMessage() { - PB.Role.Builder builder = PB.Role.newBuilder() - .setUid(uid) - .setName(name) - .setLink(link) - .setBondedRoleType(bondedRoleType.name()); - return builder.build(); - } - - public static Role fromProto(PB.Role proto) { - return new Role(proto.getUid(), - proto.getName(), - proto.getLink(), - ProtoUtil.enumFromProto(BondedRoleType.class, proto.getBondedRoleType())); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // BondWithHash implementation - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public byte[] getHash() { - // We use only the immutable data as input for hash - byte[] bytes = BigInteger.valueOf(hashCode()).toByteArray(); - return Hash.getSha256Ripemd160hash(bytes); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // API - /////////////////////////////////////////////////////////////////////////////////////////// - - public String getDisplayString() { - return Res.get("dao.bond.bondedRoleType." + bondedRoleType.name()) + ": " + name; - } - - // We use only the immutable data - // bondedRoleType must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! - // The equals and hashCode methods cannot be overwritten in Enums. - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Role that = (Role) o; - return Objects.equals(uid, that.uid) && - Objects.equals(name, that.name) && - Objects.equals(link, that.link) && - bondedRoleType.name().equals(that.bondedRoleType.name()); - } - - @Override - public int hashCode() { - return Objects.hash(uid, name, link, bondedRoleType.name()); - } - - @Override - public String toString() { - return "Role{" + - "\n uid='" + uid + '\'' + - ",\n name='" + name + '\'' + - ",\n link='" + link + '\'' + - ",\n bondedRoleType=" + bondedRoleType + - "\n}"; - } -} From 8ce8813e8935b56f68076c1c9662addb76c17cfe Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 2 Nov 2018 16:09:53 -0500 Subject: [PATCH 15/27] Complete handling of bonds for roles. - Add BondedRoleState to reflect all diff. states. - Show in UI correct state and button state for lockup/revoke - Rename ProposalService classes to ProposalFactory --- .../main/java/bisq/core/dao/DaoFacade.java | 83 +++++----- .../main/java/bisq/core/dao/DaoModule.java | 28 ++-- .../core/dao/governance/bond/BondedRole.java | 22 +-- .../dao/governance/bond/BondedRoleState.java | 29 ++++ .../governance/bond/BondedRolesService.java | 142 +++++++++++------- .../bonding/lockup/LockupService.java | 15 +- .../bonding/unlock/UnlockService.java | 7 +- ...lService.java => BaseProposalFactory.java} | 7 +- ....java => CompensationProposalFactory.java} | 6 +- ...ava => ConfiscateBondProposalFactory.java} | 6 +- ...rvice.java => GenericProposalFactory.java} | 6 +- ...e.java => ChangeParamProposalFactory.java} | 6 +- ...java => ReimbursementProposalFactory.java} | 6 +- ...e.java => RemoveAssetProposalFactory.java} | 6 +- ...lService.java => RoleProposalFactory.java} | 6 +- .../bisq/core/dao/state/DaoStateService.java | 11 +- .../resources/i18n/displayStrings.properties | 17 ++- .../i18n/displayStrings_de.properties | 2 +- .../i18n/displayStrings_el.properties | 2 +- .../i18n/displayStrings_es.properties | 2 +- .../i18n/displayStrings_fa.properties | 2 +- .../i18n/displayStrings_hu.properties | 2 +- .../i18n/displayStrings_pt.properties | 2 +- .../i18n/displayStrings_ro.properties | 2 +- .../i18n/displayStrings_ru.properties | 2 +- .../i18n/displayStrings_sr.properties | 2 +- .../i18n/displayStrings_th.properties | 2 +- .../i18n/displayStrings_vi.properties | 2 +- .../i18n/displayStrings_zh.properties | 2 +- .../main/dao/bonding/BondingViewUtils.java | 34 ++--- .../main/dao/bonding/lockup/LockupView.java | 6 +- .../bonding/roles/BondedRolesListItem.java | 87 ++++++----- .../dao/bonding/roles/BondedRolesView.java | 20 +-- .../main/dao/bonding/unlock/UnlockView.java | 2 +- 34 files changed, 324 insertions(+), 252 deletions(-) create mode 100644 core/src/main/java/bisq/core/dao/governance/bond/BondedRoleState.java rename core/src/main/java/bisq/core/dao/governance/proposal/{BaseProposalService.java => BaseProposalFactory.java} (94%) rename core/src/main/java/bisq/core/dao/governance/proposal/compensation/{CompensationProposalService.java => CompensationProposalFactory.java} (94%) rename core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/{ConfiscateBondProposalService.java => ConfiscateBondProposalFactory.java} (91%) rename core/src/main/java/bisq/core/dao/governance/proposal/generic/{GenericProposalService.java => GenericProposalFactory.java} (92%) rename core/src/main/java/bisq/core/dao/governance/proposal/param/{ChangeParamProposalService.java => ChangeParamProposalFactory.java} (92%) rename core/src/main/java/bisq/core/dao/governance/proposal/reimbursement/{ReimbursementProposalService.java => ReimbursementProposalFactory.java} (94%) rename core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/{RemoveAssetProposalService.java => RemoveAssetProposalFactory.java} (92%) rename core/src/main/java/bisq/core/dao/governance/proposal/role/{RoleProposalService.java => RoleProposalFactory.java} (92%) diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index 5518ce6b63d..4dbed2c7ca8 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -42,14 +42,14 @@ import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.governance.proposal.compensation.CompensationConsensus; -import bisq.core.dao.governance.proposal.compensation.CompensationProposalService; -import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposalService; -import bisq.core.dao.governance.proposal.generic.GenericProposalService; -import bisq.core.dao.governance.proposal.param.ChangeParamProposalService; +import bisq.core.dao.governance.proposal.compensation.CompensationProposalFactory; +import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposalFactory; +import bisq.core.dao.governance.proposal.generic.GenericProposalFactory; +import bisq.core.dao.governance.proposal.param.ChangeParamProposalFactory; import bisq.core.dao.governance.proposal.reimbursement.ReimbursementConsensus; -import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposalService; -import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalService; -import bisq.core.dao.governance.proposal.role.RoleProposalService; +import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposalFactory; +import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalFactory; +import bisq.core.dao.governance.proposal.role.RoleProposalFactory; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateStorageService; @@ -89,6 +89,7 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Consumer; import lombok.extern.slf4j.Slf4j; @@ -108,13 +109,13 @@ public class DaoFacade implements DaoSetupService { private final PeriodService periodService; private final MyBlindVoteListService myBlindVoteListService; private final MyVoteListService myVoteListService; - private final CompensationProposalService compensationProposalService; - private final ReimbursementProposalService reimbursementProposalService; - private final ChangeParamProposalService changeParamProposalService; - private final ConfiscateBondProposalService confiscateBondProposalService; - private final RoleProposalService roleProposalService; - private final GenericProposalService genericProposalService; - private final RemoveAssetProposalService removeAssetProposalService; + private final CompensationProposalFactory compensationProposalFactory; + private final ReimbursementProposalFactory reimbursementProposalFactory; + private final ChangeParamProposalFactory changeParamProposalFactory; + private final ConfiscateBondProposalFactory confiscateBondProposalFactory; + private final RoleProposalFactory roleProposalFactory; + private final GenericProposalFactory genericProposalFactory; + private final RemoveAssetProposalFactory removeAssetProposalFactory; private final BondedRolesService bondedRolesService; private final BondedReputationService bondedReputationService; private final LockupService lockupService; @@ -132,13 +133,13 @@ public DaoFacade(MyProposalListService myProposalListService, PeriodService periodService, MyBlindVoteListService myBlindVoteListService, MyVoteListService myVoteListService, - CompensationProposalService compensationProposalService, - ReimbursementProposalService reimbursementProposalService, - ChangeParamProposalService changeParamProposalService, - ConfiscateBondProposalService confiscateBondProposalService, - RoleProposalService roleProposalService, - GenericProposalService genericProposalService, - RemoveAssetProposalService removeAssetProposalService, + CompensationProposalFactory compensationProposalFactory, + ReimbursementProposalFactory reimbursementProposalFactory, + ChangeParamProposalFactory changeParamProposalFactory, + ConfiscateBondProposalFactory confiscateBondProposalFactory, + RoleProposalFactory roleProposalFactory, + GenericProposalFactory genericProposalFactory, + RemoveAssetProposalFactory removeAssetProposalFactory, BondedRolesService bondedRolesService, BondedReputationService bondedReputationService, LockupService lockupService, @@ -152,13 +153,13 @@ public DaoFacade(MyProposalListService myProposalListService, this.periodService = periodService; this.myBlindVoteListService = myBlindVoteListService; this.myVoteListService = myVoteListService; - this.compensationProposalService = compensationProposalService; - this.reimbursementProposalService = reimbursementProposalService; - this.changeParamProposalService = changeParamProposalService; - this.confiscateBondProposalService = confiscateBondProposalService; - this.roleProposalService = roleProposalService; - this.genericProposalService = genericProposalService; - this.removeAssetProposalService = removeAssetProposalService; + this.compensationProposalFactory = compensationProposalFactory; + this.reimbursementProposalFactory = reimbursementProposalFactory; + this.changeParamProposalFactory = changeParamProposalFactory; + this.confiscateBondProposalFactory = confiscateBondProposalFactory; + this.roleProposalFactory = roleProposalFactory; + this.genericProposalFactory = genericProposalFactory; + this.removeAssetProposalFactory = removeAssetProposalFactory; this.bondedRolesService = bondedRolesService; this.bondedReputationService = bondedReputationService; this.lockupService = lockupService; @@ -229,7 +230,7 @@ public ProposalWithTransaction getCompensationProposalWithTransaction(String nam String link, Coin requestedBsq) throws ValidationException, InsufficientMoneyException, TxException { - return compensationProposalService.createProposalWithTransaction(name, + return compensationProposalFactory.createProposalWithTransaction(name, link, requestedBsq); } @@ -238,7 +239,7 @@ public ProposalWithTransaction getReimbursementProposalWithTransaction(String na String link, Coin requestedBsq) throws ValidationException, InsufficientMoneyException, TxException { - return reimbursementProposalService.createProposalWithTransaction(name, + return reimbursementProposalFactory.createProposalWithTransaction(name, link, requestedBsq); } @@ -248,7 +249,7 @@ public ProposalWithTransaction getParamProposalWithTransaction(String name, Param param, String paramValue) throws ValidationException, InsufficientMoneyException, TxException { - return changeParamProposalService.createProposalWithTransaction(name, + return changeParamProposalFactory.createProposalWithTransaction(name, link, param, paramValue); @@ -258,31 +259,31 @@ public ProposalWithTransaction getConfiscateBondProposalWithTransaction(String n String link, byte[] hash) throws ValidationException, InsufficientMoneyException, TxException { - return confiscateBondProposalService.createProposalWithTransaction(name, + return confiscateBondProposalFactory.createProposalWithTransaction(name, link, hash); } public ProposalWithTransaction getBondedRoleProposalWithTransaction(Role role) throws ValidationException, InsufficientMoneyException, TxException { - return roleProposalService.createProposalWithTransaction(role); + return roleProposalFactory.createProposalWithTransaction(role); } public ProposalWithTransaction getGenericProposalWithTransaction(String name, String link) throws ValidationException, InsufficientMoneyException, TxException { - return genericProposalService.createProposalWithTransaction(name, link); + return genericProposalFactory.createProposalWithTransaction(name, link); } public ProposalWithTransaction getRemoveAssetProposalWithTransaction(String name, String link, Asset asset) throws ValidationException, InsufficientMoneyException, TxException { - return removeAssetProposalService.createProposalWithTransaction(name, link, asset); + return removeAssetProposalFactory.createProposalWithTransaction(name, link, asset); } - public Collection getBondedRoleStates() { - return bondedRolesService.getBondedRoleStates(); + public Collection getBondedRoles() { + return bondedRolesService.getBondedRoles(); } public List getBondedReputationList() { @@ -487,11 +488,11 @@ public int getChainHeight() { /////////////////////////////////////////////////////////////////////////////////////////// public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, BondWithHash bondWithHash, - ResultHandler resultHandler, ExceptionHandler exceptionHandler) { + Consumer resultHandler, ExceptionHandler exceptionHandler) { lockupService.publishLockupTx(lockupAmount, lockTime, lockupType, bondWithHash, resultHandler, exceptionHandler); } - public void publishUnlockTx(String lockupTxId, ResultHandler resultHandler, + public void publishUnlockTx(String lockupTxId, Consumer resultHandler, ExceptionHandler exceptionHandler) { unlockService.publishUnlockTx(lockupTxId, resultHandler, exceptionHandler); } @@ -656,4 +657,8 @@ public String getParamValue(Param param) { public void resyncDao(Runnable resultHandler) { daoStateStorageService.resetDaoState(resultHandler); } + + public boolean isMyRole(Role role) { + return bondedRolesService.isMyRole(role); + } } diff --git a/core/src/main/java/bisq/core/dao/DaoModule.java b/core/src/main/java/bisq/core/dao/DaoModule.java index 99bc45fdb9a..b2317928f0f 100644 --- a/core/src/main/java/bisq/core/dao/DaoModule.java +++ b/core/src/main/java/bisq/core/dao/DaoModule.java @@ -37,19 +37,19 @@ import bisq.core.dao.governance.proposal.ProposalListPresentation; import bisq.core.dao.governance.proposal.ProposalService; import bisq.core.dao.governance.proposal.ProposalValidator; -import bisq.core.dao.governance.proposal.compensation.CompensationProposalService; +import bisq.core.dao.governance.proposal.compensation.CompensationProposalFactory; import bisq.core.dao.governance.proposal.compensation.CompensationValidator; -import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposalService; +import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondProposalFactory; import bisq.core.dao.governance.proposal.confiscatebond.ConfiscateBondValidator; -import bisq.core.dao.governance.proposal.generic.GenericProposalService; +import bisq.core.dao.governance.proposal.generic.GenericProposalFactory; import bisq.core.dao.governance.proposal.generic.GenericProposalValidator; -import bisq.core.dao.governance.proposal.param.ChangeParamProposalService; +import bisq.core.dao.governance.proposal.param.ChangeParamProposalFactory; import bisq.core.dao.governance.proposal.param.ChangeParamValidator; -import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposalService; +import bisq.core.dao.governance.proposal.reimbursement.ReimbursementProposalFactory; import bisq.core.dao.governance.proposal.reimbursement.ReimbursementValidator; -import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalService; +import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetProposalFactory; import bisq.core.dao.governance.proposal.removeAsset.RemoveAssetValidator; -import bisq.core.dao.governance.proposal.role.RoleProposalService; +import bisq.core.dao.governance.proposal.role.RoleProposalFactory; import bisq.core.dao.governance.proposal.role.RoleValidator; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStorageService; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStore; @@ -132,25 +132,25 @@ protected void configure() { bind(ProposalValidator.class).in(Singleton.class); bind(CompensationValidator.class).in(Singleton.class); - bind(CompensationProposalService.class).in(Singleton.class); + bind(CompensationProposalFactory.class).in(Singleton.class); bind(ReimbursementValidator.class).in(Singleton.class); - bind(ReimbursementProposalService.class).in(Singleton.class); + bind(ReimbursementProposalFactory.class).in(Singleton.class); bind(ChangeParamValidator.class).in(Singleton.class); - bind(ChangeParamProposalService.class).in(Singleton.class); + bind(ChangeParamProposalFactory.class).in(Singleton.class); bind(RoleValidator.class).in(Singleton.class); - bind(RoleProposalService.class).in(Singleton.class); + bind(RoleProposalFactory.class).in(Singleton.class); bind(ConfiscateBondValidator.class).in(Singleton.class); - bind(ConfiscateBondProposalService.class).in(Singleton.class); + bind(ConfiscateBondProposalFactory.class).in(Singleton.class); bind(GenericProposalValidator.class).in(Singleton.class); - bind(GenericProposalService.class).in(Singleton.class); + bind(GenericProposalFactory.class).in(Singleton.class); bind(RemoveAssetValidator.class).in(Singleton.class); - bind(RemoveAssetProposalService.class).in(Singleton.class); + bind(RemoveAssetProposalFactory.class).in(Singleton.class); // Ballot diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondedRole.java b/core/src/main/java/bisq/core/dao/governance/bond/BondedRole.java index eecfc8af126..b5ed827eede 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondedRole.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondedRole.java @@ -30,32 +30,20 @@ @Getter public class BondedRole { private final Role role; - - @Setter - private long startDate; - // LockupTxId is null as long the bond holder has not been accepted by voting and made the lockup tx. - // It will get set after the proposal has been accepted and the lockup tx is confirmed. @Setter @Nullable private String lockupTxId; - // Date when role has been revoked - @Setter - private long revokeDate; @Setter @Nullable private String unlockTxId; @Setter - private boolean isUnlocking; + private long startDate; + @Setter + private long revokeDate; + @Setter + private BondedRoleState bondedRoleState = BondedRoleState.READY_FOR_LOCKUP; BondedRole(Role role) { this.role = role; } - - public boolean isLockedUp() { - return lockupTxId != null; - } - - public boolean isUnlocked() { - return unlockTxId != null; - } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondedRoleState.java b/core/src/main/java/bisq/core/dao/governance/bond/BondedRoleState.java new file mode 100644 index 00000000000..f6ddd65042f --- /dev/null +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondedRoleState.java @@ -0,0 +1,29 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.governance.bond; + +// Used in string properties ("dao.bond.bondedRoleState.*") +public enum BondedRoleState { + READY_FOR_LOCKUP, // Accepted by voting but no lockup tx made yet. + LOCKUP_TX_PENDING, // Tx broadcasted but not confirmed. Used only by tx publisher. + LOCKUP_TX_CONFIRMED, + UNLOCK_TX_PENDING, // Tx broadcasted but not confirmed. Used only by tx publisher. + UNLOCK_TX_CONFIRMED, + UNLOCKING, // lock time not expired + UNLOCKED, +} diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondedRolesService.java b/core/src/main/java/bisq/core/dao/governance/bond/BondedRolesService.java index 50d7d4adf8b..db1690f2b69 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondedRolesService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondedRolesService.java @@ -17,7 +17,9 @@ package bisq.core.dao.governance.bond; +import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.governance.bonding.BondingConsensus; +import bisq.core.dao.governance.bonding.bond.BondWithHash; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.model.blockchain.BaseTxOutput; @@ -25,9 +27,15 @@ import bisq.core.dao.state.model.blockchain.SpentInfo; import bisq.core.dao.state.model.blockchain.TxType; import bisq.core.dao.state.model.governance.BondedRoleType; +import bisq.core.dao.state.model.governance.Proposal; import bisq.core.dao.state.model.governance.Role; import bisq.core.dao.state.model.governance.RoleProposal; +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionConfidence; +import org.bitcoinj.core.TransactionInput; +import org.bitcoinj.core.TransactionOutput; + import javax.inject.Inject; import java.util.Arrays; @@ -35,7 +43,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -49,9 +59,10 @@ @Slf4j public class BondedRolesService implements DaoStateListener { private final DaoStateService daoStateService; + private final BsqWalletService bsqWalletService; // This map is just for convenience. The data which are used to fill the map are store din the DaoState (role, txs). - private final Map bondedRoleStateMap = new HashMap<>(); + private final Map bondedRoleByRoleUidMap = new HashMap<>(); /////////////////////////////////////////////////////////////////////////////////////////// @@ -59,8 +70,9 @@ public class BondedRolesService implements DaoStateListener { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public BondedRolesService(DaoStateService daoStateService) { + public BondedRolesService(DaoStateService daoStateService, BsqWalletService bsqWalletService) { this.daoStateService = daoStateService; + this.bsqWalletService = bsqWalletService; daoStateService.addBsqStateListener(this); } @@ -78,8 +90,8 @@ public void onNewBlockHeight(int blockHeight) { public void onParseTxsComplete(Block block) { // TODO optimize to not re-write the whole map at each block getBondedRoleStream().forEach(bondedRole -> { - bondedRoleStateMap.putIfAbsent(bondedRole.getUid(), new BondedRole(bondedRole)); - BondedRole bondedRoleState = bondedRoleStateMap.get(bondedRole.getUid()); + bondedRoleByRoleUidMap.putIfAbsent(bondedRole.getUid(), new BondedRole(bondedRole)); + BondedRole bondedRoleState = bondedRoleByRoleUidMap.get(bondedRole.getUid()); // Lets see if we have a lock up tx. daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> { @@ -94,17 +106,10 @@ public void onParseTxsComplete(Block block) { byte[] hash = BondingConsensus.getHashFromOpReturnData(opReturnData); Optional candidate = getBondedRoleFromHash(hash); if (candidate.isPresent() && bondedRole.equals(candidate.get())) { - if (bondedRoleState.getLockupTxId() == null) { - bondedRoleState.setLockupTxId(lockupTxId); - // We use the tx time as we want to have a unique time for all users - bondedRoleState.setStartDate(lockupTx.getTime()); - } else { - checkArgument(bondedRoleState.getLockupTxId().equals(lockupTxId), - "We have already the lockup tx set in bondedRoleState " + - "but it is different to the one we found in the daoState transactions. " + - "That should not happen. bondedRole={}, bondedRoleState={}", - bondedRole, bondedRoleState); - } + bondedRoleState.setBondedRoleState(BondedRoleState.LOCKUP_TX_CONFIRMED); + bondedRoleState.setLockupTxId(lockupTxId); + // We use the tx time as we want to have a unique time for all users + bondedRoleState.setStartDate(lockupTx.getTime()); if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { // Lockup is already spent (in unlock tx) @@ -115,26 +120,24 @@ public void onParseTxsComplete(Block block) { .ifPresent(unlockTx -> { // cross check if it is in daoStateService.getUnlockTxOutputs() ? String unlockTxId = unlockTx.getId(); - if (bondedRoleState.getUnlockTxId() == null) { - bondedRoleState.setUnlockTxId(unlockTxId); - bondedRoleState.setRevokeDate(unlockTx.getTime()); - bondedRoleState.setUnlocking(daoStateService.isUnlocking(unlockTxId)); - //TODO after locktime set to false or maybe better use states for lock state + bondedRoleState.setUnlockTxId(unlockTxId); + bondedRoleState.setBondedRoleState(BondedRoleState.UNLOCK_TX_CONFIRMED); + bondedRoleState.setRevokeDate(unlockTx.getTime()); + boolean unlocking = daoStateService.isUnlocking(unlockTxId); + if (unlocking) { + bondedRoleState.setBondedRoleState(BondedRoleState.UNLOCKING); } else { - checkArgument(bondedRoleState.getUnlockTxId().equals(unlockTxId), - "We have already the unlock tx set in bondedRoleState " + - "but it is different to the one we found in the daoState transactions. " + - "That should not happen. bondedRole={}, bondedRoleState={}", - bondedRole, bondedRoleState); + bondedRoleState.setBondedRoleState(BondedRoleState.UNLOCKED); } - - // TODO check lock time }); } } }); }); }); + + updateBondedRoleStateFromUnconfirmedLockupTxs(); + updateBondedRoleStateFromUnconfirmedUnlockTxs(); } @@ -155,8 +158,8 @@ public List getBondedRoleList() { return getBondedRoleStream().collect(Collectors.toList()); } - public Collection getBondedRoleStates() { - return bondedRoleStateMap.values(); + public Collection getBondedRoles() { + return bondedRoleByRoleUidMap.values(); } // bonded roles which are active and can be confiscated @@ -165,6 +168,46 @@ public List getActiveBondedRoles() { return getBondedRoleList(); } + private void updateBondedRoleStateFromUnconfirmedLockupTxs() { + getBondedRoleStream().filter(this::isLockupTxUnconfirmed) + .map(role -> bondedRoleByRoleUidMap.get(role.getUid())) + .filter(bondedRole -> bondedRole.getBondedRoleState() == BondedRoleState.READY_FOR_LOCKUP) + .forEach(bondedRole -> bondedRole.setBondedRoleState(BondedRoleState.LOCKUP_TX_PENDING)); + } + + private void updateBondedRoleStateFromUnconfirmedUnlockTxs() { + getBondedRoleStream().filter(this::isUnlockTxUnconfirmed) + .map(role -> bondedRoleByRoleUidMap.get(role.getUid())) + .filter(bondedRole -> bondedRole.getBondedRoleState() == BondedRoleState.LOCKUP_TX_CONFIRMED) + .forEach(bondedRole -> bondedRole.setBondedRoleState(BondedRoleState.UNLOCK_TX_PENDING)); + } + + private boolean isLockupTxUnconfirmed(BondWithHash bondWithHash) { + return bsqWalletService.getWalletTransactions().stream() + .filter(transaction -> transaction.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.PENDING) + .map(transaction -> transaction.getOutputs().get(transaction.getOutputs().size() - 1)) + .filter(lastOutput -> lastOutput.getScriptPubKey().isOpReturn()) + .map(lastOutput -> lastOutput.getScriptPubKey().getChunks()) + .filter(chunks -> chunks.size() > 1) + .map(chunks -> chunks.get(1).data) + .anyMatch(data -> Arrays.equals(BondingConsensus.getHashFromOpReturnData(data), bondWithHash.getHash())); + } + + private boolean isUnlockTxUnconfirmed(BondWithHash bondWithHash) { + return bsqWalletService.getWalletTransactions().stream() + .filter(transaction -> transaction.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.PENDING) + .filter(transaction -> transaction.getInputs().size() > 1) + .map(transaction -> transaction.getInputs().get(0)) + .map(TransactionInput::getConnectedOutput) + .filter(Objects::nonNull) + .map(TransactionOutput::getParentTransaction) + .filter(Objects::nonNull) + .map(Transaction::getHashAsString) + .flatMap(lockupTxId -> daoStateService.getLockupOpReturnTxOutput(lockupTxId).stream()) + .map(BaseTxOutput::getOpReturnData) + .anyMatch(data -> Arrays.equals(BondingConsensus.getHashFromOpReturnData(data), bondWithHash.getHash())); + } + public Optional getBondedRoleFromHash(byte[] hash) { return getBondedRoleStream() .filter(bondedRole -> { @@ -180,7 +223,7 @@ public Optional getBondedRoleFromHash(byte[] hash) { } public Optional getBondedRoleStateFromLockupTxId(String lockupTxId) { - return bondedRoleStateMap.values().stream() + return bondedRoleByRoleUidMap.values().stream() .filter(bondedRoleState -> lockupTxId.equals(bondedRoleState.getLockupTxId())) .findAny(); } @@ -204,32 +247,25 @@ private Stream getBondedRoleStream() { .map(e -> ((RoleProposal) e.getProposal()).getRole()); } - - private Optional getOpReturnData(String lockUpTxId) { - return daoStateService.getLockupOpReturnTxOutput(lockUpTxId).map(BaseTxOutput::getOpReturnData); + private Stream getBondedRoleProposalStream() { + return daoStateService.getEvaluatedProposalList().stream() + .filter(evaluatedProposal -> evaluatedProposal.getProposal() instanceof RoleProposal) + .map(e -> ((RoleProposal) e.getProposal())); } public boolean wasRoleAlreadyBonded(Role role) { - BondedRole bondedRole = bondedRoleStateMap.get(role.getUid()); - return bondedRole != null && bondedRole.getLockupTxId() != null; + BondedRole bondedRole = bondedRoleByRoleUidMap.get(role.getUid()); + checkArgument(bondedRole != null, "bondedRole must not be null"); + return bondedRole.getLockupTxId() != null; } - - /* private Optional getOptionalLockupType(String lockUpTxId) { - return getOpReturnData(lockUpTxId) - .flatMap(BondingConsensus::getLockupType); - }*/ - - /*public static Optional getBondedRoleByLockupTxId(String lockupTxId) { - return bondedRoles.stream() - .filter(bondedRole -> bondedRole.getLockupTxId().equals(lockupTxId)). - findAny(); - }*/ -/* - public static Optional getBondedRoleByHashOfBondId(byte[] hash) { - return Optional.empty(); - *//* bondedRoles.stream() - .filter(bondedRole -> Arrays.equals(bondedRole.getHash(), hash)) - .findAny();*//* - }*/ + public boolean isMyRole(Role role) { + Set myWalletTransactionIds = bsqWalletService.getWalletTransactions().stream() + .map(Transaction::getHashAsString) + .collect(Collectors.toSet()); + return getBondedRoleProposalStream() + .filter(roleProposal -> roleProposal.getRole().equals(role)) + .map(Proposal::getTxId) + .anyMatch(myWalletTransactionIds::contains); + } } diff --git a/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupService.java b/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupService.java index 43617bb2ebc..04e75e57ca5 100644 --- a/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupService.java +++ b/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupService.java @@ -31,7 +31,6 @@ import bisq.core.dao.state.model.governance.Role; import bisq.common.handlers.ExceptionHandler; -import bisq.common.handlers.ResultHandler; import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; @@ -41,6 +40,8 @@ import java.io.IOException; +import java.util.function.Consumer; + import lombok.extern.slf4j.Slf4j; import static com.google.common.base.Preconditions.checkArgument; @@ -69,10 +70,9 @@ public LockupService(WalletsManager walletsManager, } public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, BondWithHash bondWithHash, - ResultHandler resultHandler, ExceptionHandler exceptionHandler) { + Consumer resultHandler, ExceptionHandler exceptionHandler) { checkArgument(lockTime <= BondingConsensus.getMaxLockTime() && lockTime >= BondingConsensus.getMinLockTime(), "lockTime not in rage"); - if (bondWithHash instanceof Role) { Role role = (Role) bondWithHash; if (bondedRolesService.wasRoleAlreadyBonded(role)) { @@ -81,17 +81,16 @@ public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupTy } } + byte[] hash = BondingConsensus.getHash(bondWithHash); try { - - byte[] hash = BondingConsensus.getHash(bondWithHash); byte[] opReturnData = BondingConsensus.getLockupOpReturnData(lockTime, lockupType, hash); - final Transaction lockupTx = getLockupTx(lockupAmount, opReturnData); + final Transaction lockupTx = createLockupTx(lockupAmount, opReturnData); //noinspection Duplicates walletsManager.publishAndCommitBsqTx(lockupTx, new TxBroadcaster.Callback() { @Override public void onSuccess(Transaction transaction) { - resultHandler.handleResult(); + resultHandler.accept(transaction.getHashAsString()); } @Override @@ -111,7 +110,7 @@ public void onFailure(TxBroadcastException exception) { } } - private Transaction getLockupTx(Coin lockupAmount, byte[] opReturnData) + private Transaction createLockupTx(Coin lockupAmount, byte[] opReturnData) throws InsufficientMoneyException, WalletException, TransactionVerificationException { Transaction preparedTx = bsqWalletService.getPreparedLockupTx(lockupAmount); Transaction txWithBtcFee = btcWalletService.completePreparedBsqTx(preparedTx, true, opReturnData); diff --git a/core/src/main/java/bisq/core/dao/governance/bonding/unlock/UnlockService.java b/core/src/main/java/bisq/core/dao/governance/bonding/unlock/UnlockService.java index 9a9a9af27fc..d3f8242c565 100644 --- a/core/src/main/java/bisq/core/dao/governance/bonding/unlock/UnlockService.java +++ b/core/src/main/java/bisq/core/dao/governance/bonding/unlock/UnlockService.java @@ -29,13 +29,14 @@ import bisq.core.dao.state.model.blockchain.TxOutput; import bisq.common.handlers.ExceptionHandler; -import bisq.common.handlers.ResultHandler; import org.bitcoinj.core.InsufficientMoneyException; import org.bitcoinj.core.Transaction; import javax.inject.Inject; +import java.util.function.Consumer; + import lombok.extern.slf4j.Slf4j; @Slf4j @@ -61,7 +62,7 @@ public UnlockService(WalletsManager walletsManager, this.daoStateService = daoStateService; } - public void publishUnlockTx(String lockupTxId, ResultHandler resultHandler, + public void publishUnlockTx(String lockupTxId, Consumer resultHandler, ExceptionHandler exceptionHandler) { try { TxOutput lockupTxOutput = daoStateService.getLockupTxOutput(lockupTxId).get(); @@ -71,7 +72,7 @@ public void publishUnlockTx(String lockupTxId, ResultHandler resultHandler, walletsManager.publishAndCommitBsqTx(unlockTx, new TxBroadcaster.Callback() { @Override public void onSuccess(Transaction transaction) { - resultHandler.handleResult(); + resultHandler.accept(transaction.getHashAsString()); } @Override diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalFactory.java similarity index 94% rename from core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalService.java rename to core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalFactory.java index 36e56d1ca2a..dbecf46283e 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/BaseProposalFactory.java @@ -37,10 +37,11 @@ import javax.annotation.Nullable; /** - * Base class for proposalService classes. Provides creation of a transaction. + * Base class for proposalFactory classes. Provides creation of a transaction. Proposal creation is delegated to + * concrete classes. */ @Slf4j -public abstract class BaseProposalService { +public abstract class BaseProposalFactory { protected final BsqWalletService bsqWalletService; protected final BtcWalletService btcWalletService; protected final DaoStateService daoStateService; @@ -55,7 +56,7 @@ public abstract class BaseProposalService { // Constructor /////////////////////////////////////////////////////////////////////////////////////////// - public BaseProposalService(BsqWalletService bsqWalletService, + public BaseProposalFactory(BsqWalletService bsqWalletService, BtcWalletService btcWalletService, DaoStateService daoStateService, ProposalValidator proposalValidator) { diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposalFactory.java similarity index 94% rename from core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposalService.java rename to core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposalFactory.java index e78dce8598c..0b61fac400f 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/compensation/CompensationProposalFactory.java @@ -22,7 +22,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.BaseProposalService; +import bisq.core.dao.governance.proposal.BaseProposalFactory; import bisq.core.dao.governance.proposal.ProposalConsensus; import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; @@ -45,13 +45,13 @@ * Creates the CompensationProposal and the transaction. */ @Slf4j -public class CompensationProposalService extends BaseProposalService { +public class CompensationProposalFactory extends BaseProposalFactory { private Coin requestedBsq; private String bsqAddress; @Inject - public CompensationProposalService(BsqWalletService bsqWalletService, + public CompensationProposalFactory(BsqWalletService bsqWalletService, BtcWalletService btcWalletService, DaoStateService daoStateService, CompensationValidator proposalValidator) { diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalFactory.java similarity index 91% rename from core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalService.java rename to core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalFactory.java index 5dc238d98ff..59ebcf5337e 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalFactory.java @@ -20,7 +20,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.BaseProposalService; +import bisq.core.dao.governance.proposal.BaseProposalFactory; import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.state.DaoStateService; @@ -36,7 +36,7 @@ * Creates ConfiscateBondProposal and transaction. */ @Slf4j -public class ConfiscateBondProposalService extends BaseProposalService { +public class ConfiscateBondProposalFactory extends BaseProposalFactory { private byte[] hash; @@ -45,7 +45,7 @@ public class ConfiscateBondProposalService extends BaseProposalService { +public class GenericProposalFactory extends BaseProposalFactory { /////////////////////////////////////////////////////////////////////////////////////////// @@ -44,7 +44,7 @@ public class GenericProposalService extends BaseProposalService /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public GenericProposalService(BsqWalletService bsqWalletService, + public GenericProposalFactory(BsqWalletService bsqWalletService, BtcWalletService btcWalletService, DaoStateService daoStateService, GenericProposalValidator proposalValidator) { diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposalFactory.java similarity index 92% rename from core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposalService.java rename to core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposalFactory.java index a166e01b9e5..4ff64e37f34 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/param/ChangeParamProposalFactory.java @@ -21,7 +21,7 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.exceptions.ValidationException; import bisq.core.dao.governance.param.Param; -import bisq.core.dao.governance.proposal.BaseProposalService; +import bisq.core.dao.governance.proposal.BaseProposalFactory; import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.state.DaoStateService; @@ -37,7 +37,7 @@ * Creates ChangeParamProposal and transaction. */ @Slf4j -public class ChangeParamProposalService extends BaseProposalService { +public class ChangeParamProposalFactory extends BaseProposalFactory { private Param param; private String paramValue; @@ -47,7 +47,7 @@ public class ChangeParamProposalService extends BaseProposalService { +public class ReimbursementProposalFactory extends BaseProposalFactory { private Coin requestedBsq; private String bsqAddress; @Inject - public ReimbursementProposalService(BsqWalletService bsqWalletService, + public ReimbursementProposalFactory(BsqWalletService bsqWalletService, BtcWalletService btcWalletService, DaoStateService daoStateService, ReimbursementValidator proposalValidator) { diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposalService.java b/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposalFactory.java similarity index 92% rename from core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposalService.java rename to core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposalFactory.java index 4ba9b913b7e..71d8c56ea6f 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposalService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/removeAsset/RemoveAssetProposalFactory.java @@ -20,7 +20,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.exceptions.ValidationException; -import bisq.core.dao.governance.proposal.BaseProposalService; +import bisq.core.dao.governance.proposal.BaseProposalFactory; import bisq.core.dao.governance.proposal.ProposalWithTransaction; import bisq.core.dao.governance.proposal.TxException; import bisq.core.dao.state.DaoStateService; @@ -38,7 +38,7 @@ * Creates RemoveAssetProposal and transaction. */ @Slf4j -public class RemoveAssetProposalService extends BaseProposalService { +public class RemoveAssetProposalFactory extends BaseProposalFactory { private Asset asset; @@ -47,7 +47,7 @@ public class RemoveAssetProposalService extends BaseProposalService { +public class RoleProposalFactory extends BaseProposalFactory { private Role role; @@ -46,7 +46,7 @@ public class RoleProposalService extends BaseProposalService { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public RoleProposalService(BsqWalletService bsqWalletService, + public RoleProposalFactory(BsqWalletService bsqWalletService, BtcWalletService btcWalletService, DaoStateService daoStateService, RoleValidator proposalValidator) { diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateService.java b/core/src/main/java/bisq/core/dao/state/DaoStateService.java index 7c05ed9d28d..63436de0d82 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateService.java @@ -687,7 +687,11 @@ public boolean isUnlockingOutput(TxOutputKey key) { return opTxOutput.isPresent() && isUnlockingOutput(opTxOutput.get()); } - // TODO SQ i changed the code here. i think it was wrong before + public boolean isUnlocking(String unlockTxId) { + Optional optionalTx = getTx(unlockTxId); + return optionalTx.isPresent() && isUnlockingOutput(optionalTx.get().getTxOutputs().get(0)); + } + public boolean isUnlockingOutput(TxOutput unlockTxOutput) { return unlockTxOutput.getTxOutputType() == TxOutputType.UNLOCK_OUTPUT && !isLockTimeOverForUnlockTxOutput(unlockTxOutput); @@ -756,11 +760,6 @@ public void applyConfiscateBond(TxOutput txOutput) { // txOutput.setTxOutputType(TxOutputType.BTC_OUTPUT); } - public boolean isUnlocking(String unlockTxId) { - Optional optionalTx = getTx(unlockTxId); - return optionalTx.isPresent() && isUnlockingOutput(optionalTx.get().getTxOutputs().get(0)); - } - /////////////////////////////////////////////////////////////////////////////////////////// // Param diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index e8e55a0296c..1d44fbad8aa 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -1382,7 +1382,7 @@ dao.bond.bondedReputation=Bonded Reputation dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=Name -dao.bond.table.column.header.linkToAccount=Account +dao.bond.table.column.header.link=Link dao.bond.table.column.header.bondedRoleType=Role dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID @@ -1397,6 +1397,21 @@ dao.bond.table.lockedUp=Bond locked up dao.bond.table.unlocking=Bond unlocking dao.bond.table.unlocked=Bond unlocked +# suppress inspection "UnusedProperty" +dao.bond.bondedRoleState.READY_FOR_LOCKUP=Not bonded yet +# suppress inspection "UnusedProperty" +dao.bond.bondedRoleState.LOCKUP_TX_PENDING=Lockup pending +# suppress inspection "UnusedProperty" +dao.bond.bondedRoleState.LOCKUP_TX_CONFIRMED=Bond locked up +# suppress inspection "UnusedProperty" +dao.bond.bondedRoleState.UNLOCK_TX_PENDING=Unlock pending +# suppress inspection "UnusedProperty" +dao.bond.bondedRoleState.UNLOCK_TX_CONFIRMED=Unlock tx confirmed +# suppress inspection "UnusedProperty" +dao.bond.bondedRoleState.UNLOCKING=Bond unlocking +# suppress inspection "UnusedProperty" +dao.bond.bondedRoleState.UNLOCKED=Bond unlocked + # suppress inspection "UnusedProperty" dao.phase.UNDEFINED=Undefined # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_de.properties b/core/src/main/resources/i18n/displayStrings_de.properties index 0f0bb7b7843..eed8face964 100644 --- a/core/src/main/resources/i18n/displayStrings_de.properties +++ b/core/src/main/resources/i18n/displayStrings_de.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} Blöcke dao.bond.table.header=Gekoppelte Rollen dao.bond.table.column.header.name=Name -dao.bond.table.column.header.linkToAccount=Konto +dao.bond.table.column.header.link=Konto dao.bond.table.column.header.bondedRoleType=Rolle dao.bond.table.column.header.startDate=Gestartet dao.bond.table.column.header.lockupTxId=Sperrung Tx ID diff --git a/core/src/main/resources/i18n/displayStrings_el.properties b/core/src/main/resources/i18n/displayStrings_el.properties index 21d8f8e38b5..21e556b61b9 100644 --- a/core/src/main/resources/i18n/displayStrings_el.properties +++ b/core/src/main/resources/i18n/displayStrings_el.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=Όνομα -dao.bond.table.column.header.linkToAccount=Λογαριασμός +dao.bond.table.column.header.link=Λογαριασμός dao.bond.table.column.header.bondedRoleType=Ρόλος dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID diff --git a/core/src/main/resources/i18n/displayStrings_es.properties b/core/src/main/resources/i18n/displayStrings_es.properties index 8f1f9713097..79fe174a3a2 100644 --- a/core/src/main/resources/i18n/displayStrings_es.properties +++ b/core/src/main/resources/i18n/displayStrings_es.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=Nombre -dao.bond.table.column.header.linkToAccount=Cuenta +dao.bond.table.column.header.link=Cuenta dao.bond.table.column.header.bondedRoleType=Rol dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID diff --git a/core/src/main/resources/i18n/displayStrings_fa.properties b/core/src/main/resources/i18n/displayStrings_fa.properties index fd5e2cbae0c..47ff169df8b 100644 --- a/core/src/main/resources/i18n/displayStrings_fa.properties +++ b/core/src/main/resources/i18n/displayStrings_fa.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=نام -dao.bond.table.column.header.linkToAccount=حساب +dao.bond.table.column.header.link=حساب dao.bond.table.column.header.bondedRoleType=نقش dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID diff --git a/core/src/main/resources/i18n/displayStrings_hu.properties b/core/src/main/resources/i18n/displayStrings_hu.properties index 7cf07cd230d..1c76d6bcd54 100644 --- a/core/src/main/resources/i18n/displayStrings_hu.properties +++ b/core/src/main/resources/i18n/displayStrings_hu.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=Név -dao.bond.table.column.header.linkToAccount=Fiók +dao.bond.table.column.header.link=Fiók dao.bond.table.column.header.bondedRoleType=Szerep dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID diff --git a/core/src/main/resources/i18n/displayStrings_pt.properties b/core/src/main/resources/i18n/displayStrings_pt.properties index 449fc47d532..79f6dfbecc7 100644 --- a/core/src/main/resources/i18n/displayStrings_pt.properties +++ b/core/src/main/resources/i18n/displayStrings_pt.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=Nome -dao.bond.table.column.header.linkToAccount=Conta +dao.bond.table.column.header.link=Conta dao.bond.table.column.header.bondedRoleType=Função dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID diff --git a/core/src/main/resources/i18n/displayStrings_ro.properties b/core/src/main/resources/i18n/displayStrings_ro.properties index e6c829c28c5..9971c0abc00 100644 --- a/core/src/main/resources/i18n/displayStrings_ro.properties +++ b/core/src/main/resources/i18n/displayStrings_ro.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=Nume -dao.bond.table.column.header.linkToAccount=Cont +dao.bond.table.column.header.link=Cont dao.bond.table.column.header.bondedRoleType=Rol dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID diff --git a/core/src/main/resources/i18n/displayStrings_ru.properties b/core/src/main/resources/i18n/displayStrings_ru.properties index 9f405c2aaa5..71a661c1ddc 100644 --- a/core/src/main/resources/i18n/displayStrings_ru.properties +++ b/core/src/main/resources/i18n/displayStrings_ru.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} блоков dao.bond.table.header=Обеспеченные роли dao.bond.table.column.header.name=Имя -dao.bond.table.column.header.linkToAccount=Счёт +dao.bond.table.column.header.link=Счёт dao.bond.table.column.header.bondedRoleType=Роль dao.bond.table.column.header.startDate=Начато dao.bond.table.column.header.lockupTxId=Транз. идент. блокировки diff --git a/core/src/main/resources/i18n/displayStrings_sr.properties b/core/src/main/resources/i18n/displayStrings_sr.properties index 7eea4a6a7f5..57e1984ac85 100644 --- a/core/src/main/resources/i18n/displayStrings_sr.properties +++ b/core/src/main/resources/i18n/displayStrings_sr.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=Ime -dao.bond.table.column.header.linkToAccount=Nalog +dao.bond.table.column.header.link=Nalog dao.bond.table.column.header.bondedRoleType=Uloga dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID diff --git a/core/src/main/resources/i18n/displayStrings_th.properties b/core/src/main/resources/i18n/displayStrings_th.properties index 25888214133..4be351a53fb 100644 --- a/core/src/main/resources/i18n/displayStrings_th.properties +++ b/core/src/main/resources/i18n/displayStrings_th.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=ชื่อ -dao.bond.table.column.header.linkToAccount=บัญชี +dao.bond.table.column.header.link=บัญชี dao.bond.table.column.header.bondedRoleType=บทบาท dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID diff --git a/core/src/main/resources/i18n/displayStrings_vi.properties b/core/src/main/resources/i18n/displayStrings_vi.properties index ccf3b6ee194..5da6984fcaf 100644 --- a/core/src/main/resources/i18n/displayStrings_vi.properties +++ b/core/src/main/resources/i18n/displayStrings_vi.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=Tên -dao.bond.table.column.header.linkToAccount=Tài khoản +dao.bond.table.column.header.link=Tài khoản dao.bond.table.column.header.bondedRoleType=Vai trò dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID diff --git a/core/src/main/resources/i18n/displayStrings_zh.properties b/core/src/main/resources/i18n/displayStrings_zh.properties index fd21a8be074..f74c73e5f09 100644 --- a/core/src/main/resources/i18n/displayStrings_zh.properties +++ b/core/src/main/resources/i18n/displayStrings_zh.properties @@ -1163,7 +1163,7 @@ dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=名称 -dao.bond.table.column.header.linkToAccount=账户 +dao.bond.table.column.header.link=账户 dao.bond.table.column.header.bondedRoleType=角色 dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java index 7f4edd829f7..ad06e0883de 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java @@ -38,7 +38,6 @@ import bisq.network.p2p.P2PService; import bisq.common.app.DevEnv; -import bisq.common.handlers.ResultHandler; import org.bitcoinj.core.Coin; import org.bitcoinj.core.InsufficientMoneyException; @@ -46,9 +45,12 @@ import javax.inject.Inject; import java.util.Optional; +import java.util.function.Consumer; import lombok.extern.slf4j.Slf4j; +import static com.google.common.base.Preconditions.checkArgument; + @Slf4j public class BondingViewUtils { @@ -69,7 +71,7 @@ public BondingViewUtils(P2PService p2PService, WalletsSetup walletsSetup, DaoFac } private void lockupBond(BondWithHash bondWithHash, Coin lockupAmount, int lockupTime, LockupType lockupType, - ResultHandler resultHandler) { + Consumer resultHandler) { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { if (!DevEnv.isDevMode()) { new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) @@ -89,41 +91,38 @@ private void lockupBond(BondWithHash bondWithHash, Coin lockupAmount, int lockup } } - private void publishLockupTx(BondWithHash bondWithHash, Coin lockupAmount, int lockupTime, LockupType lockupType, ResultHandler resultHandler) { + private void publishLockupTx(BondWithHash bondWithHash, Coin lockupAmount, int lockupTime, LockupType lockupType, Consumer resultHandler) { daoFacade.publishLockupTx(lockupAmount, lockupTime, lockupType, bondWithHash, - () -> { + txId -> { if (!DevEnv.isDevMode()) new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); + + if (resultHandler != null) + resultHandler.accept(txId); }, this::handleError ); - if (resultHandler != null) - resultHandler.handleResult(); } - public void lockupBondForBondedRole(Role role, ResultHandler resultHandler) { + public void lockupBondForBondedRole(Role role, Consumer resultHandler) { BondedRoleType bondedRoleType = role.getBondedRoleType(); Coin lockupAmount = Coin.valueOf(bondedRoleType.getRequiredBond()); int lockupTime = bondedRoleType.getUnlockTimeInBlocks(); lockupBond(role, lockupAmount, lockupTime, LockupType.BONDED_ROLE, resultHandler); } - public void lockupBondForReputation(Coin lockupAmount, int lockupTime, ResultHandler resultHandler) { + public void lockupBondForReputation(Coin lockupAmount, int lockupTime, Consumer resultHandler) { BondedReputation bondedReputation = BondedReputation.createBondedReputation(); lockupBond(bondedReputation, lockupAmount, lockupTime, LockupType.REPUTATION, resultHandler); } - public void unLock(String lockupTxId, ResultHandler resultHandler) { + public void unLock(String lockupTxId, Consumer resultHandler) { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { Optional lockupTxOutput = daoFacade.getLockupTxOutput(lockupTxId); - if (!lockupTxOutput.isPresent()) { - log.warn("Lockup output not found, txId = ", lockupTxId); - return; - } - + checkArgument(lockupTxOutput.isPresent(), "Lockup output must be present. TxId=" + lockupTxId); Coin unlockAmount = Coin.valueOf(lockupTxOutput.get().getValue()); Optional opLockTime = daoFacade.getLockTime(lockupTxId); int lockTime = opLockTime.orElse(-1); @@ -153,13 +152,14 @@ public void unLock(String lockupTxId, ResultHandler resultHandler) { log.info("unlock tx: {}", lockupTxId); } - private void publishUnlockTx(String lockupTxId, ResultHandler resultHandler) { + private void publishUnlockTx(String lockupTxId, Consumer resultHandler) { daoFacade.publishUnlockTx(lockupTxId, - () -> { + txId -> { if (!DevEnv.isDevMode()) new Popup<>().confirmation(Res.get("dao.tx.published.success")).show(); - resultHandler.handleResult(); + if (resultHandler != null) + resultHandler.accept(txId); }, errorMessage -> new Popup<>().warning(errorMessage.toString()).show() ); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java index fe4122b1d22..e9f6e21fa57 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.java @@ -150,7 +150,7 @@ public LockupType fromString(String string) { bondedRolesComboBox.setVisible(true); lockupRows++; - bondedRolesComboBox.setItems(FXCollections.observableArrayList(daoFacade.getBondedRoleStates())); + bondedRolesComboBox.setItems(FXCollections.observableArrayList(daoFacade.getBondedRoles())); } else { bondedRolesComboBox.setVisible(false); bondedRolesComboBox.getItems().clear(); @@ -199,13 +199,13 @@ public BondedRole fromString(String string) { case BONDED_ROLE: if (bondedRolesComboBox.getValue() != null) { bondingViewUtils.lockupBondForBondedRole(bondedRolesComboBox.getValue().getRole(), - () -> bondedRolesComboBox.getSelectionModel().clearSelection()); + txId -> bondedRolesComboBox.getSelectionModel().clearSelection()); } break; case REPUTATION: bondingViewUtils.lockupBondForReputation(bsqFormatter.parseToCoin(amountInputTextField.getText()), Integer.parseInt(timeInputTextField.getText()), - () -> { + txId -> { amountInputTextField.setText(""); timeInputTextField.setText(""); }); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java index e8aa1504c83..5c69303ef93 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java @@ -18,9 +18,11 @@ package bisq.desktop.main.dao.bonding.roles; import bisq.desktop.components.AutoTooltipButton; +import bisq.desktop.main.dao.bonding.BondingViewUtils; import bisq.core.dao.DaoFacade; import bisq.core.dao.governance.bond.BondedRole; +import bisq.core.dao.governance.bond.BondedRoleState; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.model.blockchain.Block; import bisq.core.dao.state.model.governance.Role; @@ -31,37 +33,65 @@ import java.util.Date; -import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; @Slf4j @EqualsAndHashCode -@Data class BondedRolesListItem implements DaoStateListener { + @Getter private final BondedRole bondedRole; private final DaoFacade daoFacade; + private final BondingViewUtils bondingViewUtils; private final BsqFormatter bsqFormatter; + @Getter private final AutoTooltipButton button; + @Getter private final Label label; + @Getter private final Role role; + private final boolean isMyRole; + BondedRolesListItem(BondedRole bondedRole, DaoFacade daoFacade, + BondingViewUtils bondingViewUtils, BsqFormatter bsqFormatter) { this.bondedRole = bondedRole; this.daoFacade = daoFacade; + this.bondingViewUtils = bondingViewUtils; this.bsqFormatter = bsqFormatter; role = bondedRole.getRole(); + isMyRole = daoFacade.isMyRole(bondedRole.getRole()); daoFacade.addBsqStateListener(this); button = new AutoTooltipButton(); button.setMinWidth(70); - label = new Label(); + button.setOnAction(e -> { + if (bondedRole.getBondedRoleState() == BondedRoleState.READY_FOR_LOCKUP) { + bondingViewUtils.lockupBondForBondedRole(role, + txId -> { + bondedRole.setLockupTxId(txId); + bondedRole.setBondedRoleState(BondedRoleState.LOCKUP_TX_PENDING); + update(); + button.setDisable(true); + }); + } else if (bondedRole.getBondedRoleState() == BondedRoleState.LOCKUP_TX_CONFIRMED) { + bondingViewUtils.unLock(bondedRole.getLockupTxId(), + txId -> { + bondedRole.setUnlockTxId(txId); + bondedRole.setBondedRoleState(BondedRoleState.UNLOCK_TX_PENDING); + update(); + button.setDisable(true); + }); + } + }); + update(); } @@ -79,48 +109,27 @@ public String getRevokeDate() { public void cleanup() { daoFacade.removeBsqStateListener(this); - setOnAction(null); - } - - public void setOnAction(Runnable handler) { - button.setOnAction(e -> handler.run()); + button.setOnAction(null); } - public boolean isBonded() { - return bondedRole.isLockedUp(); - } private void update() { - // We have following state: - // 1. Not bonded: !isLockedUp, !isUnlocked, !isUnlocking: notBonded - // 2. Locked up: isLockedUp, !isUnlocked, !isUnlocking: lockedUp - // 3. Unlocking: isLockedUp, isUnlocked, isUnlocking: unlocking - // 4. Unlocked: isLockedUp, isUnlocked, !isUnlocking: unlocked - - boolean isLockedUp = bondedRole.isLockedUp(); - boolean isUnlocked = bondedRole.isUnlocked(); - boolean isUnlocking = bondedRole.isUnlocking(); - - String text; - if (!isLockedUp) - text = Res.get("dao.bond.table.notBonded"); - else if (!isUnlocked) - text = Res.get("dao.bond.table.lockedUp"); - else if (isUnlocking) - text = Res.get("dao.bond.table.unlocking"); - else - text = Res.get("dao.bond.table.unlocked"); - - label.setText(text); - - button.updateText(isLockedUp ? Res.get("dao.bond.table.button.revoke") : Res.get("dao.bond.table.button.lockup")); - button.setVisible(!isLockedUp || !isUnlocked); - button.setManaged(button.isVisible()); - - //TODO listen to unconfirmed txs and update button and label state - } + label.setText(Res.get("dao.bond.bondedRoleState." + bondedRole.getBondedRoleState().name())); + + log.error("bondedRole.getLockupTxId()={}, bondedRole.getBondedRoleState()={}", bondedRole.getLockupTxId(), bondedRole.getBondedRoleState()); + boolean showLockup = bondedRole.getBondedRoleState() == BondedRoleState.READY_FOR_LOCKUP; + boolean showRevoke = bondedRole.getBondedRoleState() == BondedRoleState.LOCKUP_TX_CONFIRMED; + if (showLockup) + button.updateText(Res.get("dao.bond.table.button.lockup")); + else if (showRevoke) + button.updateText(Res.get("dao.bond.table.button.revoke")); + boolean showButton = isMyRole && (showLockup || showRevoke); + button.setVisible(showButton); + button.setManaged(showButton); + } + // DaoStateListener @Override public void onNewBlockHeight(int blockHeight) { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java index 895ca539502..09134020717 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java @@ -153,8 +153,8 @@ public void onParseBlockChainComplete() { private void updateList() { observableList.forEach(BondedRolesListItem::cleanup); - observableList.setAll(daoFacade.getBondedRoleStates().stream() - .map(bondedRoleState -> new BondedRolesListItem(bondedRoleState, daoFacade, bsqFormatter)) + observableList.setAll(daoFacade.getBondedRoles().stream() + .map(bondedRole -> new BondedRolesListItem(bondedRole, daoFacade, bondingViewUtils, bsqFormatter)) .collect(Collectors.toList())); } @@ -195,7 +195,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.linkToAccount")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.link")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(60); column.setCellFactory( @@ -315,7 +315,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockupTxId")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(60); + column.setMinWidth(80); column.setCellFactory( new Callback, TableCell>() { @@ -357,7 +357,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.unlockTxId")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(60); + column.setMinWidth(80); column.setCellFactory( new Callback, TableCell>() { @@ -447,16 +447,6 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { if (item != null && !empty) { if (button == null) { button = item.getButton(); - item.setOnAction(() -> { - if (item.isBonded()) - bondingViewUtils.unLock(item.getBondedRole().getLockupTxId(), - () -> { - // TODO - button.setDisable(true); - }); - else - bondingViewUtils.lockupBondForBondedRole(item.getRole(), null); - }); setGraphic(button); } } else { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java index 93c6287ca84..7544c57b0b2 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.java @@ -397,7 +397,7 @@ public void updateItem(final LockupTxListItem item, boolean empty) { if (item != null && !empty) { if (button == null) { button = item.getButton(); - button.setOnAction(e -> bondingViewUtils.unLock(item.getTxId(), () -> { + button.setOnAction(e -> bondingViewUtils.unLock(item.getTxId(), txId -> { //TODO button.setDisable(true); })); From e7daaae9eed866b47b24b83f5221ed39b41c70cb Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 2 Nov 2018 16:11:56 -0500 Subject: [PATCH 16/27] Rename lockupViews to ReputationView - To avoid that we handle lockup/unlock 2 times in the view we will remove the generic options (upcoming commits...) --- .../desktop/main/dao/bonding/BondingView.java | 6 +++--- .../ReputationView.fxml} | 2 +- .../ReputationView.java} | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) rename desktop/src/main/java/bisq/desktop/main/dao/bonding/{lockup/LockupView.fxml => reputation/ReputationView.fxml} (97%) rename desktop/src/main/java/bisq/desktop/main/dao/bonding/{lockup/LockupView.java => reputation/ReputationView.java} (96%) diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index 973464a6920..58cd56fbd26 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -28,7 +28,7 @@ import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.bonding.dashboard.BondingDashboardView; -import bisq.desktop.main.dao.bonding.lockup.LockupView; +import bisq.desktop.main.dao.bonding.reputation.ReputationView; import bisq.desktop.main.dao.bonding.roles.BondedRolesView; import bisq.desktop.main.dao.bonding.unlock.UnlockView; @@ -86,7 +86,7 @@ public void initialize() { bondedRoles = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.bondedRoles"), BondedRolesView.class, AwesomeIcon.SHIELD, baseNavPath); lockupBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.lockupBSQ"), - LockupView.class, AwesomeIcon.LOCK, baseNavPath); + ReputationView.class, AwesomeIcon.LOCK, baseNavPath); unlockBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.unlockBSQ"), UnlockView.class, AwesomeIcon.UNLOCK, baseNavPath); @@ -131,7 +131,7 @@ private void loadView(Class viewClass) { if (view instanceof BondingDashboardView) dashboard.setSelected(true); else if (view instanceof BondedRolesView) bondedRoles.setSelected(true); - else if (view instanceof LockupView) lockupBSQ.setSelected(true); + else if (view instanceof ReputationView) lockupBSQ.setSelected(true); else if (view instanceof UnlockView) unlockBSQ.setSelected(true); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.fxml b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.fxml similarity index 97% rename from desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.fxml rename to desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.fxml index 451bf1d6e77..869dfe78c70 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/lockup/LockupView.fxml +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.fxml @@ -21,7 +21,7 @@ -. */ -package bisq.desktop.main.dao.bonding.lockup; +package bisq.desktop.main.dao.bonding.reputation; import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; @@ -59,7 +59,7 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class LockupView extends ActivatableView implements BsqBalanceListener { +public class ReputationView extends ActivatableView implements BsqBalanceListener { private final BsqWalletService bsqWalletService; private final BsqFormatter bsqFormatter; private final BsqBalanceUtil bsqBalanceUtil; @@ -86,12 +86,12 @@ public class LockupView extends ActivatableView implements BsqBa /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private LockupView(BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BsqBalanceUtil bsqBalanceUtil, - BondingViewUtils bondingViewUtils, - BsqValidator bsqValidator, - DaoFacade daoFacade) { + private ReputationView(BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BsqBalanceUtil bsqBalanceUtil, + BondingViewUtils bondingViewUtils, + BsqValidator bsqValidator, + DaoFacade daoFacade) { this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; this.bsqBalanceUtil = bsqBalanceUtil; From 15b8f02c67ae3db348af3cf4e82cef9e8e964b93 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Fri, 2 Nov 2018 19:31:31 -0500 Subject: [PATCH 17/27] Work on bonded reputation (WIP) --- common/src/main/proto/pb.proto | 12 +- .../core/app/misc/AppSetupWithP2PAndDAO.java | 2 +- .../main/java/bisq/core/dao/DaoFacade.java | 20 +- .../main/java/bisq/core/dao/DaoModule.java | 8 +- .../BondConsensus.java} | 9 +- .../{BondedRoleState.java => BondState.java} | 4 +- .../{bonding => }/bond/BondWithHash.java | 2 +- .../lockup/LockupService.java | 25 ++- .../{bonding => bond}/lockup/LockupType.java | 2 +- .../bond/reputation/BondedReputation.java | 70 +++++++ .../reputation}/BondedReputationService.java | 79 +++----- .../bond/reputation/Reputation.java | 76 ++++++++ .../reputation/ReputationList.java} | 30 +-- .../bond/{ => role}/BondedRole.java | 5 +- .../bond/{ => role}/BondedRolesService.java | 127 ++++++------ .../unlock/UnlockService.java | 2 +- .../bonding/bond/BondedReputation.java | 150 -------------- .../voteresult/VoteResultService.java | 2 +- .../core/dao/node/parser/OpReturnParser.java | 12 +- .../core/dao/node/parser/TxOutputParser.java | 4 +- .../bisq/core/dao/state/DaoStateService.java | 6 +- .../core/dao/state/model/governance/Role.java | 2 +- .../core/setup/CorePersistedDataHost.java | 2 +- .../util/validation/HexStringValidator.java | 46 +++++ .../resources/i18n/displayStrings.properties | 20 +- .../i18n/displayStrings_de.properties | 4 +- .../i18n/displayStrings_el.properties | 4 +- .../i18n/displayStrings_es.properties | 4 +- .../i18n/displayStrings_fa.properties | 4 +- .../i18n/displayStrings_hu.properties | 4 +- .../i18n/displayStrings_pt.properties | 4 +- .../i18n/displayStrings_ro.properties | 4 +- .../i18n/displayStrings_ru.properties | 4 +- .../i18n/displayStrings_sr.properties | 4 +- .../i18n/displayStrings_th.properties | 4 +- .../i18n/displayStrings_vi.properties | 4 +- .../i18n/displayStrings_zh.properties | 4 +- .../desktop/main/dao/bonding/BondingView.java | 24 +-- .../main/dao/bonding/BondingViewUtils.java | 12 +- .../BondListItem.java} | 28 +-- .../UnlockView.fxml => bonds/BondsView.fxml} | 2 +- .../UnlockView.java => bonds/BondsView.java} | 100 +++++----- .../bonding/reputation/ReputationView.java | 184 ++++++------------ .../bonding/roles/BondedRolesListItem.java | 19 +- 44 files changed, 541 insertions(+), 593 deletions(-) rename core/src/main/java/bisq/core/dao/governance/{bonding/BondingConsensus.java => bond/BondConsensus.java} (91%) rename core/src/main/java/bisq/core/dao/governance/bond/{BondedRoleState.java => BondState.java} (92%) rename core/src/main/java/bisq/core/dao/governance/{bonding => }/bond/BondWithHash.java (94%) rename core/src/main/java/bisq/core/dao/governance/{bonding => bond}/lockup/LockupService.java (80%) rename core/src/main/java/bisq/core/dao/governance/{bonding => bond}/lockup/LockupType.java (96%) create mode 100644 core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java rename core/src/main/java/bisq/core/dao/governance/{bonding/bond => bond/reputation}/BondedReputationService.java (67%) create mode 100644 core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java rename core/src/main/java/bisq/core/dao/governance/{bonding/bond/BondedReputationList.java => bond/reputation/ReputationList.java} (60%) rename core/src/main/java/bisq/core/dao/governance/bond/{ => role}/BondedRole.java (89%) rename core/src/main/java/bisq/core/dao/governance/bond/{ => role}/BondedRolesService.java (85%) rename core/src/main/java/bisq/core/dao/governance/{bonding => bond}/unlock/UnlockService.java (98%) delete mode 100644 core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputation.java create mode 100644 core/src/main/java/bisq/core/util/validation/HexStringValidator.java rename desktop/src/main/java/bisq/desktop/main/dao/bonding/{unlock/LockupTxListItem.java => bonds/BondListItem.java} (87%) rename desktop/src/main/java/bisq/desktop/main/dao/bonding/{unlock/UnlockView.fxml => bonds/BondsView.fxml} (98%) rename desktop/src/main/java/bisq/desktop/main/dao/bonding/{unlock/UnlockView.java => bonds/BondsView.java} (78%) diff --git a/common/src/main/proto/pb.proto b/common/src/main/proto/pb.proto index 91af8cb1ab7..7191d23925b 100644 --- a/common/src/main/proto/pb.proto +++ b/common/src/main/proto/pb.proto @@ -943,7 +943,7 @@ message PersistableEnvelope { MeritList merit_list = 23; RemovedAssetList removed_asset_list = 24; DaoStateStore dao_state_store = 25; - BondedReputationList bonded_reputation_list = 26; + ReputationList reputation_list = 26; } } @@ -1546,14 +1546,12 @@ message Role { string bonded_role_type = 4; // name of BondedRoleType enum } -message BondedReputation { - string salt = 1; - string lockup_tx_id = 2; - string unlock_tx_id = 3; +message Reputation { + bytes salt = 1; } -message BondedReputationList { - repeated BondedReputation bonded_reputation = 1; +message ReputationList { + repeated Reputation reputation = 1; } message TempProposalPayload { diff --git a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java index e45c235dfab..0ac2aa50a59 100644 --- a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java +++ b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java @@ -22,7 +22,7 @@ import bisq.core.dao.governance.asset.AssetService; import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; -import bisq.core.dao.governance.bonding.bond.BondedReputationService; +import bisq.core.dao.governance.bond.reputation.BondedReputationService; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.proposal.MyProposalListService; import bisq.core.filter.FilterManager; diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index 4dbed2c7ca8..2cc21777d5d 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -24,14 +24,14 @@ import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.BlindVoteConsensus; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; -import bisq.core.dao.governance.bond.BondedRole; -import bisq.core.dao.governance.bond.BondedRolesService; -import bisq.core.dao.governance.bonding.bond.BondWithHash; -import bisq.core.dao.governance.bonding.bond.BondedReputation; -import bisq.core.dao.governance.bonding.bond.BondedReputationService; -import bisq.core.dao.governance.bonding.lockup.LockupService; -import bisq.core.dao.governance.bonding.lockup.LockupType; -import bisq.core.dao.governance.bonding.unlock.UnlockService; +import bisq.core.dao.governance.bond.BondWithHash; +import bisq.core.dao.governance.bond.lockup.LockupService; +import bisq.core.dao.governance.bond.lockup.LockupType; +import bisq.core.dao.governance.bond.reputation.BondedReputation; +import bisq.core.dao.governance.bond.reputation.BondedReputationService; +import bisq.core.dao.governance.bond.role.BondedRole; +import bisq.core.dao.governance.bond.role.BondedRolesService; +import bisq.core.dao.governance.bond.unlock.UnlockService; import bisq.core.dao.governance.myvote.MyVote; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.param.Param; @@ -286,8 +286,8 @@ public Collection getBondedRoles() { return bondedRolesService.getBondedRoles(); } - public List getBondedReputationList() { - return bondedReputationService.getBondedReputationList(); + public List getReputationList() { + return bondedReputationService.getReputationList(); } // Show fee diff --git a/core/src/main/java/bisq/core/dao/DaoModule.java b/core/src/main/java/bisq/core/dao/DaoModule.java index b2317928f0f..90d7af1ca29 100644 --- a/core/src/main/java/bisq/core/dao/DaoModule.java +++ b/core/src/main/java/bisq/core/dao/DaoModule.java @@ -26,10 +26,10 @@ import bisq.core.dao.governance.blindvote.network.RepublishGovernanceDataHandler; import bisq.core.dao.governance.blindvote.storage.BlindVoteStorageService; import bisq.core.dao.governance.blindvote.storage.BlindVoteStore; -import bisq.core.dao.governance.bond.BondedRolesService; -import bisq.core.dao.governance.bonding.bond.BondedReputationService; -import bisq.core.dao.governance.bonding.lockup.LockupService; -import bisq.core.dao.governance.bonding.unlock.UnlockService; +import bisq.core.dao.governance.bond.lockup.LockupService; +import bisq.core.dao.governance.bond.reputation.BondedReputationService; +import bisq.core.dao.governance.bond.role.BondedRolesService; +import bisq.core.dao.governance.bond.unlock.UnlockService; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.period.CycleService; import bisq.core.dao.governance.period.PeriodService; diff --git a/core/src/main/java/bisq/core/dao/governance/bonding/BondingConsensus.java b/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java similarity index 91% rename from core/src/main/java/bisq/core/dao/governance/bonding/BondingConsensus.java rename to core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java index 1c1c33390e6..3fc1d8c9b13 100644 --- a/core/src/main/java/bisq/core/dao/governance/bonding/BondingConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java @@ -15,10 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.bonding; +package bisq.core.dao.governance.bond; -import bisq.core.dao.governance.bonding.bond.BondWithHash; -import bisq.core.dao.governance.bonding.lockup.LockupType; +import bisq.core.dao.governance.bond.lockup.LockupType; import bisq.core.dao.state.model.blockchain.OpReturnType; import bisq.common.app.Version; @@ -34,7 +33,7 @@ import lombok.extern.slf4j.Slf4j; @Slf4j -public class BondingConsensus { +public class BondConsensus { // In the UI we don't allow 0 as that would mean that the tx gets spent // in the same block as the unspent tx and we don't support unconfirmed txs in the DAO. Technically though 0 // works as well. @@ -74,7 +73,7 @@ public static int getLockTime(byte[] opReturnData) { } public static boolean isLockTimeInValidRange(int lockTime) { - return lockTime >= BondingConsensus.getMinLockTime() && lockTime <= BondingConsensus.getMaxLockTime(); + return lockTime >= BondConsensus.getMinLockTime() && lockTime <= BondConsensus.getMaxLockTime(); } public static Optional getLockupType(byte[] opReturnData) { diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondedRoleState.java b/core/src/main/java/bisq/core/dao/governance/bond/BondState.java similarity index 92% rename from core/src/main/java/bisq/core/dao/governance/bond/BondedRoleState.java rename to core/src/main/java/bisq/core/dao/governance/bond/BondState.java index f6ddd65042f..aaf06b181a7 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondedRoleState.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondState.java @@ -17,8 +17,8 @@ package bisq.core.dao.governance.bond; -// Used in string properties ("dao.bond.bondedRoleState.*") -public enum BondedRoleState { +// Used in string properties ("dao.bond.bondState.*") +public enum BondState { READY_FOR_LOCKUP, // Accepted by voting but no lockup tx made yet. LOCKUP_TX_PENDING, // Tx broadcasted but not confirmed. Used only by tx publisher. LOCKUP_TX_CONFIRMED, diff --git a/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondWithHash.java b/core/src/main/java/bisq/core/dao/governance/bond/BondWithHash.java similarity index 94% rename from core/src/main/java/bisq/core/dao/governance/bonding/bond/BondWithHash.java rename to core/src/main/java/bisq/core/dao/governance/bond/BondWithHash.java index 12c91d5accb..592d6f69c7a 100644 --- a/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondWithHash.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondWithHash.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.bonding.bond; +package bisq.core.dao.governance.bond; public interface BondWithHash { byte[] getHash(); diff --git a/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupService.java b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java similarity index 80% rename from core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupService.java rename to core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java index 04e75e57ca5..c183c9b602f 100644 --- a/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.bonding.lockup; +package bisq.core.dao.governance.bond.lockup; import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.TxBroadcastException; @@ -25,9 +25,11 @@ import bisq.core.btc.wallet.BtcWalletService; import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsManager; -import bisq.core.dao.governance.bond.BondedRolesService; -import bisq.core.dao.governance.bonding.BondingConsensus; -import bisq.core.dao.governance.bonding.bond.BondWithHash; +import bisq.core.dao.governance.bond.BondConsensus; +import bisq.core.dao.governance.bond.BondWithHash; +import bisq.core.dao.governance.bond.reputation.BondedReputationService; +import bisq.core.dao.governance.bond.reputation.Reputation; +import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.state.model.governance.Role; import bisq.common.handlers.ExceptionHandler; @@ -51,6 +53,7 @@ public class LockupService { private final WalletsManager walletsManager; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; + private final BondedReputationService bondedReputationService; private final BondedRolesService bondedRolesService; @@ -62,29 +65,33 @@ public class LockupService { public LockupService(WalletsManager walletsManager, BsqWalletService bsqWalletService, BtcWalletService btcWalletService, + BondedReputationService bondedReputationService, BondedRolesService bondedRolesService) { this.walletsManager = walletsManager; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; + this.bondedReputationService = bondedReputationService; this.bondedRolesService = bondedRolesService; } public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, BondWithHash bondWithHash, Consumer resultHandler, ExceptionHandler exceptionHandler) { - checkArgument(lockTime <= BondingConsensus.getMaxLockTime() && - lockTime >= BondingConsensus.getMinLockTime(), "lockTime not in rage"); + checkArgument(lockTime <= BondConsensus.getMaxLockTime() && + lockTime >= BondConsensus.getMinLockTime(), "lockTime not in rage"); if (bondWithHash instanceof Role) { Role role = (Role) bondWithHash; if (bondedRolesService.wasRoleAlreadyBonded(role)) { exceptionHandler.handleException(new RuntimeException("The role has been used already for a lockup tx.")); return; } + } else if (bondWithHash instanceof Reputation) { + bondedReputationService.addReputation((Reputation) bondWithHash); } - byte[] hash = BondingConsensus.getHash(bondWithHash); + byte[] hash = BondConsensus.getHash(bondWithHash); try { - byte[] opReturnData = BondingConsensus.getLockupOpReturnData(lockTime, lockupType, hash); - final Transaction lockupTx = createLockupTx(lockupAmount, opReturnData); + byte[] opReturnData = BondConsensus.getLockupOpReturnData(lockTime, lockupType, hash); + Transaction lockupTx = createLockupTx(lockupAmount, opReturnData); //noinspection Duplicates walletsManager.publishAndCommitBsqTx(lockupTx, new TxBroadcaster.Callback() { diff --git a/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupType.java b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupType.java similarity index 96% rename from core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupType.java rename to core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupType.java index cebc0084d68..914ad31be6f 100644 --- a/core/src/main/java/bisq/core/dao/governance/bonding/lockup/LockupType.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupType.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.bonding.lockup; +package bisq.core.dao.governance.bond.lockup; import bisq.core.locale.Res; diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java new file mode 100644 index 00000000000..f2f09d65ec0 --- /dev/null +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java @@ -0,0 +1,70 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.governance.bond.reputation; + +import bisq.core.locale.Res; + +import lombok.Getter; +import lombok.Setter; + +import javax.annotation.Nullable; + +/** + * Wrapper for reputation which contains the mutable state of a bonded reputation. Only kept in memory. + */ +@Getter +public final class BondedReputation { + private final Reputation reputation; + @Nullable + @Setter + private String lockupTxId; + @Nullable + @Setter + private String unlockTxId; + + public BondedReputation(Reputation reputation) { + this.reputation = reputation; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + public String getDisplayString() { + return Res.get("dao.bond.bondedReputation"); + } + + public boolean isLockedUp() { + return lockupTxId != null; + } + + public boolean isUnlocked() { + return unlockTxId != null; + } + + + @Override + public String toString() { + return "BondedReputation{" + + "\n reputation='" + reputation + '\'' + + ",\n lockupTxId='" + lockupTxId + '\'' + + ",\n unlockTxId='" + unlockTxId + '\'' + + "\n}"; + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java similarity index 67% rename from core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationService.java rename to core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java index 0d4bfa96c9d..5ba76a7ae42 100644 --- a/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java @@ -15,22 +15,19 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.bonding.bond; +package bisq.core.dao.governance.bond.reputation; import bisq.core.app.BisqEnvironment; -import bisq.core.dao.governance.bonding.BondingConsensus; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.model.blockchain.Block; -import bisq.core.dao.state.model.blockchain.SpentInfo; -import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.proto.persistable.PersistedDataHost; import bisq.common.storage.Storage; import javax.inject.Inject; -import java.util.Arrays; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.concurrent.CopyOnWriteArrayList; @@ -41,16 +38,16 @@ @Slf4j public class BondedReputationService implements PersistedDataHost, DaoStateListener { - public interface BondedReputationListChangeListener { - void onListChanged(List list); + public interface ReputationListChangeListener { + void onListChanged(List list); } private final DaoStateService daoStateService; - private final Storage storage; - private final BondedReputationList bondedReputationList = new BondedReputationList(); + private final Storage storage; + private final ReputationList reputationList = new ReputationList(); @Getter - private final List listeners = new CopyOnWriteArrayList<>(); + private final List listeners = new CopyOnWriteArrayList<>(); /////////////////////////////////////////////////////////////////////////////////////////// @@ -58,7 +55,7 @@ public interface BondedReputationListChangeListener { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public BondedReputationService(Storage storage, DaoStateService daoStateService) { + public BondedReputationService(Storage storage, DaoStateService daoStateService) { this.storage = storage; this.daoStateService = daoStateService; @@ -73,11 +70,11 @@ public BondedReputationService(Storage storage, DaoStateSe @Override public void readPersisted() { if (BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq()) { - BondedReputationList persisted = storage.initAndGetPersisted(bondedReputationList, 100); + ReputationList persisted = storage.initAndGetPersisted(reputationList, 100); if (persisted != null) { - bondedReputationList.clear(); - bondedReputationList.addAll(persisted.getList()); - listeners.forEach(l -> l.onListChanged(bondedReputationList.getList())); + reputationList.clear(); + reputationList.addAll(persisted.getList()); + listeners.forEach(l -> l.onListChanged(reputationList.getList())); } } } @@ -92,13 +89,13 @@ public void onNewBlockHeight(int blockHeight) { @Override public void onParseTxsComplete(Block block) { - bondedReputationList.getList().forEach(bondedReputation -> { + /* bondedReputationList.getList().forEach(bondedReputation -> { daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> { String lockupTxId = lockupTxOutput.getTxId(); daoStateService.getTx(lockupTxId) .ifPresent(lockupTx -> { byte[] opReturnData = lockupTx.getLastTxOutput().getOpReturnData(); - byte[] hash = BondingConsensus.getHashFromOpReturnData(opReturnData); + byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); Optional candidate = getBondedReputationFromHash(hash); if (candidate.isPresent() && bondedReputation.equals(candidate.get())) { if (bondedReputation.getLockupTxId() == null) { @@ -125,7 +122,7 @@ public void onParseTxsComplete(Block block) { } }); }); - }); + });*/ } @Override @@ -140,39 +137,35 @@ public void onParseBlockChainComplete() { public void start() { } - public void addListener(BondedReputationListChangeListener listener) { + public void addListener(ReputationListChangeListener listener) { listeners.add(listener); } -// public void addAcceptedBondedReputation(BondedReputation bondedReputation) { -// if (bondedReputationList.getList().stream().noneMatch(role -> role.equals(bondedReputation))) { -// bondedReputationList.add(bondedReputation); -// persist(); -// listeners.forEach(l -> l.onListChanged(bondedReputationList.getList())); -// } -// } - - public List getBondedReputationList() { - return bondedReputationList.getList(); + public void addReputation(Reputation reputation) { + if (!reputationList.contains(reputation)) { + reputationList.add(reputation); + persist(); + } } - /* public List getValidBondedReputationList() { - //TODO validation ??? - return bondedReputationList.getList(); - }*/ + public List getReputationList() { + return new ArrayList<>(); //bondedReputationList.getList(); + } public Optional getBondedReputationFromHash(byte[] hash) { + return Optional.empty(); + /* return bondedReputationList.getList().stream() .filter(bondedReputation -> { byte[] candidateHash = bondedReputation.getHash(); - /* log.error("getBondedReputationFromHash: equals?={}, hash={}, candidateHash={}\bondedReputation={}", + *//* log.error("getBondedReputationFromHash: equals?={}, hash={}, candidateHash={}\bondedReputation={}", Arrays.equals(candidateHash, hash), Utilities.bytesAsHexString(hash), Utilities.bytesAsHexString(candidateHash), - bondedReputation.toString());*/ + bondedReputation.toString());*//* return Arrays.equals(candidateHash, hash); }) - .findAny(); + .findAny();*/ } /////////////////////////////////////////////////////////////////////////////////////////// @@ -182,18 +175,4 @@ public Optional getBondedReputationFromHash(byte[] hash) { private void persist() { storage.queueUpForSave(20); } - - - /*public static Optional getBondedReputationByLockupTxId(String lockupTxId) { - return BondedReputations.stream() - .filter(BondedReputation -> BondedReputation.getLockupTxId().equals(lockupTxId)). - findAny(); - }*/ - - /* public static Optional getBondedReputationByHashOfBondId(byte[] hash) { - return Optional.empty(); - *//* BondedReputations.stream() - .filter(BondedReputation -> Arrays.equals(BondedReputation.getHash(), hash)) - .findAny();*//* - }*/ } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java new file mode 100644 index 00000000000..f44f40a361d --- /dev/null +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java @@ -0,0 +1,76 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.governance.bond.reputation; + +import bisq.core.dao.governance.bond.BondWithHash; + +import bisq.common.crypto.Hash; +import bisq.common.proto.network.NetworkPayload; +import bisq.common.proto.persistable.PersistablePayload; +import bisq.common.util.Utilities; + +import io.bisq.generated.protobuffer.PB; + +import com.google.protobuf.ByteString; + +import lombok.Value; + +import javax.annotation.concurrent.Immutable; + +@Immutable +@Value +public final class Reputation implements PersistablePayload, NetworkPayload, BondWithHash { + private final byte[] salt; + + public Reputation(byte[] salt) { + this.salt = salt; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public PB.Reputation toProtoMessage() { + PB.Reputation.Builder builder = PB.Reputation.newBuilder() + .setSalt(ByteString.copyFrom(salt)); + return builder.build(); + } + + public static Reputation fromProto(PB.Reputation proto) { + return new Reputation(proto.getSalt().toByteArray()); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public byte[] getHash() { + return Hash.getSha256Ripemd160hash(salt); + } + + @Override + public String toString() { + return "Reputation{" + + "\n salt=" + Utilities.bytesAsHexString(salt) + + "\n}"; + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationList.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/ReputationList.java similarity index 60% rename from core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationList.java rename to core/src/main/java/bisq/core/dao/governance/bond/reputation/ReputationList.java index aff6d349f43..88c88cf08f9 100644 --- a/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputationList.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/ReputationList.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.bonding.bond; +package bisq.core.dao.governance.bond.reputation; import bisq.common.proto.persistable.PersistableList; @@ -28,16 +28,16 @@ import lombok.EqualsAndHashCode; /** - * PersistableEnvelope wrapper for list of BondedReputations. + * PersistableEnvelope wrapper for list of Reputations. */ @EqualsAndHashCode(callSuper = true) -public class BondedReputationList extends PersistableList { +public class ReputationList extends PersistableList { - public BondedReputationList(List list) { + public ReputationList(List list) { super(list); } - public BondedReputationList() { + public ReputationList() { super(); } @@ -48,26 +48,26 @@ public BondedReputationList() { @Override public PB.PersistableEnvelope toProtoMessage() { - return PB.PersistableEnvelope.newBuilder().setBondedReputationList(getBuilder()).build(); + return PB.PersistableEnvelope.newBuilder().setReputationList(getBuilder()).build(); } - public PB.BondedReputationList.Builder getBuilder() { - return PB.BondedReputationList.newBuilder() - .addAllBondedReputation(getList().stream() - .map(BondedReputation::toProtoMessage) + public PB.ReputationList.Builder getBuilder() { + return PB.ReputationList.newBuilder() + .addAllReputation(getList().stream() + .map(Reputation::toProtoMessage) .collect(Collectors.toList())); } - public static BondedReputationList fromProto(PB.BondedReputationList proto) { - return new BondedReputationList(new ArrayList<>(proto.getBondedReputationList().stream() - .map(BondedReputation::fromProto) + public static ReputationList fromProto(PB.ReputationList proto) { + return new ReputationList(new ArrayList<>(proto.getReputationList().stream() + .map(Reputation::fromProto) .collect(Collectors.toList()))); } @Override public String toString() { - return "List of salts in BondedReputationList: " + getList().stream() - .map(BondedReputation::getSalt) + return "List of salts in ReputationList: " + getList().stream() + .map(Reputation::getSalt) .collect(Collectors.toList()); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondedRole.java b/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRole.java similarity index 89% rename from core/src/main/java/bisq/core/dao/governance/bond/BondedRole.java rename to core/src/main/java/bisq/core/dao/governance/bond/role/BondedRole.java index b5ed827eede..84995bf6c78 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondedRole.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRole.java @@ -15,8 +15,9 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.bond; +package bisq.core.dao.governance.bond.role; +import bisq.core.dao.governance.bond.BondState; import bisq.core.dao.state.model.governance.Role; import lombok.Getter; @@ -41,7 +42,7 @@ public class BondedRole { @Setter private long revokeDate; @Setter - private BondedRoleState bondedRoleState = BondedRoleState.READY_FOR_LOCKUP; + private BondState bondState = BondState.READY_FOR_LOCKUP; BondedRole(Role role) { this.role = role; diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondedRolesService.java b/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesService.java similarity index 85% rename from core/src/main/java/bisq/core/dao/governance/bond/BondedRolesService.java rename to core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesService.java index db1690f2b69..000afc4a5b0 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondedRolesService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesService.java @@ -15,11 +15,12 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.bond; +package bisq.core.dao.governance.bond.role; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.governance.bonding.BondingConsensus; -import bisq.core.dao.governance.bonding.bond.BondWithHash; +import bisq.core.dao.governance.bond.BondConsensus; +import bisq.core.dao.governance.bond.BondState; +import bisq.core.dao.governance.bond.BondWithHash; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.model.blockchain.BaseTxOutput; @@ -103,10 +104,10 @@ public void onParseTxsComplete(Block block) { // We used the hash of th bonded role object as our hash in OpReturn of the lock up tx to have a // unique binding of the tx to the data object. - byte[] hash = BondingConsensus.getHashFromOpReturnData(opReturnData); + byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); Optional candidate = getBondedRoleFromHash(hash); if (candidate.isPresent() && bondedRole.equals(candidate.get())) { - bondedRoleState.setBondedRoleState(BondedRoleState.LOCKUP_TX_CONFIRMED); + bondedRoleState.setBondState(BondState.LOCKUP_TX_CONFIRMED); bondedRoleState.setLockupTxId(lockupTxId); // We use the tx time as we want to have a unique time for all users bondedRoleState.setStartDate(lockupTx.getTime()); @@ -121,13 +122,13 @@ public void onParseTxsComplete(Block block) { // cross check if it is in daoStateService.getUnlockTxOutputs() ? String unlockTxId = unlockTx.getId(); bondedRoleState.setUnlockTxId(unlockTxId); - bondedRoleState.setBondedRoleState(BondedRoleState.UNLOCK_TX_CONFIRMED); + bondedRoleState.setBondState(BondState.UNLOCK_TX_CONFIRMED); bondedRoleState.setRevokeDate(unlockTx.getTime()); boolean unlocking = daoStateService.isUnlocking(unlockTxId); if (unlocking) { - bondedRoleState.setBondedRoleState(BondedRoleState.UNLOCKING); + bondedRoleState.setBondState(BondState.UNLOCKING); } else { - bondedRoleState.setBondedRoleState(BondedRoleState.UNLOCKED); + bondedRoleState.setBondState(BondState.UNLOCKED); } }); } @@ -153,11 +154,6 @@ public void onParseBlockChainComplete() { public void start() { } - - public List getBondedRoleList() { - return getBondedRoleStream().collect(Collectors.toList()); - } - public Collection getBondedRoles() { return bondedRoleByRoleUidMap.values(); } @@ -168,18 +164,62 @@ public List getActiveBondedRoles() { return getBondedRoleList(); } + + public Optional getBondedRoleFromHash(byte[] hash) { + return getBondedRoleStream() + .filter(bondedRole -> Arrays.equals(bondedRole.getHash(), hash)) + .findAny(); + } + + public Optional getBondedRoleStateFromLockupTxId(String lockupTxId) { + return bondedRoleByRoleUidMap.values().stream() + .filter(bondedRoleState -> lockupTxId.equals(bondedRoleState.getLockupTxId())) + .findAny(); + } + + public Optional getBondedRoleType(String lockUpTxId) { + return getBondedRoleStateFromLockupTxId(lockUpTxId) + .map(BondedRole::getRole) + .map(Role::getBondedRoleType); + } + + public boolean wasRoleAlreadyBonded(Role role) { + BondedRole bondedRole = bondedRoleByRoleUidMap.get(role.getUid()); + checkArgument(bondedRole != null, "bondedRole must not be null"); + return bondedRole.getLockupTxId() != null; + } + + public boolean isMyRole(Role role) { + Set myWalletTransactionIds = bsqWalletService.getWalletTransactions().stream() + .map(Transaction::getHashAsString) + .collect(Collectors.toSet()); + return getBondedRoleProposalStream() + .filter(roleProposal -> roleProposal.getRole().equals(role)) + .map(Proposal::getTxId) + .anyMatch(myWalletTransactionIds::contains); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private List getBondedRoleList() { + return getBondedRoleStream().collect(Collectors.toList()); + } + private void updateBondedRoleStateFromUnconfirmedLockupTxs() { getBondedRoleStream().filter(this::isLockupTxUnconfirmed) .map(role -> bondedRoleByRoleUidMap.get(role.getUid())) - .filter(bondedRole -> bondedRole.getBondedRoleState() == BondedRoleState.READY_FOR_LOCKUP) - .forEach(bondedRole -> bondedRole.setBondedRoleState(BondedRoleState.LOCKUP_TX_PENDING)); + .filter(bondedRole -> bondedRole.getBondState() == BondState.READY_FOR_LOCKUP) + .forEach(bondedRole -> bondedRole.setBondState(BondState.LOCKUP_TX_PENDING)); } private void updateBondedRoleStateFromUnconfirmedUnlockTxs() { getBondedRoleStream().filter(this::isUnlockTxUnconfirmed) .map(role -> bondedRoleByRoleUidMap.get(role.getUid())) - .filter(bondedRole -> bondedRole.getBondedRoleState() == BondedRoleState.LOCKUP_TX_CONFIRMED) - .forEach(bondedRole -> bondedRole.setBondedRoleState(BondedRoleState.UNLOCK_TX_PENDING)); + .filter(bondedRole -> bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED) + .forEach(bondedRole -> bondedRole.setBondState(BondState.UNLOCK_TX_PENDING)); } private boolean isLockupTxUnconfirmed(BondWithHash bondWithHash) { @@ -190,7 +230,7 @@ private boolean isLockupTxUnconfirmed(BondWithHash bondWithHash) { .map(lastOutput -> lastOutput.getScriptPubKey().getChunks()) .filter(chunks -> chunks.size() > 1) .map(chunks -> chunks.get(1).data) - .anyMatch(data -> Arrays.equals(BondingConsensus.getHashFromOpReturnData(data), bondWithHash.getHash())); + .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondWithHash.getHash())); } private boolean isUnlockTxUnconfirmed(BondWithHash bondWithHash) { @@ -205,42 +245,9 @@ private boolean isUnlockTxUnconfirmed(BondWithHash bondWithHash) { .map(Transaction::getHashAsString) .flatMap(lockupTxId -> daoStateService.getLockupOpReturnTxOutput(lockupTxId).stream()) .map(BaseTxOutput::getOpReturnData) - .anyMatch(data -> Arrays.equals(BondingConsensus.getHashFromOpReturnData(data), bondWithHash.getHash())); - } - - public Optional getBondedRoleFromHash(byte[] hash) { - return getBondedRoleStream() - .filter(bondedRole -> { - byte[] candidateHash = bondedRole.getHash(); - /* log.error("getBondedRoleFromHash: equals?={}, hash={}, candidateHash={}\nbondedRole={}", - Arrays.equals(candidateHash, hash), - Utilities.bytesAsHexString(hash), - Utilities.bytesAsHexString(candidateHash), - bondedRole.toString());*/ - return Arrays.equals(candidateHash, hash); - }) - .findAny(); - } - - public Optional getBondedRoleStateFromLockupTxId(String lockupTxId) { - return bondedRoleByRoleUidMap.values().stream() - .filter(bondedRoleState -> lockupTxId.equals(bondedRoleState.getLockupTxId())) - .findAny(); + .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondWithHash.getHash())); } - - public Optional getBondedRoleType(String lockUpTxId) { - return getBondedRoleStateFromLockupTxId(lockUpTxId) - .map(BondedRole::getRole) - .map(Role::getBondedRoleType); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Private - /////////////////////////////////////////////////////////////////////////////////////////// - - private Stream getBondedRoleStream() { return daoStateService.getEvaluatedProposalList().stream() .filter(evaluatedProposal -> evaluatedProposal.getProposal() instanceof RoleProposal) @@ -252,20 +259,4 @@ private Stream getBondedRoleProposalStream() { .filter(evaluatedProposal -> evaluatedProposal.getProposal() instanceof RoleProposal) .map(e -> ((RoleProposal) e.getProposal())); } - - public boolean wasRoleAlreadyBonded(Role role) { - BondedRole bondedRole = bondedRoleByRoleUidMap.get(role.getUid()); - checkArgument(bondedRole != null, "bondedRole must not be null"); - return bondedRole.getLockupTxId() != null; - } - - public boolean isMyRole(Role role) { - Set myWalletTransactionIds = bsqWalletService.getWalletTransactions().stream() - .map(Transaction::getHashAsString) - .collect(Collectors.toSet()); - return getBondedRoleProposalStream() - .filter(roleProposal -> roleProposal.getRole().equals(role)) - .map(Proposal::getTxId) - .anyMatch(myWalletTransactionIds::contains); - } } diff --git a/core/src/main/java/bisq/core/dao/governance/bonding/unlock/UnlockService.java b/core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockService.java similarity index 98% rename from core/src/main/java/bisq/core/dao/governance/bonding/unlock/UnlockService.java rename to core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockService.java index d3f8242c565..4b37e7ebac8 100644 --- a/core/src/main/java/bisq/core/dao/governance/bonding/unlock/UnlockService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockService.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.core.dao.governance.bonding.unlock; +package bisq.core.dao.governance.bond.unlock; import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.TxBroadcastException; diff --git a/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputation.java b/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputation.java deleted file mode 100644 index 13c6f2f4590..00000000000 --- a/core/src/main/java/bisq/core/dao/governance/bonding/bond/BondedReputation.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.core.dao.governance.bonding.bond; - -import bisq.core.locale.Res; - -import bisq.common.crypto.Hash; -import bisq.common.proto.network.NetworkPayload; -import bisq.common.proto.persistable.PersistablePayload; - -import io.bisq.generated.protobuffer.PB; - -import com.google.common.base.Charsets; - -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; - -import lombok.Getter; -import lombok.Setter; - -import javax.annotation.Nullable; - -//TODO shoudld be immutable? -@Getter -public final class BondedReputation implements PersistablePayload, NetworkPayload, BondWithHash { - private final String salt; - - @Nullable - @Setter - private String lockupTxId; - - @Nullable - @Setter - private String unlockTxId; - - public BondedReputation(@Nullable String salt) { - this(salt, - null, - null - ); - } - - public static BondedReputation createBondedReputation() { - return new BondedReputation(UUID.randomUUID().toString()); - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER - /////////////////////////////////////////////////////////////////////////////////////////// - - public BondedReputation(String salt, - @Nullable String lockupTxId, - @Nullable String unlockTxId) { - this.salt = salt; - this.lockupTxId = lockupTxId; - this.unlockTxId = unlockTxId; - } - - @Override - public PB.BondedReputation toProtoMessage() { - PB.BondedReputation.Builder builder = PB.BondedReputation.newBuilder() - .setSalt(salt); - Optional.ofNullable(lockupTxId).ifPresent(builder::setLockupTxId); - Optional.ofNullable(unlockTxId).ifPresent(builder::setUnlockTxId); - return builder.build(); - } - - public static BondedReputation fromProto(PB.BondedReputation proto) { - return new BondedReputation(proto.getSalt(), - proto.getLockupTxId().isEmpty() ? null : proto.getLockupTxId(), - proto.getUnlockTxId().isEmpty() ? null : proto.getUnlockTxId()); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // API - /////////////////////////////////////////////////////////////////////////////////////////// -/* - @Override - public String getUnlockTxId() { - return unlockTxId; - }*/ - - @Override - public byte[] getHash() { - // We use the salt as input for the hash - byte[] bytes = salt.getBytes(Charsets.UTF_8); - byte[] hash = Hash.getSha256Ripemd160hash(bytes); - return hash; - } - - public String getDisplayString() { - return Res.get("dao.bond.bondedReputation"); - } - - public boolean isLockedUp() { - return lockupTxId != null; - } - - public boolean isUnlocked() { - return unlockTxId != null; - } - - /* public boolean isUnlocking(DaoFacade daoFacade) { - return daoFacade.isUnlocking(unlockTxId); - }*/ - - /* public boolean isUnlocking(DaoStateService daoStateService) { - return daoStateService.isUnlocking(this); - }*/ - - // We use only the immutable data - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - BondedReputation that = (BondedReputation) o; - return Objects.equals(salt, that.salt); - } - - @Override - public int hashCode() { - return Objects.hash(salt); - } - - @Override - public String toString() { - return "BondedReputation{" + - "\n salt='" + salt + '\'' + - ",\n lockupTxId='" + lockupTxId + '\'' + - ",\n unlockTxId='" + unlockTxId + '\'' + - "\n}"; - } -} diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java index d185f5ec6d4..b90474fcc58 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java @@ -25,8 +25,8 @@ import bisq.core.dao.governance.blindvote.BlindVoteListService; import bisq.core.dao.governance.blindvote.VoteWithProposalTxId; import bisq.core.dao.governance.blindvote.VoteWithProposalTxIdList; -import bisq.core.dao.governance.bond.BondedRolesService; import bisq.core.dao.governance.bond.ConfiscateBond; +import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.governance.merit.MeritConsensus; import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.IssuanceProposal; diff --git a/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java b/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java index 1723637d477..b0dc5a1e196 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java @@ -18,8 +18,8 @@ package bisq.core.dao.node.parser; import bisq.core.dao.governance.blindvote.BlindVoteConsensus; -import bisq.core.dao.governance.bonding.BondingConsensus; -import bisq.core.dao.governance.bonding.lockup.LockupType; +import bisq.core.dao.governance.bond.BondConsensus; +import bisq.core.dao.governance.bond.lockup.LockupType; import bisq.core.dao.governance.proposal.ProposalConsensus; import bisq.core.dao.governance.voteresult.VoteResultConsensus; import bisq.core.dao.node.parser.exceptions.InvalidParsingConditionException; @@ -105,16 +105,16 @@ static TxOutputType getTxOutputType(TempTxOutput tempTxOutput) { else break; case LOCKUP: - if (!BondingConsensus.hasOpReturnDataValidLength(opReturnData)) + if (!BondConsensus.hasOpReturnDataValidLength(opReturnData)) return TxOutputType.INVALID_OUTPUT; - Optional lockupType = BondingConsensus.getLockupType(opReturnData); + Optional lockupType = BondConsensus.getLockupType(opReturnData); if (!lockupType.isPresent()) { log.warn("No lockupType found for lockup tx, opReturnData=" + Utilities.encodeToHex(opReturnData)); return TxOutputType.INVALID_OUTPUT; } - int lockTime = BondingConsensus.getLockTime(opReturnData); - if (BondingConsensus.isLockTimeInValidRange(lockTime)) { + int lockTime = BondConsensus.getLockTime(opReturnData); + if (BondConsensus.isLockTimeInValidRange(lockTime)) { return TxOutputType.LOCKUP_OP_RETURN_OUTPUT; } else { break; diff --git a/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java b/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java index 42a7906a37d..a19893faa2d 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java @@ -17,7 +17,7 @@ package bisq.core.dao.node.parser; -import bisq.core.dao.governance.bonding.BondingConsensus; +import bisq.core.dao.governance.bond.BondConsensus; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.model.blockchain.OpReturnType; import bisq.core.dao.state.model.blockchain.TxOutput; @@ -96,7 +96,7 @@ void processOpReturnOutput(TempTxOutput tempTxOutput) { // If we have a LOCKUP opReturn output we save the lockTime to apply it later to the LOCKUP output. // We keep that data in that other output as it makes parsing of the UNLOCK tx easier. optionalOpReturnType.filter(opReturnType -> opReturnType == OpReturnType.LOCKUP) - .ifPresent(opReturnType -> lockTime = BondingConsensus.getLockTime(opReturnData)); + .ifPresent(opReturnType -> lockTime = BondConsensus.getLockTime(opReturnData)); } void processTxOutput(TempTxOutput tempTxOutput) { diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateService.java b/core/src/main/java/bisq/core/dao/state/DaoStateService.java index 63436de0d82..789eb32edf0 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateService.java @@ -18,8 +18,8 @@ package bisq.core.dao.state; import bisq.core.dao.DaoSetupService; +import bisq.core.dao.governance.bond.BondConsensus; import bisq.core.dao.governance.bond.ConfiscateBond; -import bisq.core.dao.governance.bonding.BondingConsensus; import bisq.core.dao.governance.param.Param; import bisq.core.dao.state.model.DaoState; import bisq.core.dao.state.model.blockchain.Block; @@ -603,7 +603,7 @@ public Optional getLockupHash(TxOutput txOutput) { if (lockupTx.isPresent()) { byte[] opReturnData = lockupTx.get().getLastTxOutput().getOpReturnData(); if (opReturnData != null) - return Optional.of(BondingConsensus.getHashFromOpReturnData(opReturnData)); + return Optional.of(BondConsensus.getHashFromOpReturnData(opReturnData)); } return Optional.empty(); } @@ -705,7 +705,7 @@ public Optional getUnlockBlockHeight(String txId) { public boolean isLockTimeOverForUnlockTxOutput(TxOutput unlockTxOutput) { checkArgument(isUnlockOutput(unlockTxOutput), "txOutput must be of type UNLOCK"); return getUnlockBlockHeight(unlockTxOutput.getTxId()) - .map(unlockBlockHeight -> BondingConsensus.isLockTimeOver(unlockBlockHeight, getChainHeight())) + .map(unlockBlockHeight -> BondConsensus.isLockTimeOver(unlockBlockHeight, getChainHeight())) .orElse(false); } diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/Role.java b/core/src/main/java/bisq/core/dao/state/model/governance/Role.java index 567e0a269b2..7b26aa61dea 100644 --- a/core/src/main/java/bisq/core/dao/state/model/governance/Role.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/Role.java @@ -17,7 +17,7 @@ package bisq.core.dao.state.model.governance; -import bisq.core.dao.governance.bonding.bond.BondWithHash; +import bisq.core.dao.governance.bond.BondWithHash; import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.core.locale.Res; diff --git a/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java b/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java index d6672e86c12..2865950a273 100644 --- a/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java +++ b/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java @@ -23,7 +23,7 @@ import bisq.core.dao.governance.asset.AssetService; import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; -import bisq.core.dao.governance.bonding.bond.BondedReputationService; +import bisq.core.dao.governance.bond.reputation.BondedReputationService; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.proposal.MyProposalListService; import bisq.core.offer.OpenOfferManager; diff --git a/core/src/main/java/bisq/core/util/validation/HexStringValidator.java b/core/src/main/java/bisq/core/util/validation/HexStringValidator.java new file mode 100644 index 00000000000..09d601f9bbf --- /dev/null +++ b/core/src/main/java/bisq/core/util/validation/HexStringValidator.java @@ -0,0 +1,46 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.util.validation; + +import bisq.core.locale.Res; + +import bisq.common.util.Utilities; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode(callSuper = true) +@Data +public class HexStringValidator extends InputValidator { + public HexStringValidator() { + } + + public ValidationResult validate(String input) { + ValidationResult validationResult = super.validate(input); + if (!validationResult.isValid) + return validationResult; + + try { + Utilities.decodeFromHex(input); + return validationResult; + } catch (Throwable t) { + return new ValidationResult(false, Res.get("validation.noHexString", input)); + } + + } +} diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 1d44fbad8aa..836f5e00028 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -1308,11 +1308,12 @@ dao.results.votes.table.header.merit=Earned dao.results.votes.table.header.vote=Vote dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Bonded reputation +dao.bonding.menuItem.bonds=Bonds dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup dao.bonding.lock.time=Unlock time in blocks +dao.bonding.lock.salt=Salt dao.bonding.lock.type=Type of bond dao.bonding.lock.bondedRoles=Bonded roles dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) @@ -1398,19 +1399,19 @@ dao.bond.table.unlocking=Bond unlocking dao.bond.table.unlocked=Bond unlocked # suppress inspection "UnusedProperty" -dao.bond.bondedRoleState.READY_FOR_LOCKUP=Not bonded yet +dao.bond.bondState.READY_FOR_LOCKUP=Not bonded yet # suppress inspection "UnusedProperty" -dao.bond.bondedRoleState.LOCKUP_TX_PENDING=Lockup pending +dao.bond.bondState.LOCKUP_TX_PENDING=Lockup pending # suppress inspection "UnusedProperty" -dao.bond.bondedRoleState.LOCKUP_TX_CONFIRMED=Bond locked up +dao.bond.bondState.LOCKUP_TX_CONFIRMED=Bond locked up # suppress inspection "UnusedProperty" -dao.bond.bondedRoleState.UNLOCK_TX_PENDING=Unlock pending +dao.bond.bondState.UNLOCK_TX_PENDING=Unlock pending # suppress inspection "UnusedProperty" -dao.bond.bondedRoleState.UNLOCK_TX_CONFIRMED=Unlock tx confirmed +dao.bond.bondState.UNLOCK_TX_CONFIRMED=Unlock tx confirmed # suppress inspection "UnusedProperty" -dao.bond.bondedRoleState.UNLOCKING=Bond unlocking +dao.bond.bondState.UNLOCKING=Bond unlocking # suppress inspection "UnusedProperty" -dao.bond.bondedRoleState.UNLOCKED=Bond unlocked +dao.bond.bondState.UNLOCKED=Bond unlocked # suppress inspection "UnusedProperty" dao.phase.UNDEFINED=Undefined @@ -2470,3 +2471,4 @@ validation.inputTooSmall=Input has to be larger than {0} validation.amountBelowDust=The amount below the dust limit of {0} is not allowed. validation.length=Length must be between {0} and {1} validation.pattern=Input must be of format: {0} +validation.noHexString=The input is not in HEX format. diff --git a/core/src/main/resources/i18n/displayStrings_de.properties b/core/src/main/resources/i18n/displayStrings_de.properties index eed8face964..09cae748a0c 100644 --- a/core/src/main/resources/i18n/displayStrings_de.properties +++ b/core/src/main/resources/i18n/displayStrings_de.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Stimmoffenbarung Tx ID dao.results.votes.table.header.vote=Stimme dao.bonding.menuItem.bondedRoles=Gekoppelte Rollen -dao.bonding.menuItem.lockupBSQ=BSQ sperren -dao.bonding.menuItem.unlockBSQ=BSQ entsperren +dao.bonding.menuItem.reputation=BSQ sperren +dao.bonding.menuItem.bonds=BSQ entsperren dao.bonding.lock.lockBSQ=BSQ sperren dao.bonding.lock.amount=Betrag von BSQ zu sperren: dao.bonding.lock.time=Entsperrung-Zeit in Blöcken: diff --git a/core/src/main/resources/i18n/displayStrings_el.properties b/core/src/main/resources/i18n/displayStrings_el.properties index 21e556b61b9..18e7047de3b 100644 --- a/core/src/main/resources/i18n/displayStrings_el.properties +++ b/core/src/main/resources/i18n/displayStrings_el.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Ψήφισε dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Lockup BSQ +dao.bonding.menuItem.bonds=Unlock BSQ dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: diff --git a/core/src/main/resources/i18n/displayStrings_es.properties b/core/src/main/resources/i18n/displayStrings_es.properties index 79fe174a3a2..70f7793b68b 100644 --- a/core/src/main/resources/i18n/displayStrings_es.properties +++ b/core/src/main/resources/i18n/displayStrings_es.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=otar dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Lockup BSQ +dao.bonding.menuItem.bonds=Unlock BSQ dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: diff --git a/core/src/main/resources/i18n/displayStrings_fa.properties b/core/src/main/resources/i18n/displayStrings_fa.properties index 47ff169df8b..3fa3b57aae0 100644 --- a/core/src/main/resources/i18n/displayStrings_fa.properties +++ b/core/src/main/resources/i18n/displayStrings_fa.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=رأی dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Lockup BSQ +dao.bonding.menuItem.bonds=Unlock BSQ dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: diff --git a/core/src/main/resources/i18n/displayStrings_hu.properties b/core/src/main/resources/i18n/displayStrings_hu.properties index 1c76d6bcd54..93bd0899e56 100644 --- a/core/src/main/resources/i18n/displayStrings_hu.properties +++ b/core/src/main/resources/i18n/displayStrings_hu.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Szavazás dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Lockup BSQ +dao.bonding.menuItem.bonds=Unlock BSQ dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: diff --git a/core/src/main/resources/i18n/displayStrings_pt.properties b/core/src/main/resources/i18n/displayStrings_pt.properties index 79f6dfbecc7..9171d444a99 100644 --- a/core/src/main/resources/i18n/displayStrings_pt.properties +++ b/core/src/main/resources/i18n/displayStrings_pt.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Votar dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Lockup BSQ +dao.bonding.menuItem.bonds=Unlock BSQ dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: diff --git a/core/src/main/resources/i18n/displayStrings_ro.properties b/core/src/main/resources/i18n/displayStrings_ro.properties index 9971c0abc00..0c656ea8ee4 100644 --- a/core/src/main/resources/i18n/displayStrings_ro.properties +++ b/core/src/main/resources/i18n/displayStrings_ro.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Votează dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Lockup BSQ +dao.bonding.menuItem.bonds=Unlock BSQ dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: diff --git a/core/src/main/resources/i18n/displayStrings_ru.properties b/core/src/main/resources/i18n/displayStrings_ru.properties index 71a661c1ddc..47c50b27080 100644 --- a/core/src/main/resources/i18n/displayStrings_ru.properties +++ b/core/src/main/resources/i18n/displayStrings_ru.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Транз. идент. выяв dao.results.votes.table.header.vote=Голосование dao.bonding.menuItem.bondedRoles=Обеспеченные роли -dao.bonding.menuItem.lockupBSQ=Запереть BSQ -dao.bonding.menuItem.unlockBSQ=Разблокировать BSQ +dao.bonding.menuItem.reputation=Запереть BSQ +dao.bonding.menuItem.bonds=Разблокировать BSQ dao.bonding.lock.lockBSQ=Запереть BSQ dao.bonding.lock.amount=Запереть BSQ на сумму: dao.bonding.lock.time=Срок разблокировки в блоках: diff --git a/core/src/main/resources/i18n/displayStrings_sr.properties b/core/src/main/resources/i18n/displayStrings_sr.properties index 57e1984ac85..369925adea5 100644 --- a/core/src/main/resources/i18n/displayStrings_sr.properties +++ b/core/src/main/resources/i18n/displayStrings_sr.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Glasaj dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Lockup BSQ +dao.bonding.menuItem.bonds=Unlock BSQ dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: diff --git a/core/src/main/resources/i18n/displayStrings_th.properties b/core/src/main/resources/i18n/displayStrings_th.properties index 4be351a53fb..01acd7ec57c 100644 --- a/core/src/main/resources/i18n/displayStrings_th.properties +++ b/core/src/main/resources/i18n/displayStrings_th.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=โหวต dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Lockup BSQ +dao.bonding.menuItem.bonds=Unlock BSQ dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: diff --git a/core/src/main/resources/i18n/displayStrings_vi.properties b/core/src/main/resources/i18n/displayStrings_vi.properties index 5da6984fcaf..c5d83623e17 100644 --- a/core/src/main/resources/i18n/displayStrings_vi.properties +++ b/core/src/main/resources/i18n/displayStrings_vi.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Bỏ phiếu dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Lockup BSQ +dao.bonding.menuItem.bonds=Unlock BSQ dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: diff --git a/core/src/main/resources/i18n/displayStrings_zh.properties b/core/src/main/resources/i18n/displayStrings_zh.properties index f74c73e5f09..dbb468b2ab0 100644 --- a/core/src/main/resources/i18n/displayStrings_zh.properties +++ b/core/src/main/resources/i18n/displayStrings_zh.properties @@ -1122,8 +1122,8 @@ dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=投票 dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.lockupBSQ=Lockup BSQ -dao.bonding.menuItem.unlockBSQ=Unlock BSQ +dao.bonding.menuItem.reputation=Lockup BSQ +dao.bonding.menuItem.bonds=Unlock BSQ dao.bonding.lock.lockBSQ=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index 58cd56fbd26..efe8f9578ba 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -27,10 +27,10 @@ import bisq.desktop.components.MenuItem; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; +import bisq.desktop.main.dao.bonding.bonds.BondsView; import bisq.desktop.main.dao.bonding.dashboard.BondingDashboardView; import bisq.desktop.main.dao.bonding.reputation.ReputationView; import bisq.desktop.main.dao.bonding.roles.BondedRolesView; -import bisq.desktop.main.dao.bonding.unlock.UnlockView; import bisq.core.locale.Res; @@ -53,7 +53,7 @@ public class BondingView extends ActivatableViewAndModel { private final ViewLoader viewLoader; private final Navigation navigation; - private MenuItem dashboard, bondedRoles, lockupBSQ, unlockBSQ; + private MenuItem dashboard, bondedRoles, reputation, bonds; private Navigation.Listener listener; @FXML @@ -85,20 +85,20 @@ public void initialize() { BondingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); bondedRoles = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.bondedRoles"), BondedRolesView.class, AwesomeIcon.SHIELD, baseNavPath); - lockupBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.lockupBSQ"), + reputation = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.reputation"), ReputationView.class, AwesomeIcon.LOCK, baseNavPath); - unlockBSQ = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.unlockBSQ"), - UnlockView.class, AwesomeIcon.UNLOCK, baseNavPath); + bonds = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.bonds"), + BondsView.class, AwesomeIcon.UNLOCK, baseNavPath); - leftVBox.getChildren().addAll(dashboard, bondedRoles, lockupBSQ, unlockBSQ); + leftVBox.getChildren().addAll(dashboard, bondedRoles, reputation, bonds); } @Override protected void activate() { dashboard.activate(); bondedRoles.activate(); - lockupBSQ.activate(); - unlockBSQ.activate(); + reputation.activate(); + bonds.activate(); navigation.addListener(listener); ViewPath viewPath = navigation.getCurrentPath(); @@ -121,8 +121,8 @@ protected void deactivate() { dashboard.deactivate(); bondedRoles.deactivate(); - lockupBSQ.deactivate(); - unlockBSQ.deactivate(); + reputation.deactivate(); + bonds.deactivate(); } private void loadView(Class viewClass) { @@ -131,7 +131,7 @@ private void loadView(Class viewClass) { if (view instanceof BondingDashboardView) dashboard.setSelected(true); else if (view instanceof BondedRolesView) bondedRoles.setSelected(true); - else if (view instanceof ReputationView) lockupBSQ.setSelected(true); - else if (view instanceof UnlockView) unlockBSQ.setSelected(true); + else if (view instanceof ReputationView) reputation.setSelected(true); + else if (view instanceof BondsView) bonds.setSelected(true); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java index ad06e0883de..f7a5cb990e2 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java @@ -26,9 +26,9 @@ import bisq.core.btc.setup.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bonding.bond.BondWithHash; -import bisq.core.dao.governance.bonding.bond.BondedReputation; -import bisq.core.dao.governance.bonding.lockup.LockupType; +import bisq.core.dao.governance.bond.BondWithHash; +import bisq.core.dao.governance.bond.lockup.LockupType; +import bisq.core.dao.governance.bond.reputation.Reputation; import bisq.core.dao.state.model.blockchain.TxOutput; import bisq.core.dao.state.model.governance.BondedRoleType; import bisq.core.dao.state.model.governance.Role; @@ -114,9 +114,9 @@ public void lockupBondForBondedRole(Role role, Consumer resultHandler) { lockupBond(role, lockupAmount, lockupTime, LockupType.BONDED_ROLE, resultHandler); } - public void lockupBondForReputation(Coin lockupAmount, int lockupTime, Consumer resultHandler) { - BondedReputation bondedReputation = BondedReputation.createBondedReputation(); - lockupBond(bondedReputation, lockupAmount, lockupTime, LockupType.REPUTATION, resultHandler); + public void lockupBondForReputation(Coin lockupAmount, int lockupTime, byte[] salt, Consumer resultHandler) { + Reputation reputation = new Reputation(salt); + lockupBond(reputation, lockupAmount, lockupTime, LockupType.REPUTATION, resultHandler); } public void unLock(String lockupTxId, Consumer resultHandler) { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java similarity index 87% rename from desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java rename to desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java index b2c94d321d1..a15c66456db 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/LockupTxListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java @@ -15,7 +15,7 @@ * along with Bisq. If not, see . */ -package bisq.desktop.main.dao.bonding.unlock; +package bisq.desktop.main.dao.bonding.bonds; import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.components.TxConfidenceListItem; @@ -25,10 +25,10 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.BondedRole; -import bisq.core.dao.governance.bond.BondedRolesService; -import bisq.core.dao.governance.bonding.BondingConsensus; -import bisq.core.dao.governance.bonding.lockup.LockupType; +import bisq.core.dao.governance.bond.BondConsensus; +import bisq.core.dao.governance.bond.lockup.LockupType; +import bisq.core.dao.governance.bond.role.BondedRole; +import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.state.model.blockchain.BaseTxOutput; import bisq.core.dao.state.model.blockchain.TxOutput; import bisq.core.dao.state.model.blockchain.TxType; @@ -51,7 +51,7 @@ @EqualsAndHashCode(callSuper = true) @Data @Slf4j -class LockupTxListItem extends TxConfidenceListItem { +class BondListItem extends TxConfidenceListItem { private final BtcWalletService btcWalletService; private final DaoFacade daoFacade; @@ -67,13 +67,13 @@ class LockupTxListItem extends TxConfidenceListItem { private TxConfidenceListener txConfidenceListener; private boolean issuanceTx; - LockupTxListItem(Transaction transaction, - BsqWalletService bsqWalletService, - BtcWalletService btcWalletService, - DaoFacade daoFacade, - BondedRolesService bondedRolesService, - Date date, - BsqFormatter bsqFormatter) { + BondListItem(Transaction transaction, + BsqWalletService bsqWalletService, + BtcWalletService btcWalletService, + DaoFacade daoFacade, + BondedRolesService bondedRolesService, + Date date, + BsqFormatter bsqFormatter) { super(transaction, bsqWalletService); this.btcWalletService = btcWalletService; @@ -128,7 +128,7 @@ public TxType getTxType() { private Optional getOptionalLockupType() { return getOpReturnData() - .flatMap(BondingConsensus::getLockupType); + .flatMap(BondConsensus::getLockupType); } private Optional getOpReturnData() { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.fxml b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.fxml similarity index 98% rename from desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.fxml rename to desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.fxml index 569aca0c183..b7d03d7bd5f 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/unlock/UnlockView.fxml +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.fxml @@ -21,7 +21,7 @@ -. */ -package bisq.desktop.main.dao.bonding.unlock; +package bisq.desktop.main.dao.bonding.bonds; import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; @@ -30,7 +30,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.BondedRolesService; +import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.model.blockchain.Block; import bisq.core.dao.state.model.blockchain.TxType; @@ -71,8 +71,8 @@ import java.util.stream.Collectors; @FxmlView -public class UnlockView extends ActivatableView implements BsqBalanceListener, DaoStateListener { - private TableView tableView; +public class BondsView extends ActivatableView implements BsqBalanceListener, DaoStateListener { + private TableView tableView; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; @@ -84,11 +84,10 @@ public class UnlockView extends ActivatableView implements BsqBa private final DaoFacade daoFacade; private final Preferences preferences; - private int gridRow = 0; - private final ObservableList observableList = FXCollections.observableArrayList(); - private final FilteredList lockupTxs = new FilteredList<>(observableList); + private final ObservableList observableList = FXCollections.observableArrayList(); + private final FilteredList lockupTxs = new FilteredList<>(observableList); private ListChangeListener walletBsqTransactionsListener; private ChangeListener walletChainHeightListener; @@ -99,15 +98,15 @@ public class UnlockView extends ActivatableView implements BsqBa /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private UnlockView(BsqWalletService bsqWalletService, - BtcWalletService btcWalletService, - BsqFormatter bsqFormatter, - BsqBalanceUtil bsqBalanceUtil, - BsqValidator bsqValidator, - BondingViewUtils bondingViewUtils, - BondedRolesService bondedRolesService, - DaoFacade daoFacade, - Preferences preferences) { + private BondsView(BsqWalletService bsqWalletService, + BtcWalletService btcWalletService, + BsqFormatter bsqFormatter, + BsqBalanceUtil bsqBalanceUtil, + BsqValidator bsqValidator, + BondingViewUtils bondingViewUtils, + BondedRolesService bondedRolesService, + DaoFacade daoFacade, + Preferences preferences) { this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; this.bsqFormatter = bsqFormatter; @@ -132,7 +131,7 @@ public void initialize() { addLockTimeColumn(); addUnlockColumn(); - lockupTxs.setPredicate(LockupTxListItem::isLockupAndUnspent); + lockupTxs.setPredicate(BondListItem::isLockupAndUnspent); walletBsqTransactionsListener = change -> updateList(); walletChainHeightListener = (observable, oldValue, newValue) -> updateList(); @@ -178,7 +177,7 @@ protected void deactivate() { btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); daoFacade.removeBsqStateListener(this); - observableList.forEach(LockupTxListItem::cleanup); + observableList.forEach(BondListItem::cleanup); } @@ -219,19 +218,19 @@ public void onParseBlockChainComplete() { // Private /////////////////////////////////////////////////////////////////////////////////////////// - private void openTxInBlockExplorer(LockupTxListItem item) { + private void openTxInBlockExplorer(BondListItem item) { if (item.getTxId() != null) GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); } private void updateList() { - observableList.forEach(LockupTxListItem::cleanup); + observableList.forEach(BondListItem::cleanup); // copy list to avoid ConcurrentModificationException final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); - List items = walletTransactions.stream() + List items = walletTransactions.stream() .map(transaction -> { - return new LockupTxListItem(transaction, + return new BondListItem(transaction, bsqWalletService, btcWalletService, daoFacade, @@ -249,22 +248,21 @@ private void updateList() { /////////////////////////////////////////////////////////////////////////////////////////// private void addTxIdColumn() { - TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.txId")); + TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.txId")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(60); column.setCellFactory( - new Callback, TableCell>() { + new Callback<>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell<>() { private HyperlinkWithIcon hyperlinkWithIcon; @Override - public void updateItem(final LockupTxListItem item, boolean empty) { + public void updateItem(final BondListItem item, boolean empty) { super.updateItem(item, empty); //noinspection Duplicates @@ -287,7 +285,7 @@ public void updateItem(final LockupTxListItem item, boolean empty) { } private void addInfoColumn() { - TableColumn column = + TableColumn column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.type")); column.setMinWidth(160); column.setMaxWidth(column.getMinWidth()); @@ -296,12 +294,12 @@ private void addInfoColumn() { column.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { @Override - public void updateItem(final LockupTxListItem item, boolean empty) { + public void updateItem(final BondListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { setText(item.getInfo()); @@ -315,22 +313,21 @@ public void updateItem(final LockupTxListItem item, boolean empty) { } private void addAmountColumn() { - TableColumn column = + TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", "BSQ")); column.setMinWidth(120); column.setMaxWidth(column.getMinWidth()); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setCellFactory(new Callback, - TableCell>() { + column.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell<>() { @Override - public void updateItem(final LockupTxListItem item, boolean empty) { + public void updateItem(final BondListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { TxType txType = item.getTxType(); @@ -347,22 +344,21 @@ public void updateItem(final LockupTxListItem item, boolean empty) { } private void addLockTimeColumn() { - TableColumn column = + TableColumn column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.time")); column.setMinWidth(120); column.setMaxWidth(column.getMinWidth()); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setCellFactory(new Callback, - TableCell>() { + column.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell<>() { @Override - public void updateItem(final LockupTxListItem item, boolean empty) { + public void updateItem(final BondListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { TxType txType = item.getTxType(); @@ -379,19 +375,19 @@ public void updateItem(final LockupTxListItem item, boolean empty) { } private void addUnlockColumn() { - TableColumn unlockColumn = new TableColumn<>(); + TableColumn unlockColumn = new TableColumn<>(); unlockColumn.setMinWidth(130); unlockColumn.setMaxWidth(unlockColumn.getMinWidth()); unlockColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); unlockColumn.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { Button button; @Override - public void updateItem(final LockupTxListItem item, boolean empty) { + public void updateItem(final BondListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -414,7 +410,7 @@ public void updateItem(final LockupTxListItem item, boolean empty) { }; } }); - unlockColumn.setComparator(Comparator.comparing(LockupTxListItem::getConfirmations)); + unlockColumn.setComparator(Comparator.comparing(BondListItem::getConfirmations)); tableView.getColumns().add(unlockColumn); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.java index 4a95312bc8c..ea8002e59fc 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.java @@ -29,30 +29,27 @@ import bisq.core.btc.listeners.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.BondedRole; -import bisq.core.dao.governance.bonding.BondingConsensus; -import bisq.core.dao.governance.bonding.lockup.LockupType; -import bisq.core.dao.state.model.governance.Role; +import bisq.core.dao.governance.bond.BondConsensus; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; +import bisq.core.util.validation.HexStringValidator; import bisq.core.util.validation.IntegerValidator; +import bisq.common.crypto.Hash; +import bisq.common.util.Utilities; + import org.bitcoinj.core.Coin; import javax.inject.Inject; +import com.google.common.base.Charsets; + import javafx.scene.control.Button; -import javafx.scene.control.ComboBox; import javafx.scene.layout.GridPane; import javafx.beans.value.ChangeListener; -import javafx.collections.FXCollections; - -import javafx.util.StringConverter; - -import java.util.Arrays; +import java.util.UUID; import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; import static bisq.desktop.util.FormBuilder.addInputTextField; @@ -64,21 +61,15 @@ public class ReputationView extends ActivatableView implements B private final BsqFormatter bsqFormatter; private final BsqBalanceUtil bsqBalanceUtil; private final BondingViewUtils bondingViewUtils; + private final HexStringValidator hexStringValidator; private final BsqValidator bsqValidator; - private final DaoFacade daoFacade; private final IntegerValidator timeInputTextFieldValidator; private int gridRow = 0; - private InputTextField amountInputTextField; - private InputTextField timeInputTextField; - private ComboBox lockupTypeComboBox; - private ComboBox bondedRolesComboBox; + private InputTextField amountInputTextField, timeInputTextField, saltInputTextField; private Button lockupButton; - private ChangeListener amountFocusOutListener, timeFocusOutListener; - private ChangeListener amountInputTextFieldListener, timeInputTextFieldListener; - private ChangeListener bondedRoleStateListener; - private ChangeListener lockupTypeListener; - private TitledGroupBg titledGroupBg; + private ChangeListener amountFocusOutListener, timeFocusOutListener, saltFocusOutListener; + private ChangeListener amountInputTextFieldListener, timeInputTextFieldListener, saltInputTextFieldListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -90,18 +81,18 @@ private ReputationView(BsqWalletService bsqWalletService, BsqFormatter bsqFormatter, BsqBalanceUtil bsqBalanceUtil, BondingViewUtils bondingViewUtils, - BsqValidator bsqValidator, - DaoFacade daoFacade) { + HexStringValidator hexStringValidator, + BsqValidator bsqValidator) { this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; this.bsqBalanceUtil = bsqBalanceUtil; this.bondingViewUtils = bondingViewUtils; + this.hexStringValidator = hexStringValidator; this.bsqValidator = bsqValidator; - this.daoFacade = daoFacade; timeInputTextFieldValidator = new IntegerValidator(); - timeInputTextFieldValidator.setMinValue(BondingConsensus.getMinLockTime()); - timeInputTextFieldValidator.setMaxValue(BondingConsensus.getMaxLockTime()); + timeInputTextFieldValidator.setMinValue(BondConsensus.getMinLockTime()); + timeInputTextFieldValidator.setMaxValue(BondConsensus.getMaxLockTime()); } @Override @@ -109,7 +100,7 @@ public void initialize() { gridRow = bsqBalanceUtil.addGroup(root, gridRow); int columnSpan = 3; - titledGroupBg = addTitledGroupBg(root, ++gridRow, 3, Res.get("dao.bonding.lock.lockBSQ"), + TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 3, Res.get("dao.bonding.lock.lockBSQ"), Layout.GROUP_DISTANCE); GridPane.setColumnSpan(titledGroupBg, columnSpan); @@ -121,98 +112,28 @@ public void initialize() { timeInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time")); + saltInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.salt")); + GridPane.setColumnSpan(saltInputTextField, columnSpan); + saltInputTextField.setValidator(hexStringValidator); + /* timeInputTextField.setPromptText(Res.get("dao.bonding.lock.setTime", - String.valueOf(BondingConsensus.getMinLockTime()), String.valueOf(BondingConsensus.getMaxLockTime())));*/ + String.valueOf(BondConsensus.getMinLockTime()), String.valueOf(BondConsensus.getMaxLockTime())));*/ timeInputTextField.setValidator(timeInputTextFieldValidator); GridPane.setColumnSpan(timeInputTextField, columnSpan); - lockupTypeComboBox = FormBuilder.addComboBox(root, ++gridRow, Res.get("dao.bonding.lock.type")); - GridPane.setColumnSpan(lockupTypeComboBox, columnSpan); - lockupTypeComboBox.setConverter(new StringConverter<>() { - @Override - public String toString(LockupType lockupType) { - return lockupType.getDisplayString(); - } - - @Override - public LockupType fromString(String string) { - return null; - } - }); - lockupTypeComboBox.setItems(FXCollections.observableArrayList(Arrays.asList(LockupType.values()))); - lockupTypeListener = (observable, oldValue, newValue) -> { - if (newValue != null) { - bondedRolesComboBox.getSelectionModel().clearSelection(); - } - int lockupRows = 3; - if (newValue == LockupType.BONDED_ROLE) { - bondedRolesComboBox.setVisible(true); - lockupRows++; - - bondedRolesComboBox.setItems(FXCollections.observableArrayList(daoFacade.getBondedRoles())); - } else { - bondedRolesComboBox.setVisible(false); - bondedRolesComboBox.getItems().clear(); - } - GridPane.setRowSpan(titledGroupBg, lockupRows); - GridPane.setRowIndex(lockupButton, GridPane.getRowIndex(amountInputTextField) + lockupRows); - }; - - - bondedRolesComboBox = FormBuilder.addComboBox(root, ++gridRow, Res.get("dao.bonding.lock.bondedRoles")); - GridPane.setColumnSpan(bondedRolesComboBox, columnSpan); - bondedRolesComboBox.setVisible(false); - bondedRolesComboBox.setConverter(new StringConverter<>() { - @Override - public String toString(BondedRole bondedRole) { - return bondedRole.getRole().getDisplayString(); - } - - @Override - public BondedRole fromString(String string) { - return null; - } - }); - bondedRoleStateListener = (observable, oldValue, newValue) -> { - if (newValue != null) { - Role role = newValue.getRole(); - amountInputTextField.setText(bsqFormatter.formatCoin(Coin.valueOf(role.getBondedRoleType().getRequiredBond()))); - timeInputTextField.setText(String.valueOf(role.getBondedRoleType().getUnlockTimeInBlocks())); - amountInputTextField.resetValidation(); - timeInputTextField.resetValidation(); - amountInputTextField.setEditable(false); - timeInputTextField.setEditable(false); - } else { - amountInputTextField.clear(); - timeInputTextField.clear(); - amountInputTextField.resetValidation(); - timeInputTextField.resetValidation(); - amountInputTextField.setEditable(true); - timeInputTextField.setEditable(true); - } - }; - - lockupButton = addButtonAfterGroup(root, gridRow, Res.get("dao.bonding.lock.lockupButton")); + lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); lockupButton.setOnAction((event) -> { - switch (lockupTypeComboBox.getValue()) { - case BONDED_ROLE: - if (bondedRolesComboBox.getValue() != null) { - bondingViewUtils.lockupBondForBondedRole(bondedRolesComboBox.getValue().getRole(), - txId -> bondedRolesComboBox.getSelectionModel().clearSelection()); - } - break; - case REPUTATION: - bondingViewUtils.lockupBondForReputation(bsqFormatter.parseToCoin(amountInputTextField.getText()), - Integer.parseInt(timeInputTextField.getText()), - txId -> { - amountInputTextField.setText(""); - timeInputTextField.setText(""); - }); - break; - default: - log.error("Unknown lockup option=" + lockupTypeComboBox.getValue()); - } + Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); + int lockupTime = Integer.parseInt(timeInputTextField.getText()); + byte[] salt = Utilities.decodeFromHex(saltInputTextField.getText()); + bondingViewUtils.lockupBondForReputation(lockupAmount, + lockupTime, + salt, + txId -> { + amountInputTextField.setText(""); + timeInputTextField.setText(""); + }); }); amountFocusOutListener = (observable, oldValue, newValue) -> { @@ -227,8 +148,15 @@ public BondedRole fromString(String string) { onUpdateBalances(); } }; + saltFocusOutListener = (observable, oldValue, newValue) -> { + if (!newValue) { + updateButtonState(); + onUpdateBalances(); + } + }; amountInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); timeInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); + saltInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); } @Override @@ -236,16 +164,19 @@ protected void activate() { bsqBalanceUtil.activate(); amountInputTextField.textProperty().addListener(amountInputTextFieldListener); - timeInputTextField.textProperty().addListener(timeInputTextFieldListener); amountInputTextField.focusedProperty().addListener(amountFocusOutListener); + + timeInputTextField.textProperty().addListener(timeInputTextFieldListener); timeInputTextField.focusedProperty().addListener(timeFocusOutListener); - lockupTypeComboBox.getSelectionModel().selectedItemProperty().addListener(lockupTypeListener); - bondedRolesComboBox.getSelectionModel().selectedItemProperty().addListener(bondedRoleStateListener); + + saltInputTextField.textProperty().addListener(saltInputTextFieldListener); + saltInputTextField.focusedProperty().addListener(saltFocusOutListener); bsqWalletService.addBsqBalanceListener(this); - lockupTypeComboBox.getSelectionModel().clearSelection(); - bondedRolesComboBox.getSelectionModel().clearSelection(); + byte[] randomBytes = UUID.randomUUID().toString().getBytes(Charsets.UTF_8); + byte[] hashOfRandomBytes = Hash.getSha256Ripemd160hash(randomBytes); + saltInputTextField.setText(Utilities.bytesAsHexString(hashOfRandomBytes)); onUpdateBalances(); } @@ -255,11 +186,13 @@ protected void deactivate() { bsqBalanceUtil.deactivate(); amountInputTextField.textProperty().removeListener(amountInputTextFieldListener); - timeInputTextField.textProperty().removeListener(timeInputTextFieldListener); amountInputTextField.focusedProperty().removeListener(amountFocusOutListener); + + timeInputTextField.textProperty().removeListener(timeInputTextFieldListener); timeInputTextField.focusedProperty().removeListener(timeFocusOutListener); - lockupTypeComboBox.getSelectionModel().selectedItemProperty().removeListener(lockupTypeListener); - bondedRolesComboBox.getSelectionModel().selectedItemProperty().removeListener(bondedRoleStateListener); + + saltInputTextField.textProperty().removeListener(saltInputTextFieldListener); + saltInputTextField.focusedProperty().removeListener(saltFocusOutListener); bsqWalletService.removeBsqBalanceListener(this); } @@ -286,9 +219,10 @@ private void onUpdateBalances() { } private void updateButtonState() { - lockupButton.setDisable(!bsqValidator.validate(amountInputTextField.getText()).isValid || - !timeInputTextFieldValidator.validate(timeInputTextField.getText()).isValid || - bondedRolesComboBox.getSelectionModel().getSelectedItem() == null || - lockupTypeComboBox.getSelectionModel().getSelectedItem() == null); + boolean isValid = bsqValidator.validate(amountInputTextField.getText()).isValid && + timeInputTextFieldValidator.validate(timeInputTextField.getText()).isValid && + hexStringValidator.validate(saltInputTextField.getText()).isValid; + + lockupButton.setDisable(!isValid); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java index 5c69303ef93..4bc011da946 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java @@ -21,8 +21,8 @@ import bisq.desktop.main.dao.bonding.BondingViewUtils; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.BondedRole; -import bisq.core.dao.governance.bond.BondedRoleState; +import bisq.core.dao.governance.bond.BondState; +import bisq.core.dao.governance.bond.role.BondedRole; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.model.blockchain.Block; import bisq.core.dao.state.model.governance.Role; @@ -73,19 +73,19 @@ class BondedRolesListItem implements DaoStateListener { label = new Label(); button.setOnAction(e -> { - if (bondedRole.getBondedRoleState() == BondedRoleState.READY_FOR_LOCKUP) { + if (bondedRole.getBondState() == BondState.READY_FOR_LOCKUP) { bondingViewUtils.lockupBondForBondedRole(role, txId -> { bondedRole.setLockupTxId(txId); - bondedRole.setBondedRoleState(BondedRoleState.LOCKUP_TX_PENDING); + bondedRole.setBondState(BondState.LOCKUP_TX_PENDING); update(); button.setDisable(true); }); - } else if (bondedRole.getBondedRoleState() == BondedRoleState.LOCKUP_TX_CONFIRMED) { + } else if (bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { bondingViewUtils.unLock(bondedRole.getLockupTxId(), txId -> { bondedRole.setUnlockTxId(txId); - bondedRole.setBondedRoleState(BondedRoleState.UNLOCK_TX_PENDING); + bondedRole.setBondState(BondState.UNLOCK_TX_PENDING); update(); button.setDisable(true); }); @@ -114,11 +114,10 @@ public void cleanup() { private void update() { - label.setText(Res.get("dao.bond.bondedRoleState." + bondedRole.getBondedRoleState().name())); + label.setText(Res.get("dao.bond.bondState." + bondedRole.getBondState().name())); - log.error("bondedRole.getLockupTxId()={}, bondedRole.getBondedRoleState()={}", bondedRole.getLockupTxId(), bondedRole.getBondedRoleState()); - boolean showLockup = bondedRole.getBondedRoleState() == BondedRoleState.READY_FOR_LOCKUP; - boolean showRevoke = bondedRole.getBondedRoleState() == BondedRoleState.LOCKUP_TX_CONFIRMED; + boolean showLockup = bondedRole.getBondState() == BondState.READY_FOR_LOCKUP; + boolean showRevoke = bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED; if (showLockup) button.updateText(Res.get("dao.bond.table.button.lockup")); else if (showRevoke) From 7bf5c819cdd5ca459a140ab4b9fc5d6a29d5377c Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 5 Nov 2018 18:35:30 -0500 Subject: [PATCH 18/27] Implements bonded reputation Still WIP with many areas... --- common/src/main/proto/pb.proto | 8 +- .../core/app/misc/AppSetupWithP2PAndDAO.java | 6 +- .../main/java/bisq/core/dao/DaoFacade.java | 55 +- .../main/java/bisq/core/dao/DaoModule.java | 4 + .../src/main/java/bisq/core/dao/DaoSetup.java | 84 ++- .../bisq/core/dao/governance/bond/Bond.java | 77 +++ .../dao/governance/bond/BondConsensus.java | 4 +- .../core/dao/governance/bond/BondService.java | 247 ++++++++ .../{BondWithHash.java => BondedAsset.java} | 9 +- .../governance/bond/lockup/LockupService.java | 26 +- .../bond/reputation/BondedReputation.java | 40 +- .../reputation/BondedReputationService.java | 176 ++---- .../bond/reputation/MyBondedReputation.java | 41 ++ .../reputation/MyBondedReputationService.java | 125 ++++ .../bond/reputation/MyReputation.java | 112 ++++ ...utationList.java => MyReputationList.java} | 28 +- .../reputation/MyReputationListService.java | 114 ++++ .../bond/reputation/Reputation.java | 58 +- .../dao/governance/bond/role/BondedRole.java | 30 +- .../bond/role/BondedRolesService.java | 200 +------ .../bisq/core/dao/node/parser/TxParser.java | 8 +- .../bisq/core/dao/state/DaoStateService.java | 6 + .../core/dao/state/model/blockchain/Tx.java | 15 +- .../core/dao/state/model/governance/Role.java | 15 +- .../CorePersistenceProtoResolver.java | 4 + .../core/setup/CorePersistedDataHost.java | 4 +- .../resources/i18n/displayStrings.properties | 13 +- .../i18n/displayStrings_de.properties | 2 +- .../i18n/displayStrings_el.properties | 2 +- .../i18n/displayStrings_es.properties | 2 +- .../i18n/displayStrings_fa.properties | 2 +- .../i18n/displayStrings_hu.properties | 2 +- .../i18n/displayStrings_pt.properties | 2 +- .../i18n/displayStrings_ro.properties | 2 +- .../i18n/displayStrings_ru.properties | 2 +- .../i18n/displayStrings_sr.properties | 2 +- .../i18n/displayStrings_th.properties | 2 +- .../i18n/displayStrings_vi.properties | 2 +- .../i18n/displayStrings_zh.properties | 2 +- .../desktop/main/dao/bonding/BondingView.java | 6 +- .../main/dao/bonding/BondingViewUtils.java | 18 +- .../main/dao/bonding/bonds/BondListItem.java | 159 +++-- .../main/dao/bonding/bonds/BondsView.java | 198 +++---- .../MyBondedReputationListItem.java | 132 +++++ ...nView.fxml => MyBondedReputationView.fxml} | 2 +- .../reputation/MyBondedReputationView.java | 554 ++++++++++++++++++ .../bonding/reputation/ReputationView.java | 228 ------- .../bonding/roles/BondedRolesListItem.java | 12 +- .../dao/bonding/roles/BondedRolesView.java | 26 +- .../main/dao/governance/ProposalDisplay.java | 20 +- .../dao/governance/make/MakeProposalView.java | 6 +- 51 files changed, 1897 insertions(+), 997 deletions(-) create mode 100644 core/src/main/java/bisq/core/dao/governance/bond/Bond.java create mode 100644 core/src/main/java/bisq/core/dao/governance/bond/BondService.java rename core/src/main/java/bisq/core/dao/governance/bond/{BondWithHash.java => BondedAsset.java} (82%) create mode 100644 core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputation.java create mode 100644 core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java create mode 100644 core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java rename core/src/main/java/bisq/core/dao/governance/bond/reputation/{ReputationList.java => MyReputationList.java} (64%) create mode 100644 core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java create mode 100644 desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java rename desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/{ReputationView.fxml => MyBondedReputationView.fxml} (97%) create mode 100644 desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java delete mode 100644 desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.java diff --git a/common/src/main/proto/pb.proto b/common/src/main/proto/pb.proto index 7191d23925b..51e0f1be1ec 100644 --- a/common/src/main/proto/pb.proto +++ b/common/src/main/proto/pb.proto @@ -943,7 +943,7 @@ message PersistableEnvelope { MeritList merit_list = 23; RemovedAssetList removed_asset_list = 24; DaoStateStore dao_state_store = 25; - ReputationList reputation_list = 26; + MyReputationList my_reputation_list = 26; } } @@ -1546,12 +1546,12 @@ message Role { string bonded_role_type = 4; // name of BondedRoleType enum } -message Reputation { +message MyReputation { bytes salt = 1; } -message ReputationList { - repeated Reputation reputation = 1; +message MyReputationList { + repeated MyReputation my_reputation = 1; } message TempProposalPayload { diff --git a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java index 0ac2aa50a59..5195ab90e84 100644 --- a/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java +++ b/core/src/main/java/bisq/core/app/misc/AppSetupWithP2PAndDAO.java @@ -22,7 +22,7 @@ import bisq.core.dao.governance.asset.AssetService; import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; -import bisq.core.dao.governance.bond.reputation.BondedReputationService; +import bisq.core.dao.governance.bond.reputation.MyReputationListService; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.proposal.MyProposalListService; import bisq.core.filter.FilterManager; @@ -55,7 +55,7 @@ public AppSetupWithP2PAndDAO(EncryptionService encryptionService, BallotListService ballotListService, MyBlindVoteListService myBlindVoteListService, MyProposalListService myProposalListService, - BondedReputationService bondedReputationService, + MyReputationListService myReputationListService, AssetService assetService, @Named(DaoOptionKeys.DAO_ACTIVATED) boolean daoActivated) { super(encryptionService, @@ -73,7 +73,7 @@ public AppSetupWithP2PAndDAO(EncryptionService encryptionService, persistedDataHosts.add(ballotListService); persistedDataHosts.add(myBlindVoteListService); persistedDataHosts.add(myProposalListService); - persistedDataHosts.add(bondedReputationService); + persistedDataHosts.add(myReputationListService); persistedDataHosts.add(assetService); } } diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index 2cc21777d5d..95e449f5ebd 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -24,11 +24,15 @@ import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.BlindVoteConsensus; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; -import bisq.core.dao.governance.bond.BondWithHash; +import bisq.core.dao.governance.bond.Bond; +import bisq.core.dao.governance.bond.BondedAsset; import bisq.core.dao.governance.bond.lockup.LockupService; import bisq.core.dao.governance.bond.lockup.LockupType; import bisq.core.dao.governance.bond.reputation.BondedReputation; import bisq.core.dao.governance.bond.reputation.BondedReputationService; +import bisq.core.dao.governance.bond.reputation.MyBondedReputation; +import bisq.core.dao.governance.bond.reputation.MyBondedReputationService; +import bisq.core.dao.governance.bond.reputation.MyReputationListService; import bisq.core.dao.governance.bond.role.BondedRole; import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.governance.bond.unlock.UnlockService; @@ -85,7 +89,7 @@ import javafx.collections.ObservableList; import javafx.collections.transformation.FilteredList; -import java.util.Collection; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Set; @@ -118,6 +122,8 @@ public class DaoFacade implements DaoSetupService { private final RemoveAssetProposalFactory removeAssetProposalFactory; private final BondedRolesService bondedRolesService; private final BondedReputationService bondedReputationService; + private final MyReputationListService myReputationListService; + private final MyBondedReputationService myBondedReputationService; private final LockupService lockupService; private final UnlockService unlockService; private final DaoStateStorageService daoStateStorageService; @@ -142,6 +148,8 @@ public DaoFacade(MyProposalListService myProposalListService, RemoveAssetProposalFactory removeAssetProposalFactory, BondedRolesService bondedRolesService, BondedReputationService bondedReputationService, + MyReputationListService myReputationListService, + MyBondedReputationService myBondedReputationService, LockupService lockupService, UnlockService unlockService, DaoStateStorageService daoStateStorageService) { @@ -162,6 +170,8 @@ public DaoFacade(MyProposalListService myProposalListService, this.removeAssetProposalFactory = removeAssetProposalFactory; this.bondedRolesService = bondedRolesService; this.bondedReputationService = bondedReputationService; + this.myReputationListService = myReputationListService; + this.myBondedReputationService = myBondedReputationService; this.lockupService = lockupService; this.unlockService = unlockService; this.daoStateStorageService = daoStateStorageService; @@ -282,12 +292,8 @@ public ProposalWithTransaction getRemoveAssetProposalWithTransaction(String name return removeAssetProposalFactory.createProposalWithTransaction(name, link, asset); } - public Collection getBondedRoles() { - return bondedRolesService.getBondedRoles(); - } - - public List getReputationList() { - return bondedReputationService.getReputationList(); + public List getBondedRoles() { + return bondedRolesService.getBonds(); } // Show fee @@ -487,9 +493,9 @@ public int getChainHeight() { // Use case: Bonding /////////////////////////////////////////////////////////////////////////////////////////// - public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, BondWithHash bondWithHash, + public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, BondedAsset bondedAsset, Consumer resultHandler, ExceptionHandler exceptionHandler) { - lockupService.publishLockupTx(lockupAmount, lockTime, lockupType, bondWithHash, resultHandler, exceptionHandler); + lockupService.publishLockupTx(lockupAmount, lockTime, lockupType, bondedAsset, resultHandler, exceptionHandler); } public void publishUnlockTx(String lockupTxId, Consumer resultHandler, @@ -513,13 +519,21 @@ public Optional getLockTime(String txId) { return daoStateService.getLockTime(txId); } - public List getActiveBondedRoles() { - return bondedRolesService.getActiveBondedRoles(); + public List getActiveBondedRoles() { + return bondedRolesService.getActiveBonds(); } - /*public List getValidBondedReputationList() { - return bondedReputationService.getValidBondedReputationList(); - }*/ + public List getAllActiveBonds() { + List activeReputations = bondedReputationService.getActiveBonds(); + List activeRoles = bondedRolesService.getActiveBonds(); + List bonds = new ArrayList<>(activeReputations); + bonds.addAll(activeRoles); + return bonds; + } + + public List getMyBondedReputations() { + return myBondedReputationService.getMyBondedReputations(); + } /////////////////////////////////////////////////////////////////////////////////////////// @@ -622,17 +636,6 @@ public boolean isUnspent(TxOutputKey key) { return daoStateService.isUnspent(key); } - public Optional getBondedRoleFromHash(byte[] hash) { - return bondedRolesService.getBondedRoleFromHash(hash); - } - - public Optional getBondedReputationFromHash(byte[] hash) { - return bondedReputationService.getBondedReputationFromHash(hash); - } - - /*public boolean isUnlocking(String unlockTxId) { - return daoStateService.isUnlocking(unlockTxId); - }*/ public Coin getMinCompensationRequestAmount() { return CompensationConsensus.getMinCompensationRequestAmount(daoStateService, periodService.getChainHeight()); diff --git a/core/src/main/java/bisq/core/dao/DaoModule.java b/core/src/main/java/bisq/core/dao/DaoModule.java index 90d7af1ca29..f29f582ac1b 100644 --- a/core/src/main/java/bisq/core/dao/DaoModule.java +++ b/core/src/main/java/bisq/core/dao/DaoModule.java @@ -28,6 +28,8 @@ import bisq.core.dao.governance.blindvote.storage.BlindVoteStore; import bisq.core.dao.governance.bond.lockup.LockupService; import bisq.core.dao.governance.bond.reputation.BondedReputationService; +import bisq.core.dao.governance.bond.reputation.MyBondedReputationService; +import bisq.core.dao.governance.bond.reputation.MyReputationListService; import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.governance.bond.unlock.UnlockService; import bisq.core.dao.governance.myvote.MyVoteListService; @@ -188,6 +190,8 @@ protected void configure() { bind(UnlockService.class).in(Singleton.class); bind(BondedRolesService.class).in(Singleton.class); bind(BondedReputationService.class).in(Singleton.class); + bind(MyReputationListService.class).in(Singleton.class); + bind(MyBondedReputationService.class).in(Singleton.class); // Asset bind(AssetService.class).in(Singleton.class); diff --git a/core/src/main/java/bisq/core/dao/DaoSetup.java b/core/src/main/java/bisq/core/dao/DaoSetup.java index d277b6aafa2..438ca7384e3 100644 --- a/core/src/main/java/bisq/core/dao/DaoSetup.java +++ b/core/src/main/java/bisq/core/dao/DaoSetup.java @@ -20,6 +20,10 @@ import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.BlindVoteListService; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; +import bisq.core.dao.governance.bond.reputation.BondedReputationService; +import bisq.core.dao.governance.bond.reputation.MyBondedReputationService; +import bisq.core.dao.governance.bond.reputation.MyReputationListService; +import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.governance.period.CycleService; import bisq.core.dao.governance.proposal.ProposalService; import bisq.core.dao.governance.voteresult.MissingDataRequestService; @@ -34,23 +38,16 @@ import com.google.inject.Inject; +import java.util.ArrayList; +import java.util.List; + /** * High level entry point for Dao domain. * We initialize all main service classes here to be sure they are started. */ public class DaoSetup { - private final DaoStateService daoStateService; - private final CycleService cycleService; - private final ProposalService proposalService; - private final BallotListService ballotListService; - private final BlindVoteListService blindVoteListService; - private final MyBlindVoteListService myBlindVoteListService; - private final VoteRevealService voteRevealService; - private final VoteResultService voteResultService; private final BsqNode bsqNode; - private final MissingDataRequestService missingDataRequestService; - private final DaoFacade daoFacade; - private final ExportJsonFilesService exportJsonFilesService; + private final List daoSetupServices = new ArrayList<>(); @Inject public DaoSetup(BsqNodeProvider bsqNodeProvider, @@ -63,52 +60,41 @@ public DaoSetup(BsqNodeProvider bsqNodeProvider, VoteRevealService voteRevealService, VoteResultService voteResultService, MissingDataRequestService missingDataRequestService, + BondedReputationService bondedReputationService, + BondedRolesService bondedRolesService, + MyReputationListService myReputationListService, + MyBondedReputationService myBondedReputationService, DaoFacade daoFacade, ExportJsonFilesService exportJsonFilesService) { - this.daoStateService = daoStateService; - this.cycleService = cycleService; - this.proposalService = proposalService; - this.ballotListService = ballotListService; - this.blindVoteListService = blindVoteListService; - this.myBlindVoteListService = myBlindVoteListService; - this.voteRevealService = voteRevealService; - this.voteResultService = voteResultService; - this.missingDataRequestService = missingDataRequestService; - this.daoFacade = daoFacade; - this.exportJsonFilesService = exportJsonFilesService; bsqNode = bsqNodeProvider.getBsqNode(); + + // We need to take care of order of execution. + daoSetupServices.add(daoStateService); + daoSetupServices.add(cycleService); + daoSetupServices.add(proposalService); + daoSetupServices.add(ballotListService); + daoSetupServices.add(blindVoteListService); + daoSetupServices.add(myBlindVoteListService); + daoSetupServices.add(voteRevealService); + daoSetupServices.add(voteResultService); + daoSetupServices.add(missingDataRequestService); + daoSetupServices.add(bondedReputationService); + daoSetupServices.add(bondedRolesService); + daoSetupServices.add(myReputationListService); + daoSetupServices.add(myBondedReputationService); + daoSetupServices.add(daoFacade); + daoSetupServices.add(exportJsonFilesService); + daoSetupServices.add(bsqNodeProvider.getBsqNode()); } public void onAllServicesInitialized(ErrorMessageHandler errorMessageHandler) { - // We need to take care of order of execution. Let's keep both addListeners and start for all main classes even - // if they are not used to have a consistent startup sequence. - daoStateService.addListeners(); - cycleService.addListeners(); - proposalService.addListeners(); - ballotListService.addListeners(); - blindVoteListService.addListeners(); - myBlindVoteListService.addListeners(); - voteRevealService.addListeners(); - voteResultService.addListeners(); - missingDataRequestService.addListeners(); - daoFacade.addListeners(); - exportJsonFilesService.addListeners(); - - daoStateService.start(); - cycleService.start(); - proposalService.start(); - ballotListService.start(); - blindVoteListService.start(); - myBlindVoteListService.start(); - voteRevealService.start(); - voteResultService.start(); - missingDataRequestService.start(); - daoFacade.start(); - exportJsonFilesService.start(); - bsqNode.setErrorMessageHandler(errorMessageHandler); - bsqNode.start(); + + daoSetupServices.forEach(daoSetupServices -> { + daoSetupServices.addListeners(); + daoSetupServices.start(); + }); } public void shutDown() { diff --git a/core/src/main/java/bisq/core/dao/governance/bond/Bond.java b/core/src/main/java/bisq/core/dao/governance/bond/Bond.java new file mode 100644 index 00000000000..adbe0ce4567 --- /dev/null +++ b/core/src/main/java/bisq/core/dao/governance/bond/Bond.java @@ -0,0 +1,77 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.governance.bond; + +import bisq.core.locale.Res; + +import lombok.Getter; +import lombok.Setter; + +import javax.annotation.Nullable; + +/** + * Base class for BondedRole and BondedAsset. Holds the bond state of the bonded asset. + */ +@Getter +public abstract class Bond { + @Getter + protected final T bondedAsset; + @Setter + @Nullable + protected String lockupTxId; + @Setter + @Nullable + protected String unlockTxId; + @Setter + protected BondState bondState = BondState.READY_FOR_LOCKUP; + @Setter + private long amount; + @Setter + private long lockupDate; + @Setter + private long unlockDate; + @Setter + private int lockTime; + + + public Bond(T bondedAsset) { + this.bondedAsset = bondedAsset; + } + + public boolean isActive() { + return bondState != BondState.READY_FOR_LOCKUP && + bondState != BondState.UNLOCKED; + } + + public String getDisplayString() { + return Res.get("dao.bonding.info", lockupTxId, getBondedAsset().getDisplayString()); + } + + @Override + public String toString() { + return "Bond{" + + "\n bondedAsset=" + bondedAsset + + ",\n lockupTxId='" + lockupTxId + '\'' + + ",\n unlockTxId='" + unlockTxId + '\'' + + ",\n bondState=" + bondState + + ",\n amount=" + amount + + ",\n lockupDate=" + lockupDate + + ",\n unlockDate=" + unlockDate + + "\n}"; + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java b/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java index 3fc1d8c9b13..f0d77b5564a 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java @@ -88,7 +88,7 @@ public static byte[] getHashFromOpReturnData(byte[] opReturnData) { return Arrays.copyOfRange(opReturnData, 5, 25); } - public static byte[] getHash(BondWithHash bondWithHash) { - return bondWithHash.getHash(); + public static byte[] getHash(BondedAsset bondedAsset) { + return bondedAsset.getHash(); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondService.java b/core/src/main/java/bisq/core/dao/governance/bond/BondService.java new file mode 100644 index 00000000000..c7ec3978e9e --- /dev/null +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondService.java @@ -0,0 +1,247 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.governance.bond; + +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoSetupService; +import bisq.core.dao.state.DaoStateListener; +import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.blockchain.BaseTxOutput; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.state.model.blockchain.SpentInfo; +import bisq.core.dao.state.model.blockchain.TxOutput; +import bisq.core.dao.state.model.blockchain.TxType; + +import org.bitcoinj.core.Transaction; +import org.bitcoinj.core.TransactionConfidence; +import org.bitcoinj.core.TransactionInput; +import org.bitcoinj.core.TransactionOutput; + +import javax.inject.Inject; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import lombok.extern.slf4j.Slf4j; + +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Manages bonds. + */ +@Slf4j +public abstract class BondService implements DaoStateListener, DaoSetupService { + protected final DaoStateService daoStateService; + protected final BsqWalletService bsqWalletService; + + // This map is just for convenience. The data which are used to fill the map are stored in the DaoState (role, txs). + protected final Map bondByUidMap = new HashMap<>(); + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + public BondService(DaoStateService daoStateService, BsqWalletService bsqWalletService) { + this.daoStateService = daoStateService; + this.bsqWalletService = bsqWalletService; + + daoStateService.addBsqStateListener(this); + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // DaoSetupService + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void addListeners() { + } + + @Override + public void start() { + updateMap(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // DaoStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onParseTxsComplete(Block block) { + // TODO optimize to not re-write the whole map at each block + updateMap(); + } + + protected void updateMap() { + getBondedAssetStream().forEach(bondedAsset -> { + String uid = bondedAsset.getUid(); + bondByUidMap.putIfAbsent(uid, createBond(bondedAsset)); + T bond = bondByUidMap.get(uid); + + daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> { + updateBond(bond, bondedAsset, lockupTxOutput); + }); + }); + + updateBondStateFromUnconfirmedLockupTxs(); + updateBondStateFromUnconfirmedUnlockTxs(); + } + + public void updateBond(T bond, R bondedAsset, TxOutput lockupTxOutput) { + // Lets see if we have a lock up tx. + String lockupTxId = lockupTxOutput.getTxId(); + daoStateService.getTx(lockupTxId).ifPresent(lockupTx -> { + byte[] opReturnData = lockupTx.getLastTxOutput().getOpReturnData(); + // We used the hash of th bonded bondedAsset object as our hash in OpReturn of the lock up tx to have a + // unique binding of the tx to the data object. + byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); + Optional candidate = findBondedAssetByHash(hash); + if (candidate.isPresent() && bondedAsset.equals(candidate.get())) { + bond.setBondState(BondState.LOCKUP_TX_CONFIRMED); + bond.setLockupTxId(lockupTx.getId()); + // We use the tx time as we want to have a unique time for all users + bond.setLockupDate(lockupTx.getTime()); + bond.setAmount(lockupTx.getLockedAmount()); + bond.setLockTime(lockupTx.getLockTime()); + if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { + // Lockup is already spent (in unlock tx) + daoStateService.getSpentInfo(lockupTxOutput) + .map(SpentInfo::getTxId) + .flatMap(daoStateService::getTx) + .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) + .ifPresent(unlockTx -> { + // cross check if it is in daoStateService.getUnlockTxOutputs() ? + String unlockTxId = unlockTx.getId(); + bond.setUnlockTxId(unlockTxId); + bond.setBondState(BondState.UNLOCK_TX_CONFIRMED); + bond.setUnlockDate(unlockTx.getTime()); + boolean unlocking = daoStateService.isUnlocking(unlockTxId); + if (unlocking) { + bond.setBondState(BondState.UNLOCKING); + } else { + bond.setBondState(BondState.UNLOCKED); + } + }); + } + } + }); + } + + protected abstract T createBond(R bondedAsset); + + @Override + public void onParseBlockChainComplete() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + public List getBonds() { + return new ArrayList<>(bondByUidMap.values()); + } + + public List getActiveBonds() { + return bondByUidMap.values().stream() + .filter(T::isActive) + .collect(Collectors.toList()); + } + + public Optional findBondByLockupTxId(String lockupTxId) { + return bondByUidMap.values().stream() + .filter(bond -> lockupTxId.equals(bond.getLockupTxId())) + .findAny(); + } + + public boolean wasBondedAssetAlreadyBonded(R bondedAsset) { + T bond = bondByUidMap.get(bondedAsset.getUid()); + checkArgument(bond != null, "bond must not be null"); + return bond.getLockupTxId() != null; + } + + public Optional findBondedAssetByHash(byte[] hash) { + return getBondedAssetStream() + .filter(bondedAsset -> Arrays.equals(bondedAsset.getHash(), hash)) + .findAny(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void updateBondStateFromUnconfirmedLockupTxs() { + getBondedAssetStream().filter(this::isLockupTxUnconfirmed) + .map(bondedAsset -> bondByUidMap.get(bondedAsset.getUid())) + .filter(bond -> bond.getBondState() == BondState.READY_FOR_LOCKUP) + .forEach(bond -> bond.setBondState(BondState.LOCKUP_TX_PENDING)); + } + + private void updateBondStateFromUnconfirmedUnlockTxs() { + getBondedAssetStream().filter(this::isUnlockTxUnconfirmed) + .map(bondedAsset -> bondByUidMap.get(bondedAsset.getUid())) + .filter(bond -> bond.getBondState() == BondState.LOCKUP_TX_CONFIRMED) + .forEach(bond -> bond.setBondState(BondState.UNLOCK_TX_PENDING)); + } + + abstract protected Stream getBondedAssetStream(); + + + public boolean isLockupTxUnconfirmed(R bondedAsset) { + return getPendingWalletTransactionsStream() + .map(transaction -> transaction.getOutputs().get(transaction.getOutputs().size() - 1)) + .filter(lastOutput -> lastOutput.getScriptPubKey().isOpReturn()) + .map(lastOutput -> lastOutput.getScriptPubKey().getChunks()) + .filter(chunks -> chunks.size() > 1) + .map(chunks -> chunks.get(1).data) + .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondedAsset.getHash())); + } + + private boolean isUnlockTxUnconfirmed(R bondedAsset) { + return getPendingWalletTransactionsStream() + .filter(transaction -> transaction.getInputs().size() > 1) + .map(transaction -> transaction.getInputs().get(0)) + .map(TransactionInput::getConnectedOutput) + .filter(Objects::nonNull) + .map(TransactionOutput::getParentTransaction) + .filter(Objects::nonNull) + .map(Transaction::getHashAsString) + .flatMap(lockupTxId -> daoStateService.getLockupOpReturnTxOutput(lockupTxId).stream()) + .map(BaseTxOutput::getOpReturnData) + .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondedAsset.getHash())); + } + + private Stream getPendingWalletTransactionsStream() { + return bsqWalletService.getWalletTransactions().stream() + .filter(transaction -> transaction.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.PENDING); + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondWithHash.java b/core/src/main/java/bisq/core/dao/governance/bond/BondedAsset.java similarity index 82% rename from core/src/main/java/bisq/core/dao/governance/bond/BondWithHash.java rename to core/src/main/java/bisq/core/dao/governance/bond/BondedAsset.java index 592d6f69c7a..78689cc1770 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondWithHash.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondedAsset.java @@ -17,6 +17,13 @@ package bisq.core.dao.governance.bond; -public interface BondWithHash { +/** + * Interface of the bonded asset like the Role or Reputation. + */ +public interface BondedAsset { byte[] getHash(); + + String getUid(); + + String getDisplayString(); } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java index c183c9b602f..2e95c44e410 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java @@ -26,9 +26,9 @@ import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsManager; import bisq.core.dao.governance.bond.BondConsensus; -import bisq.core.dao.governance.bond.BondWithHash; -import bisq.core.dao.governance.bond.reputation.BondedReputationService; -import bisq.core.dao.governance.bond.reputation.Reputation; +import bisq.core.dao.governance.bond.BondedAsset; +import bisq.core.dao.governance.bond.reputation.MyReputation; +import bisq.core.dao.governance.bond.reputation.MyReputationListService; import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.state.model.governance.Role; @@ -53,7 +53,7 @@ public class LockupService { private final WalletsManager walletsManager; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; - private final BondedReputationService bondedReputationService; + private final MyReputationListService myReputationListService; private final BondedRolesService bondedRolesService; @@ -65,30 +65,30 @@ public class LockupService { public LockupService(WalletsManager walletsManager, BsqWalletService bsqWalletService, BtcWalletService btcWalletService, - BondedReputationService bondedReputationService, + MyReputationListService myReputationListService, BondedRolesService bondedRolesService) { this.walletsManager = walletsManager; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; - this.bondedReputationService = bondedReputationService; + this.myReputationListService = myReputationListService; this.bondedRolesService = bondedRolesService; } - public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, BondWithHash bondWithHash, + public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, BondedAsset bondedAsset, Consumer resultHandler, ExceptionHandler exceptionHandler) { checkArgument(lockTime <= BondConsensus.getMaxLockTime() && lockTime >= BondConsensus.getMinLockTime(), "lockTime not in rage"); - if (bondWithHash instanceof Role) { - Role role = (Role) bondWithHash; - if (bondedRolesService.wasRoleAlreadyBonded(role)) { + if (bondedAsset instanceof Role) { + Role role = (Role) bondedAsset; + if (bondedRolesService.wasBondedAssetAlreadyBonded(role)) { exceptionHandler.handleException(new RuntimeException("The role has been used already for a lockup tx.")); return; } - } else if (bondWithHash instanceof Reputation) { - bondedReputationService.addReputation((Reputation) bondWithHash); + } else if (bondedAsset instanceof MyReputation) { + myReputationListService.addReputation((MyReputation) bondedAsset); } - byte[] hash = BondConsensus.getHash(bondWithHash); + byte[] hash = BondConsensus.getHash(bondedAsset); try { byte[] opReturnData = BondConsensus.getLockupOpReturnData(lockTime, lockupType, hash); Transaction lockupTx = createLockupTx(lockupAmount, opReturnData); diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java index f2f09d65ec0..85053f5ac14 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java @@ -17,54 +17,26 @@ package bisq.core.dao.governance.bond.reputation; -import bisq.core.locale.Res; +import bisq.core.dao.governance.bond.Bond; +import lombok.EqualsAndHashCode; import lombok.Getter; -import lombok.Setter; - -import javax.annotation.Nullable; /** * Wrapper for reputation which contains the mutable state of a bonded reputation. Only kept in memory. */ @Getter -public final class BondedReputation { - private final Reputation reputation; - @Nullable - @Setter - private String lockupTxId; - @Nullable - @Setter - private String unlockTxId; +@EqualsAndHashCode(callSuper = true) +public final class BondedReputation extends Bond { public BondedReputation(Reputation reputation) { - this.reputation = reputation; - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // API - /////////////////////////////////////////////////////////////////////////////////////////// - - public String getDisplayString() { - return Res.get("dao.bond.bondedReputation"); - } - - public boolean isLockedUp() { - return lockupTxId != null; - } - - public boolean isUnlocked() { - return unlockTxId != null; + super(reputation); } @Override public String toString() { return "BondedReputation{" + - "\n reputation='" + reputation + '\'' + - ",\n lockupTxId='" + lockupTxId + '\'' + - ",\n unlockTxId='" + unlockTxId + '\'' + - "\n}"; + "\n} " + super.toString(); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java index 5ba76a7ae42..44ebafdb93d 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java @@ -17,162 +17,110 @@ package bisq.core.dao.governance.bond.reputation; -import bisq.core.app.BisqEnvironment; -import bisq.core.dao.state.DaoStateListener; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.governance.bond.Bond; +import bisq.core.dao.governance.bond.BondConsensus; +import bisq.core.dao.governance.bond.BondService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.model.blockchain.Block; - -import bisq.common.proto.persistable.PersistedDataHost; -import bisq.common.storage.Storage; +import bisq.core.dao.state.model.blockchain.TxOutput; import javax.inject.Inject; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; -import java.util.concurrent.CopyOnWriteArrayList; +import java.util.stream.Collectors; +import java.util.stream.Stream; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; @Slf4j -public class BondedReputationService implements PersistedDataHost, DaoStateListener { - - public interface ReputationListChangeListener { - void onListChanged(List list); - } - - private final DaoStateService daoStateService; - private final Storage storage; - private final ReputationList reputationList = new ReputationList(); - - @Getter - private final List listeners = new CopyOnWriteArrayList<>(); - +public class BondedReputationService extends BondService { /////////////////////////////////////////////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public BondedReputationService(Storage storage, DaoStateService daoStateService) { - this.storage = storage; - this.daoStateService = daoStateService; + public BondedReputationService(DaoStateService daoStateService, BsqWalletService bsqWalletService) { + super(daoStateService, bsqWalletService); - daoStateService.addBsqStateListener(this); } - /////////////////////////////////////////////////////////////////////////////////////////// - // PersistedDataHost + // API /////////////////////////////////////////////////////////////////////////////////////////// - @Override - public void readPersisted() { - if (BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq()) { - ReputationList persisted = storage.initAndGetPersisted(reputationList, 100); - if (persisted != null) { - reputationList.clear(); - reputationList.addAll(persisted.getList()); - listeners.forEach(l -> l.onListChanged(reputationList.getList())); - } - } + public List getActiveBondedReputations() { + return bondByUidMap.values().stream() + .filter(e -> e.isActive()) + .collect(Collectors.toList()); } - /////////////////////////////////////////////////////////////////////////////////////////// - // DaoStateListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onNewBlockHeight(int blockHeight) { + public List getAllBondedReputations() { + return new ArrayList<>(bondByUidMap.values()); } - @Override - public void onParseTxsComplete(Block block) { - /* bondedReputationList.getList().forEach(bondedReputation -> { - daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> { - String lockupTxId = lockupTxOutput.getTxId(); - daoStateService.getTx(lockupTxId) - .ifPresent(lockupTx -> { - byte[] opReturnData = lockupTx.getLastTxOutput().getOpReturnData(); - byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); - Optional candidate = getBondedReputationFromHash(hash); - if (candidate.isPresent() && bondedReputation.equals(candidate.get())) { - if (bondedReputation.getLockupTxId() == null) { - bondedReputation.setLockupTxId(lockupTxId); - persist(); - } - - if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { - daoStateService.getSpentInfo(lockupTxOutput) - .map(SpentInfo::getTxId) - .map(daoStateService::getTx) - .map(Optional::get) - // TODO(sq): What if the tx is burnt and not unlocked, need to check on that - .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) - .ifPresent(unlockTx -> { - if (bondedReputation.getUnlockTxId() == null) { - bondedReputation.setUnlockTxId(unlockTx.getId()); - persist(); - } - - // TODO check lock time - }); - } - } - }); - }); - });*/ - } - - @Override - public void onParseBlockChainComplete() { + public List getUnconfirmedBondedReputations() { + //TODO + /* Set myWalletTransactionIds = bsqWalletService.getWalletTransactions().stream() + .map(Transaction::getHashAsString) + .collect(Collectors.toSet()); +*/ + return bondByUidMap.values().stream() + .filter(e -> e.isActive()) + .collect(Collectors.toList()); } /////////////////////////////////////////////////////////////////////////////////////////// - // API + // Protected /////////////////////////////////////////////////////////////////////////////////////////// - public void start() { + @Override + protected BondedReputation createBond(Reputation reputation) { + return new BondedReputation(reputation); } - public void addListener(ReputationListChangeListener listener) { - listeners.add(listener); + @Override + protected Stream getBondedAssetStream() { + return getBondedReputationStream().map(Bond::getBondedAsset); } - public void addReputation(Reputation reputation) { - if (!reputationList.contains(reputation)) { - reputationList.add(reputation); - persist(); - } + @Override + protected void updateMap() { + bondByUidMap.clear(); + getBondedReputationStream().forEach(bondedReputation -> { + bondByUidMap.put(bondedReputation.getBondedAsset().getUid(), bondedReputation); + }); } - public List getReputationList() { - return new ArrayList<>(); //bondedReputationList.getList(); - } - public Optional getBondedReputationFromHash(byte[] hash) { - return Optional.empty(); - /* - return bondedReputationList.getList().stream() - .filter(bondedReputation -> { - byte[] candidateHash = bondedReputation.getHash(); - *//* log.error("getBondedReputationFromHash: equals?={}, hash={}, candidateHash={}\bondedReputation={}", - Arrays.equals(candidateHash, hash), - Utilities.bytesAsHexString(hash), - Utilities.bytesAsHexString(candidateHash), - bondedReputation.toString());*//* - return Arrays.equals(candidateHash, hash); + private Stream getBondedReputationStream() { + return daoStateService.getLockupTxOutputs().stream() + .map(lockupTxOutput -> { + String txId = lockupTxOutput.getTxId(); + // long time = daoStateService.getTx(txId).map(BaseTx::getTime).orElse(0L); + // lockupTxOutput is first output, but we need the data from the opReturn + Optional optionalOpReturnTxOutput = daoStateService.getLockupOpReturnTxOutput(txId); + if (optionalOpReturnTxOutput.isPresent()) { + TxOutput opReturnTxOutput = optionalOpReturnTxOutput.get(); + byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnTxOutput.getOpReturnData()); + Reputation reputation = new Reputation(hash); + BondedReputation bondedReputation = new BondedReputation(reputation); + updateBond(bondedReputation, reputation, lockupTxOutput); + return bondedReputation; + } else { + return null; + } + }) - .findAny();*/ + .filter(Objects::nonNull); } - /////////////////////////////////////////////////////////////////////////////////////////// - // Private - /////////////////////////////////////////////////////////////////////////////////////////// - - private void persist() { - storage.queueUpForSave(20); + @Override + public Optional findBondedAssetByHash(byte[] hash) { + return Optional.of(new Reputation(hash)); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputation.java new file mode 100644 index 00000000000..3c564510803 --- /dev/null +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputation.java @@ -0,0 +1,41 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.governance.bond.reputation; + +import bisq.core.dao.governance.bond.Bond; + +import lombok.EqualsAndHashCode; +import lombok.Getter; + +/** + * Wrapper for reputation which contains the mutable state of a bonded reputation. Only kept in memory. + */ +@Getter +@EqualsAndHashCode(callSuper = true) +public final class MyBondedReputation extends Bond { + + public MyBondedReputation(MyReputation myReputation) { + super(myReputation); + } + + @Override + public String toString() { + return "MyBondedReputation{" + + "\n} " + super.toString(); + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java new file mode 100644 index 00000000000..cd8da8118bf --- /dev/null +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java @@ -0,0 +1,125 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.governance.bond.reputation; + +import bisq.core.dao.DaoSetupService; +import bisq.core.dao.governance.bond.BondConsensus; +import bisq.core.dao.governance.bond.BondState; +import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.blockchain.SpentInfo; +import bisq.core.dao.state.model.blockchain.TxType; + +import javax.inject.Inject; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MyBondedReputationService implements DaoSetupService { + private final DaoStateService daoStateService; + private final MyReputationListService myReputationListService; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + public MyBondedReputationService(DaoStateService daoStateService, + MyReputationListService myReputationListService) { + this.daoStateService = daoStateService; + this.myReputationListService = myReputationListService; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // DaoSetupService + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void addListeners() { + } + + @Override + public void start() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + public List getMyBondedReputations() { + return myReputationListService.getMyReputationList().stream() + .map(myReputation -> getMyBondedReputation(myReputation).orElse(null)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + private Optional getMyBondedReputation(MyReputation myReputation) { + return daoStateService.getLockupTxOutputs().stream() + .map(lockupTxOutput -> { + String lockupTxId = lockupTxOutput.getTxId(); + return daoStateService.getTx(lockupTxId) + .map(lockupTx -> { + byte[] opReturnData = lockupTx.getLastTxOutput().getOpReturnData(); + byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); + if (Arrays.equals(hash, myReputation.getHash())) { + MyBondedReputation myBondedReputation = new MyBondedReputation(myReputation); + myBondedReputation.setLockTime(lockupTx.getLockTime()); + myBondedReputation.setBondState(BondState.LOCKUP_TX_CONFIRMED); + myBondedReputation.setLockupTxId(lockupTx.getId()); + // We use the tx time as we want to have a unique time for all users + myBondedReputation.setLockupDate(lockupTx.getTime()); + myBondedReputation.setAmount(lockupTx.getLockedAmount()); + if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { + // Lockup is already spent (in unlock tx) + daoStateService.getSpentInfo(lockupTxOutput) + .map(SpentInfo::getTxId) + .flatMap(daoStateService::getTx) + .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) + .ifPresent(unlockTx -> { + // cross check if it is in daoStateService.getUnlockTxOutputs() ? + String unlockTxId = unlockTx.getId(); + myBondedReputation.setUnlockTxId(unlockTxId); + myBondedReputation.setBondState(BondState.UNLOCK_TX_CONFIRMED); + myBondedReputation.setUnlockDate(unlockTx.getTime()); + boolean unlocking = daoStateService.isUnlocking(unlockTxId); + if (unlocking) { + myBondedReputation.setBondState(BondState.UNLOCKING); + } else { + myBondedReputation.setBondState(BondState.UNLOCKED); + } + }); + } + return myBondedReputation; + } else { + return null; + } + }) + .orElse(null); + }) + .filter(Objects::nonNull) + .findAny(); + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java new file mode 100644 index 00000000000..2edfaace643 --- /dev/null +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java @@ -0,0 +1,112 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.governance.bond.reputation; + +import bisq.core.dao.governance.bond.BondedAsset; + +import bisq.common.crypto.Hash; +import bisq.common.proto.network.NetworkPayload; +import bisq.common.proto.persistable.PersistablePayload; +import bisq.common.util.Utilities; + +import io.bisq.generated.protobuffer.PB; + +import com.google.protobuf.ByteString; + +import java.util.Arrays; + +import lombok.Value; +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.concurrent.Immutable; + +@Immutable +@Value +@Slf4j +public final class MyReputation implements PersistablePayload, NetworkPayload, BondedAsset { + private final byte[] salt; + private final transient byte[] hash; // not persisted as it is derived from salt. Stored for caching purpose only. + + + public MyReputation(byte[] salt) { + this.salt = salt; + this.hash = Hash.getSha256Ripemd160hash(salt); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // PROTO BUFFER + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public PB.MyReputation toProtoMessage() { + return PB.MyReputation.newBuilder().setSalt(ByteString.copyFrom(salt)).build(); + } + + public static MyReputation fromProto(PB.MyReputation proto) { + return new MyReputation(proto.getSalt().toByteArray()); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // BondedAsset implementation + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public byte[] getHash() { + return hash; + } + + @Override + public String getDisplayString() { + return Utilities.bytesAsHexString(hash); + } + + @Override + public String getUid() { + return Utilities.bytesAsHexString(hash); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof MyReputation)) return false; + if (!super.equals(o)) return false; + MyReputation that = (MyReputation) o; + return Arrays.equals(hash, that.hash); + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + Arrays.hashCode(hash); + return result; + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public String toString() { + return "MyReputation{" + + "\n salt=" + Utilities.bytesAsHexString(salt) + + "\n hash=" + Utilities.bytesAsHexString(hash) + + "\n}"; + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/ReputationList.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationList.java similarity index 64% rename from core/src/main/java/bisq/core/dao/governance/bond/reputation/ReputationList.java rename to core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationList.java index 88c88cf08f9..e2c1e46d1d1 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/ReputationList.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationList.java @@ -28,16 +28,16 @@ import lombok.EqualsAndHashCode; /** - * PersistableEnvelope wrapper for list of Reputations. + * PersistableEnvelope wrapper for list of MyReputations. */ @EqualsAndHashCode(callSuper = true) -public class ReputationList extends PersistableList { +public class MyReputationList extends PersistableList { - public ReputationList(List list) { + public MyReputationList(List list) { super(list); } - public ReputationList() { + public MyReputationList() { super(); } @@ -48,26 +48,26 @@ public ReputationList() { @Override public PB.PersistableEnvelope toProtoMessage() { - return PB.PersistableEnvelope.newBuilder().setReputationList(getBuilder()).build(); + return PB.PersistableEnvelope.newBuilder().setMyReputationList(getBuilder()).build(); } - public PB.ReputationList.Builder getBuilder() { - return PB.ReputationList.newBuilder() - .addAllReputation(getList().stream() - .map(Reputation::toProtoMessage) + public PB.MyReputationList.Builder getBuilder() { + return PB.MyReputationList.newBuilder() + .addAllMyReputation(getList().stream() + .map(MyReputation::toProtoMessage) .collect(Collectors.toList())); } - public static ReputationList fromProto(PB.ReputationList proto) { - return new ReputationList(new ArrayList<>(proto.getReputationList().stream() - .map(Reputation::fromProto) + public static MyReputationList fromProto(PB.MyReputationList proto) { + return new MyReputationList(new ArrayList<>(proto.getMyReputationList().stream() + .map(MyReputation::fromProto) .collect(Collectors.toList()))); } @Override public String toString() { - return "List of salts in ReputationList: " + getList().stream() - .map(Reputation::getSalt) + return "List of salts in MyReputationList: " + getList().stream() + .map(MyReputation::getSalt) .collect(Collectors.toList()); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java new file mode 100644 index 00000000000..d9a07eb068e --- /dev/null +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java @@ -0,0 +1,114 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.core.dao.governance.bond.reputation; + +import bisq.core.app.BisqEnvironment; +import bisq.core.dao.DaoSetupService; + +import bisq.common.proto.persistable.PersistedDataHost; +import bisq.common.storage.Storage; + +import javax.inject.Inject; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class MyReputationListService implements PersistedDataHost, DaoSetupService { + + public interface MyReputationListChangeListener { + void onListChanged(List list); + } + + private final Storage storage; + private final MyReputationList myReputationList = new MyReputationList(); + + @Getter + private final List listeners = new CopyOnWriteArrayList<>(); + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + public MyReputationListService(Storage storage) { + this.storage = storage; + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // PersistedDataHost + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void readPersisted() { + if (BisqEnvironment.isDAOActivatedAndBaseCurrencySupportingBsq()) { + MyReputationList persisted = storage.initAndGetPersisted(myReputationList, 100); + if (persisted != null) { + myReputationList.clear(); + myReputationList.addAll(persisted.getList()); + listeners.forEach(l -> l.onListChanged(myReputationList.getList())); + } + } + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // DaoSetupService + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void addListeners() { + } + + @Override + public void start() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + + public void addListener(MyReputationListChangeListener listener) { + listeners.add(listener); + } + + public void addReputation(MyReputation reputation) { + if (!myReputationList.contains(reputation)) { + myReputationList.add(reputation); + persist(); + } + } + + public List getMyReputationList() { + return myReputationList.getList(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void persist() { + storage.queueUpForSave(20); + } +} diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java index f44f40a361d..1cc5d9c0958 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java @@ -17,60 +17,70 @@ package bisq.core.dao.governance.bond.reputation; -import bisq.core.dao.governance.bond.BondWithHash; +import bisq.core.dao.governance.bond.BondedAsset; -import bisq.common.crypto.Hash; -import bisq.common.proto.network.NetworkPayload; -import bisq.common.proto.persistable.PersistablePayload; import bisq.common.util.Utilities; -import io.bisq.generated.protobuffer.PB; - -import com.google.protobuf.ByteString; +import java.util.Arrays; import lombok.Value; +import lombok.extern.slf4j.Slf4j; import javax.annotation.concurrent.Immutable; +/** + * Reputation objects we found on the blockchain. We only know the hash of it. + */ @Immutable @Value -public final class Reputation implements PersistablePayload, NetworkPayload, BondWithHash { - private final byte[] salt; +@Slf4j +public final class Reputation implements BondedAsset { + private final byte[] hash; - public Reputation(byte[] salt) { - this.salt = salt; + public Reputation(byte[] hash) { + this.hash = hash; } /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER + // BondedAsset implementation /////////////////////////////////////////////////////////////////////////////////////////// @Override - public PB.Reputation toProtoMessage() { - PB.Reputation.Builder builder = PB.Reputation.newBuilder() - .setSalt(ByteString.copyFrom(salt)); - return builder.build(); + public byte[] getHash() { + return hash; } - public static Reputation fromProto(PB.Reputation proto) { - return new Reputation(proto.getSalt().toByteArray()); + @Override + public String getDisplayString() { + return Utilities.bytesAsHexString(hash); } + @Override + public String getUid() { + return Utilities.bytesAsHexString(hash); + } - /////////////////////////////////////////////////////////////////////////////////////////// - // API - /////////////////////////////////////////////////////////////////////////////////////////// + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Reputation)) return false; + if (!super.equals(o)) return false; + Reputation that = (Reputation) o; + return Arrays.equals(hash, that.hash); + } @Override - public byte[] getHash() { - return Hash.getSha256Ripemd160hash(salt); + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + Arrays.hashCode(hash); + return result; } @Override public String toString() { return "Reputation{" + - "\n salt=" + Utilities.bytesAsHexString(salt) + + "\n hash=" + Utilities.bytesAsHexString(hash) + "\n}"; } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRole.java b/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRole.java index 84995bf6c78..f5a7026241e 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRole.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRole.java @@ -17,34 +17,26 @@ package bisq.core.dao.governance.bond.role; -import bisq.core.dao.governance.bond.BondState; +import bisq.core.dao.governance.bond.Bond; import bisq.core.dao.state.model.governance.Role; +import lombok.EqualsAndHashCode; import lombok.Getter; -import lombok.Setter; - -import javax.annotation.Nullable; /** * Wrapper for role which contains the mutable state of a bonded role. Only kept in memory. */ @Getter -public class BondedRole { - private final Role role; - @Setter - @Nullable - private String lockupTxId; - @Setter - @Nullable - private String unlockTxId; - @Setter - private long startDate; - @Setter - private long revokeDate; - @Setter - private BondState bondState = BondState.READY_FOR_LOCKUP; +@EqualsAndHashCode(callSuper = true) +public class BondedRole extends Bond { BondedRole(Role role) { - this.role = role; + super(role); + } + + @Override + public String toString() { + return "BondedRole{" + + "\n} " + super.toString(); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesService.java b/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesService.java index 000afc4a5b0..86754757b97 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesService.java @@ -18,33 +18,18 @@ package bisq.core.dao.governance.bond.role; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.governance.bond.BondConsensus; -import bisq.core.dao.governance.bond.BondState; -import bisq.core.dao.governance.bond.BondWithHash; -import bisq.core.dao.state.DaoStateListener; +import bisq.core.dao.governance.bond.Bond; +import bisq.core.dao.governance.bond.BondService; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.model.blockchain.BaseTxOutput; -import bisq.core.dao.state.model.blockchain.Block; -import bisq.core.dao.state.model.blockchain.SpentInfo; -import bisq.core.dao.state.model.blockchain.TxType; import bisq.core.dao.state.model.governance.BondedRoleType; import bisq.core.dao.state.model.governance.Proposal; import bisq.core.dao.state.model.governance.Role; import bisq.core.dao.state.model.governance.RoleProposal; import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionConfidence; -import org.bitcoinj.core.TransactionInput; -import org.bitcoinj.core.TransactionOutput; import javax.inject.Inject; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -52,19 +37,11 @@ import lombok.extern.slf4j.Slf4j; -import static com.google.common.base.Preconditions.checkArgument; - /** * Manages bonded roles if they got accepted by voting. */ @Slf4j -public class BondedRolesService implements DaoStateListener { - private final DaoStateService daoStateService; - private final BsqWalletService bsqWalletService; - - // This map is just for convenience. The data which are used to fill the map are store din the DaoState (role, txs). - private final Map bondedRoleByRoleUidMap = new HashMap<>(); - +public class BondedRolesService extends BondService { /////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -72,78 +49,7 @@ public class BondedRolesService implements DaoStateListener { @Inject public BondedRolesService(DaoStateService daoStateService, BsqWalletService bsqWalletService) { - this.daoStateService = daoStateService; - this.bsqWalletService = bsqWalletService; - - daoStateService.addBsqStateListener(this); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // DaoStateListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onNewBlockHeight(int blockHeight) { - } - - @Override - public void onParseTxsComplete(Block block) { - // TODO optimize to not re-write the whole map at each block - getBondedRoleStream().forEach(bondedRole -> { - bondedRoleByRoleUidMap.putIfAbsent(bondedRole.getUid(), new BondedRole(bondedRole)); - BondedRole bondedRoleState = bondedRoleByRoleUidMap.get(bondedRole.getUid()); - - // Lets see if we have a lock up tx. - daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> { - String lockupTxId = lockupTxOutput.getTxId(); - // log.error("lockupTxId " + lockupTxId); - - daoStateService.getTx(lockupTxId).ifPresent(lockupTx -> { - byte[] opReturnData = lockupTx.getLastTxOutput().getOpReturnData(); - - // We used the hash of th bonded role object as our hash in OpReturn of the lock up tx to have a - // unique binding of the tx to the data object. - byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); - Optional candidate = getBondedRoleFromHash(hash); - if (candidate.isPresent() && bondedRole.equals(candidate.get())) { - bondedRoleState.setBondState(BondState.LOCKUP_TX_CONFIRMED); - bondedRoleState.setLockupTxId(lockupTxId); - // We use the tx time as we want to have a unique time for all users - bondedRoleState.setStartDate(lockupTx.getTime()); - - if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { - // Lockup is already spent (in unlock tx) - daoStateService.getSpentInfo(lockupTxOutput) - .map(SpentInfo::getTxId) - .flatMap(daoStateService::getTx) - .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) - .ifPresent(unlockTx -> { - // cross check if it is in daoStateService.getUnlockTxOutputs() ? - String unlockTxId = unlockTx.getId(); - bondedRoleState.setUnlockTxId(unlockTxId); - bondedRoleState.setBondState(BondState.UNLOCK_TX_CONFIRMED); - bondedRoleState.setRevokeDate(unlockTx.getTime()); - boolean unlocking = daoStateService.isUnlocking(unlockTxId); - if (unlocking) { - bondedRoleState.setBondState(BondState.UNLOCKING); - } else { - bondedRoleState.setBondState(BondState.UNLOCKED); - } - }); - } - } - }); - }); - }); - - updateBondedRoleStateFromUnconfirmedLockupTxs(); - updateBondedRoleStateFromUnconfirmedUnlockTxs(); - } - - - @Override - public void onParseBlockChainComplete() { + super(daoStateService, bsqWalletService); } @@ -151,44 +57,6 @@ public void onParseBlockChainComplete() { // API /////////////////////////////////////////////////////////////////////////////////////////// - public void start() { - } - - public Collection getBondedRoles() { - return bondedRoleByRoleUidMap.values(); - } - - // bonded roles which are active and can be confiscated - public List getActiveBondedRoles() { - //TODO - return getBondedRoleList(); - } - - - public Optional getBondedRoleFromHash(byte[] hash) { - return getBondedRoleStream() - .filter(bondedRole -> Arrays.equals(bondedRole.getHash(), hash)) - .findAny(); - } - - public Optional getBondedRoleStateFromLockupTxId(String lockupTxId) { - return bondedRoleByRoleUidMap.values().stream() - .filter(bondedRoleState -> lockupTxId.equals(bondedRoleState.getLockupTxId())) - .findAny(); - } - - public Optional getBondedRoleType(String lockUpTxId) { - return getBondedRoleStateFromLockupTxId(lockUpTxId) - .map(BondedRole::getRole) - .map(Role::getBondedRoleType); - } - - public boolean wasRoleAlreadyBonded(Role role) { - BondedRole bondedRole = bondedRoleByRoleUidMap.get(role.getUid()); - checkArgument(bondedRole != null, "bondedRole must not be null"); - return bondedRole.getLockupTxId() != null; - } - public boolean isMyRole(Role role) { Set myWalletTransactionIds = bsqWalletService.getWalletTransactions().stream() .map(Transaction::getHashAsString) @@ -199,59 +67,25 @@ public boolean isMyRole(Role role) { .anyMatch(myWalletTransactionIds::contains); } - - /////////////////////////////////////////////////////////////////////////////////////////// - // Private - /////////////////////////////////////////////////////////////////////////////////////////// - - private List getBondedRoleList() { - return getBondedRoleStream().collect(Collectors.toList()); - } - - private void updateBondedRoleStateFromUnconfirmedLockupTxs() { - getBondedRoleStream().filter(this::isLockupTxUnconfirmed) - .map(role -> bondedRoleByRoleUidMap.get(role.getUid())) - .filter(bondedRole -> bondedRole.getBondState() == BondState.READY_FOR_LOCKUP) - .forEach(bondedRole -> bondedRole.setBondState(BondState.LOCKUP_TX_PENDING)); + public Optional getBondedRoleType(String lockUpTxId) { + return findBondByLockupTxId(lockUpTxId) + .map(Bond::getBondedAsset) + .map(Role::getBondedRoleType); } - private void updateBondedRoleStateFromUnconfirmedUnlockTxs() { - getBondedRoleStream().filter(this::isUnlockTxUnconfirmed) - .map(role -> bondedRoleByRoleUidMap.get(role.getUid())) - .filter(bondedRole -> bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED) - .forEach(bondedRole -> bondedRole.setBondState(BondState.UNLOCK_TX_PENDING)); - } - private boolean isLockupTxUnconfirmed(BondWithHash bondWithHash) { - return bsqWalletService.getWalletTransactions().stream() - .filter(transaction -> transaction.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.PENDING) - .map(transaction -> transaction.getOutputs().get(transaction.getOutputs().size() - 1)) - .filter(lastOutput -> lastOutput.getScriptPubKey().isOpReturn()) - .map(lastOutput -> lastOutput.getScriptPubKey().getChunks()) - .filter(chunks -> chunks.size() > 1) - .map(chunks -> chunks.get(1).data) - .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondWithHash.getHash())); - } + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// - private boolean isUnlockTxUnconfirmed(BondWithHash bondWithHash) { - return bsqWalletService.getWalletTransactions().stream() - .filter(transaction -> transaction.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.PENDING) - .filter(transaction -> transaction.getInputs().size() > 1) - .map(transaction -> transaction.getInputs().get(0)) - .map(TransactionInput::getConnectedOutput) - .filter(Objects::nonNull) - .map(TransactionOutput::getParentTransaction) - .filter(Objects::nonNull) - .map(Transaction::getHashAsString) - .flatMap(lockupTxId -> daoStateService.getLockupOpReturnTxOutput(lockupTxId).stream()) - .map(BaseTxOutput::getOpReturnData) - .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondWithHash.getHash())); + @Override + protected BondedRole createBond(Role role) { + return new BondedRole(role); } - private Stream getBondedRoleStream() { - return daoStateService.getEvaluatedProposalList().stream() - .filter(evaluatedProposal -> evaluatedProposal.getProposal() instanceof RoleProposal) - .map(e -> ((RoleProposal) e.getProposal()).getRole()); + @Override + protected Stream getBondedAssetStream() { + return getBondedRoleProposalStream().map(RoleProposal::getRole); } private Stream getBondedRoleProposalStream() { diff --git a/core/src/main/java/bisq/core/dao/node/parser/TxParser.java b/core/src/main/java/bisq/core/dao/node/parser/TxParser.java index fb22a62ebc5..39eb276f791 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/TxParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/TxParser.java @@ -141,8 +141,8 @@ private Optional findTx(RawTx rawTx) { boolean bsqOutputFound = txOutputParser.isBsqOutputFound(); long burntBsq = remainingInputValue + burntBondValue; - boolean hasBurntBSQ = burntBsq > 0; - if (hasBurntBSQ) + boolean hasBurntBsq = burntBsq > 0; + if (hasBurntBsq) tempTx.setBurntFee(burntBsq); @@ -152,14 +152,14 @@ private Optional findTx(RawTx rawTx) { applyTxTypeAndTxOutputType(blockHeight, tempTx, remainingInputValue); - TxType txType = evaluateTxType(tempTx, optionalOpReturnType, hasBurntBSQ, unLockInputValid); + TxType txType = evaluateTxType(tempTx, optionalOpReturnType, hasBurntBsq, unLockInputValid); tempTx.setTxType(txType); if (isTxInvalid(tempTx, bsqOutputFound, hasBurntBond)) { tempTx.setTxType(TxType.INVALID); txOutputParser.invalidateUTXOCandidates(); - if (hasBurntBSQ) { + if (hasBurntBsq) { log.warn("We have destroyed BSQ because of an invalid tx. Burned BSQ={}. tx={}", burntBsq / 100D, tempTx); } diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateService.java b/core/src/main/java/bisq/core/dao/state/DaoStateService.java index 789eb32edf0..6caf65b7c8d 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateService.java @@ -640,6 +640,12 @@ public Set getUnlockTxOutputs() { return getTxOutputsByTxOutputType(TxOutputType.UNLOCK_OUTPUT); } + public Set getUnspentLockUpTxOutputs() { + return getTxOutputsByTxOutputType(TxOutputType.LOCKUP_OUTPUT).stream() + .filter(txOutput -> isUnspent(txOutput.getKey())) + .collect(Collectors.toSet()); + } + public Optional getLockupTxOutput(String txId) { return getTx(txId).flatMap(tx -> tx.getTxOutputs().stream() .filter(this::isLockupOutput) diff --git a/core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java index a5ce9023a43..0a5a449c592 100644 --- a/core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java @@ -135,14 +135,23 @@ public TxOutput getLastTxOutput() { } - // The lockTime is stored in the first output of the LOCKUP tx. public int getLockTime() { - return txOutputs.get(0).getLockTime(); + // TODO MK: Still get confused that we have the lock time stored at a non opReturn output + return getLockupOutput().getLockTime(); + } + + public long getLockedAmount() { + return getLockupOutput().getValue(); + } + + // The lockTime is stored in the first output of the LOCKUP tx. + private TxOutput getLockupOutput() { + return txOutputs.get(0); } // The unlockBlockHeight is stored in the first output of the UNLOCK tx. public int getUnlockBlockHeight() { - return txOutputs.get(0).getUnlockBlockHeight(); + return getLockupOutput().getUnlockBlockHeight(); } @Override diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/Role.java b/core/src/main/java/bisq/core/dao/state/model/governance/Role.java index 7b26aa61dea..5ca8b572982 100644 --- a/core/src/main/java/bisq/core/dao/state/model/governance/Role.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/Role.java @@ -17,7 +17,7 @@ package bisq.core.dao.state.model.governance; -import bisq.core.dao.governance.bond.BondWithHash; +import bisq.core.dao.governance.bond.BondedAsset; import bisq.core.dao.state.model.ImmutableDaoStateModel; import bisq.core.locale.Res; @@ -44,7 +44,7 @@ @Immutable @Slf4j @Value -public final class Role implements PersistablePayload, NetworkPayload, BondWithHash, ImmutableDaoStateModel { +public final class Role implements PersistablePayload, NetworkPayload, BondedAsset, ImmutableDaoStateModel { private final String uid; private final String name; private final String link; @@ -99,7 +99,7 @@ public static Role fromProto(PB.Role proto) { /////////////////////////////////////////////////////////////////////////////////////////// - // BondWithHash implementation + // BondedAsset implementation /////////////////////////////////////////////////////////////////////////////////////////// @Override @@ -109,15 +109,16 @@ public byte[] getHash() { return Hash.getSha256Ripemd160hash(bytes); } + @Override + public String getDisplayString() { + return Res.get("dao.bond.bondedRoleType." + bondedRoleType.name()) + ": " + name; + } + /////////////////////////////////////////////////////////////////////////////////////////// // API /////////////////////////////////////////////////////////////////////////////////////////// - public String getDisplayString() { - return Res.get("dao.bond.bondedRoleType." + bondedRoleType.name()) + ": " + name; - } - // We use only the immutable data // bondedRoleType must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! // The equals and hashCode methods cannot be overwritten in Enums. diff --git a/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java b/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java index 202ebab2797..4f6ed3065e7 100644 --- a/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java +++ b/core/src/main/java/bisq/core/proto/persistable/CorePersistenceProtoResolver.java @@ -23,6 +23,7 @@ import bisq.core.dao.governance.asset.RemovedAssetsList; import bisq.core.dao.governance.blindvote.MyBlindVoteList; import bisq.core.dao.governance.blindvote.storage.BlindVoteStore; +import bisq.core.dao.governance.bond.reputation.MyReputationList; import bisq.core.dao.governance.myvote.MyVoteList; import bisq.core.dao.governance.proposal.MyProposalList; import bisq.core.dao.governance.proposal.storage.appendonly.ProposalStore; @@ -132,6 +133,9 @@ public PersistableEnvelope fromProto(PB.PersistableEnvelope proto) { return RemovedAssetsList.fromProto(proto.getRemovedAssetList()); case DAO_STATE_STORE: return DaoStateStore.fromProto(proto.getDaoStateStore()); + case MY_REPUTATION_LIST: + return MyReputationList.fromProto(proto.getMyReputationList()); + default: throw new ProtobufferRuntimeException("Unknown proto message case(PB.PersistableEnvelope). " + "messageCase=" + proto.getMessageCase() + "; proto raw data=" + proto.toString()); diff --git a/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java b/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java index 2865950a273..a48b1f44547 100644 --- a/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java +++ b/core/src/main/java/bisq/core/setup/CorePersistedDataHost.java @@ -23,7 +23,7 @@ import bisq.core.dao.governance.asset.AssetService; import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; -import bisq.core.dao.governance.bond.reputation.BondedReputationService; +import bisq.core.dao.governance.bond.reputation.MyReputationListService; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.proposal.MyProposalListService; import bisq.core.offer.OpenOfferManager; @@ -67,7 +67,7 @@ public static List getPersistedDataHosts(Injector injector) { persistedDataHosts.add(injector.getInstance(MyBlindVoteListService.class)); persistedDataHosts.add(injector.getInstance(MyVoteListService.class)); persistedDataHosts.add(injector.getInstance(MyProposalListService.class)); - persistedDataHosts.add(injector.getInstance(BondedReputationService.class)); + persistedDataHosts.add(injector.getInstance(MyReputationListService.class)); persistedDataHosts.add(injector.getInstance(AssetService.class)); } return persistedDataHosts; diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 836f5e00028..55b34cb239a 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -1310,7 +1310,8 @@ dao.results.votes.table.header.vote=Vote dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Bonded reputation dao.bonding.menuItem.bonds=Bonds -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup a bond for reputation +dao.bonding.reputation.list.header=My reputation bonds dao.bonding.lock.amount=Amount of BSQ to lockup dao.bonding.lock.time=Unlock time in blocks dao.bonding.lock.salt=Salt @@ -1323,13 +1324,18 @@ dao.bonding.lock.sendFunds.headline=Confirm lockup transaction dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=Unlock -dao.bonding.unlock.type=Type +dao.bonding.unlock.hash=Hash +dao.bonding.unlock.salt=Salt dao.bonding.unlock.reputation=Reputation dao.bonding.unlock.sendTx.headline=Confirm unlock transaction dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.dashboard.bondsHeadline=Bonded BSQ dao.bonding.dashboard.lockupAmount=Lockup funds dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over) +dao.bonding.bonds.table.lockupTxId=Lockup tx ID + +dao.bonding.info=Lockup Tx ID: {0} / {1} +dao.bonding.reputation.salt.info=Salt: {0} # suppress inspection "UnusedProperty" dao.bond.lockupType.BONDED_ROLE=Bonded role @@ -1390,9 +1396,12 @@ dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked dao.bond.table.column.header.unlockTxId=Unlock Tx ID dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.header.lockTime=Lock time +dao.bond.table.column.header.lockupDate=Lockup date dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke +dao.bond.table.button.unlock=Unlock dao.bond.table.notBonded=Not bonded yet dao.bond.table.lockedUp=Bond locked up dao.bond.table.unlocking=Bond unlocking diff --git a/core/src/main/resources/i18n/displayStrings_de.properties b/core/src/main/resources/i18n/displayStrings_de.properties index 09cae748a0c..9cee89f2691 100644 --- a/core/src/main/resources/i18n/displayStrings_de.properties +++ b/core/src/main/resources/i18n/displayStrings_de.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=Stimme dao.bonding.menuItem.bondedRoles=Gekoppelte Rollen dao.bonding.menuItem.reputation=BSQ sperren dao.bonding.menuItem.bonds=BSQ entsperren -dao.bonding.lock.lockBSQ=BSQ sperren +dao.bonding.reputation.header=BSQ sperren dao.bonding.lock.amount=Betrag von BSQ zu sperren: dao.bonding.lock.time=Entsperrung-Zeit in Blöcken: dao.bonding.lock.type=Art der Kopplung: diff --git a/core/src/main/resources/i18n/displayStrings_el.properties b/core/src/main/resources/i18n/displayStrings_el.properties index 18e7047de3b..878d35883cb 100644 --- a/core/src/main/resources/i18n/displayStrings_el.properties +++ b/core/src/main/resources/i18n/displayStrings_el.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=Ψήφισε dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Lockup BSQ dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: diff --git a/core/src/main/resources/i18n/displayStrings_es.properties b/core/src/main/resources/i18n/displayStrings_es.properties index 70f7793b68b..a01ad8cb744 100644 --- a/core/src/main/resources/i18n/displayStrings_es.properties +++ b/core/src/main/resources/i18n/displayStrings_es.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=otar dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Lockup BSQ dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: diff --git a/core/src/main/resources/i18n/displayStrings_fa.properties b/core/src/main/resources/i18n/displayStrings_fa.properties index 3fa3b57aae0..0106d34e69c 100644 --- a/core/src/main/resources/i18n/displayStrings_fa.properties +++ b/core/src/main/resources/i18n/displayStrings_fa.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=رأی dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Lockup BSQ dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: diff --git a/core/src/main/resources/i18n/displayStrings_hu.properties b/core/src/main/resources/i18n/displayStrings_hu.properties index 93bd0899e56..8a5527ae47d 100644 --- a/core/src/main/resources/i18n/displayStrings_hu.properties +++ b/core/src/main/resources/i18n/displayStrings_hu.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=Szavazás dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Lockup BSQ dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: diff --git a/core/src/main/resources/i18n/displayStrings_pt.properties b/core/src/main/resources/i18n/displayStrings_pt.properties index 9171d444a99..2376a9c8a3b 100644 --- a/core/src/main/resources/i18n/displayStrings_pt.properties +++ b/core/src/main/resources/i18n/displayStrings_pt.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=Votar dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Lockup BSQ dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: diff --git a/core/src/main/resources/i18n/displayStrings_ro.properties b/core/src/main/resources/i18n/displayStrings_ro.properties index 0c656ea8ee4..c58f1557dbd 100644 --- a/core/src/main/resources/i18n/displayStrings_ro.properties +++ b/core/src/main/resources/i18n/displayStrings_ro.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=Votează dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Lockup BSQ dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: diff --git a/core/src/main/resources/i18n/displayStrings_ru.properties b/core/src/main/resources/i18n/displayStrings_ru.properties index 47c50b27080..72f45fe859e 100644 --- a/core/src/main/resources/i18n/displayStrings_ru.properties +++ b/core/src/main/resources/i18n/displayStrings_ru.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=Голосование dao.bonding.menuItem.bondedRoles=Обеспеченные роли dao.bonding.menuItem.reputation=Запереть BSQ dao.bonding.menuItem.bonds=Разблокировать BSQ -dao.bonding.lock.lockBSQ=Запереть BSQ +dao.bonding.reputation.header=Запереть BSQ dao.bonding.lock.amount=Запереть BSQ на сумму: dao.bonding.lock.time=Срок разблокировки в блоках: dao.bonding.lock.type=Тир гарантийного депозита: diff --git a/core/src/main/resources/i18n/displayStrings_sr.properties b/core/src/main/resources/i18n/displayStrings_sr.properties index 369925adea5..5cc99db11fe 100644 --- a/core/src/main/resources/i18n/displayStrings_sr.properties +++ b/core/src/main/resources/i18n/displayStrings_sr.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=Glasaj dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Lockup BSQ dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: diff --git a/core/src/main/resources/i18n/displayStrings_th.properties b/core/src/main/resources/i18n/displayStrings_th.properties index 01acd7ec57c..d44cd51ab70 100644 --- a/core/src/main/resources/i18n/displayStrings_th.properties +++ b/core/src/main/resources/i18n/displayStrings_th.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=โหวต dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Lockup BSQ dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: diff --git a/core/src/main/resources/i18n/displayStrings_vi.properties b/core/src/main/resources/i18n/displayStrings_vi.properties index c5d83623e17..9c70e2dfa13 100644 --- a/core/src/main/resources/i18n/displayStrings_vi.properties +++ b/core/src/main/resources/i18n/displayStrings_vi.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=Bỏ phiếu dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Lockup BSQ dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: diff --git a/core/src/main/resources/i18n/displayStrings_zh.properties b/core/src/main/resources/i18n/displayStrings_zh.properties index dbb468b2ab0..d4f86541e55 100644 --- a/core/src/main/resources/i18n/displayStrings_zh.properties +++ b/core/src/main/resources/i18n/displayStrings_zh.properties @@ -1124,7 +1124,7 @@ dao.results.votes.table.header.vote=投票 dao.bonding.menuItem.bondedRoles=Bonded roles dao.bonding.menuItem.reputation=Lockup BSQ dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.lock.lockBSQ=Lockup BSQ +dao.bonding.reputation.header=Lockup BSQ dao.bonding.lock.amount=Amount of BSQ to lockup: dao.bonding.lock.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index efe8f9578ba..d93225ee445 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -29,7 +29,7 @@ import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.bonding.bonds.BondsView; import bisq.desktop.main.dao.bonding.dashboard.BondingDashboardView; -import bisq.desktop.main.dao.bonding.reputation.ReputationView; +import bisq.desktop.main.dao.bonding.reputation.MyBondedReputationView; import bisq.desktop.main.dao.bonding.roles.BondedRolesView; import bisq.core.locale.Res; @@ -86,7 +86,7 @@ public void initialize() { bondedRoles = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.bondedRoles"), BondedRolesView.class, AwesomeIcon.SHIELD, baseNavPath); reputation = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.reputation"), - ReputationView.class, AwesomeIcon.LOCK, baseNavPath); + MyBondedReputationView.class, AwesomeIcon.LOCK, baseNavPath); bonds = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.bonds"), BondsView.class, AwesomeIcon.UNLOCK, baseNavPath); @@ -131,7 +131,7 @@ private void loadView(Class viewClass) { if (view instanceof BondingDashboardView) dashboard.setSelected(true); else if (view instanceof BondedRolesView) bondedRoles.setSelected(true); - else if (view instanceof ReputationView) reputation.setSelected(true); + else if (view instanceof MyBondedReputationView) reputation.setSelected(true); else if (view instanceof BondsView) bonds.setSelected(true); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java index f7a5cb990e2..03f26b0eeef 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java @@ -26,9 +26,9 @@ import bisq.core.btc.setup.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.BondWithHash; +import bisq.core.dao.governance.bond.BondedAsset; import bisq.core.dao.governance.bond.lockup.LockupType; -import bisq.core.dao.governance.bond.reputation.Reputation; +import bisq.core.dao.governance.bond.reputation.MyReputation; import bisq.core.dao.state.model.blockchain.TxOutput; import bisq.core.dao.state.model.governance.BondedRoleType; import bisq.core.dao.state.model.governance.Role; @@ -70,7 +70,7 @@ public BondingViewUtils(P2PService p2PService, WalletsSetup walletsSetup, DaoFac this.bsqFormatter = bsqFormatter; } - private void lockupBond(BondWithHash bondWithHash, Coin lockupAmount, int lockupTime, LockupType lockupType, + private void lockupBond(BondedAsset bondedAsset, Coin lockupAmount, int lockupTime, LockupType lockupType, Consumer resultHandler) { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { if (!DevEnv.isDevMode()) { @@ -80,22 +80,22 @@ private void lockupBond(BondWithHash bondWithHash, Coin lockupAmount, int lockup lockupTime )) .actionButtonText(Res.get("shared.yes")) - .onAction(() -> publishLockupTx(bondWithHash, lockupAmount, lockupTime, lockupType, resultHandler)) + .onAction(() -> publishLockupTx(bondedAsset, lockupAmount, lockupTime, lockupType, resultHandler)) .closeButtonText(Res.get("shared.cancel")) .show(); } else { - publishLockupTx(bondWithHash, lockupAmount, lockupTime, lockupType, resultHandler); + publishLockupTx(bondedAsset, lockupAmount, lockupTime, lockupType, resultHandler); } } else { GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); } } - private void publishLockupTx(BondWithHash bondWithHash, Coin lockupAmount, int lockupTime, LockupType lockupType, Consumer resultHandler) { + private void publishLockupTx(BondedAsset bondedAsset, Coin lockupAmount, int lockupTime, LockupType lockupType, Consumer resultHandler) { daoFacade.publishLockupTx(lockupAmount, lockupTime, lockupType, - bondWithHash, + bondedAsset, txId -> { if (!DevEnv.isDevMode()) new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); @@ -115,8 +115,8 @@ public void lockupBondForBondedRole(Role role, Consumer resultHandler) { } public void lockupBondForReputation(Coin lockupAmount, int lockupTime, byte[] salt, Consumer resultHandler) { - Reputation reputation = new Reputation(salt); - lockupBond(reputation, lockupAmount, lockupTime, LockupType.REPUTATION, resultHandler); + MyReputation myReputation = new MyReputation(salt); + lockupBond(myReputation, lockupAmount, lockupTime, LockupType.REPUTATION, resultHandler); } public void unLock(String lockupTxId, Consumer resultHandler) { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java index a15c66456db..5a6b0ccd97a 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java @@ -18,135 +18,118 @@ package bisq.desktop.main.dao.bonding.bonds; import bisq.desktop.components.AutoTooltipButton; -import bisq.desktop.components.TxConfidenceListItem; -import bisq.desktop.components.indicator.TxConfidenceIndicator; +import bisq.desktop.main.dao.bonding.BondingViewUtils; -import bisq.core.btc.listeners.TxConfidenceListener; -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.BondConsensus; -import bisq.core.dao.governance.bond.lockup.LockupType; -import bisq.core.dao.governance.bond.role.BondedRole; +import bisq.core.dao.governance.bond.Bond; import bisq.core.dao.governance.bond.role.BondedRolesService; -import bisq.core.dao.state.model.blockchain.BaseTxOutput; -import bisq.core.dao.state.model.blockchain.TxOutput; -import bisq.core.dao.state.model.blockchain.TxType; -import bisq.core.dao.state.model.governance.BondedRoleType; -import bisq.core.locale.Res; +import bisq.core.dao.state.DaoStateListener; +import bisq.core.dao.state.model.blockchain.Block; import bisq.core.util.BsqFormatter; import org.bitcoinj.core.Coin; -import org.bitcoinj.core.Transaction; + +import javafx.scene.control.Button; import java.util.Date; -import java.util.Optional; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import static com.google.common.base.Preconditions.checkNotNull; - -@EqualsAndHashCode(callSuper = true) +@EqualsAndHashCode @Data @Slf4j -class BondListItem extends TxConfidenceListItem { - private final BtcWalletService btcWalletService; +class BondListItem implements DaoStateListener { + private final Bond bond; private final DaoFacade daoFacade; - - private final BsqFormatter bsqFormatter; private final BondedRolesService bondedRolesService; - private final Date date; - - private Coin amount = Coin.ZERO; - private int lockTime; - private AutoTooltipButton button; + private final BondingViewUtils bondingViewUtils; + private final BsqFormatter bsqFormatter; + private final String info; + private final String txId; + private final String amount; + private final String lockTime; - private TxConfidenceIndicator txConfidenceIndicator; - private TxConfidenceListener txConfidenceListener; - private boolean issuanceTx; + @Getter + private Button button; - BondListItem(Transaction transaction, - BsqWalletService bsqWalletService, - BtcWalletService btcWalletService, + BondListItem(Bond bond, DaoFacade daoFacade, BondedRolesService bondedRolesService, - Date date, + BondingViewUtils bondingViewUtils, BsqFormatter bsqFormatter) { - super(transaction, bsqWalletService); - - this.btcWalletService = btcWalletService; + this.bond = bond; this.daoFacade = daoFacade; this.bondedRolesService = bondedRolesService; - this.date = date; + this.bondingViewUtils = bondingViewUtils; this.bsqFormatter = bsqFormatter; - checkNotNull(transaction, "transaction must not be null as we only have list items from transactions " + - "which are available in the wallet"); - daoFacade.getLockupTxOutput(transaction.getHashAsString()) - .ifPresent(out -> amount = Coin.valueOf(out.getValue())); - - Optional opLockTime = daoFacade.getLockTime(transaction.getHashAsString()); - lockTime = opLockTime.orElse(-1); + info = bond.getBondedAsset().getDisplayString(); + txId = bond.getLockupTxId(); + amount = bsqFormatter.formatCoin(Coin.valueOf(bond.getAmount())); + lockTime = bsqFormatter.formatDateTime(new Date(bond.getLockupDate())); button = new AutoTooltipButton(); button.setMinWidth(70); - button.updateText(Res.get("dao.bonding.unlock.unlock")); - button.setVisible(true); - button.setManaged(true); + // label = new Label(); +/* + daoFacade.addBsqStateListener(this); + button.setOnAction(e -> { + if (bondedRole.getBondState() == BondState.READY_FOR_LOCKUP) { + bondingViewUtils.lockupBondForBondedRole(role, + txId -> { + bondedRole.setLockupTxId(txId); + bondedRole.setBondState(BondState.LOCKUP_TX_PENDING); + update(); + button.setDisable(true); + }); + } else if (bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { + bondingViewUtils.unLock(bondedRole.getLockupTxId(), + txId -> { + bondedRole.setUnlockTxId(txId); + bondedRole.setBondState(BondState.UNLOCK_TX_PENDING); + update(); + button.setDisable(true); + }); + } + });*/ } - public boolean isLockupAndUnspent() { - boolean isLocked; - Optional optionalBondedRoleState = bondedRolesService.getBondedRoleStateFromLockupTxId(txId); - if (optionalBondedRoleState.isPresent()) { - BondedRole bondedRole = optionalBondedRoleState.get(); - //TODO - //isLocked = bondedRole.getLockupTxId() != null && bondedRole.getUnlockTxId() == null; - //log.error("isLocked {}, tx={}",isLocked,bondedRole.getLockupTxId()); - } else { - //TODO get reputation - isLocked = true; - } - return /*isLocked && */!isSpent() && getTxType() == TxType.LOCKUP; - } + private void update() { + /* label.setText(Res.get("dao.bond.bondState." + bondedRole.getBondState().name())); + + boolean showLockup = bondedRole.getBondState() == BondState.READY_FOR_LOCKUP; + boolean showRevoke = bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED; + if (showLockup) + button.updateText(Res.get("dao.bond.table.button.lockup")); + else if (showRevoke) + button.updateText(Res.get("dao.bond.table.button.revoke")); - private boolean isSpent() { - Optional optionalTxOutput = daoFacade.getLockupTxOutput(txId); - return optionalTxOutput.map(txOutput -> !daoFacade.isUnspent(txOutput.getKey())) - .orElse(true); + boolean showButton = isMyRole && (showLockup || showRevoke); + button.setVisible(showButton); + button.setManaged(showButton);*/ } - public TxType getTxType() { - return daoFacade.getTx(txId) - .flatMap(tx -> daoFacade.getOptionalTxType(tx.getId())) - .orElse(confirmations == 0 ? TxType.UNVERIFIED : TxType.UNDEFINED_TX_TYPE); + public void cleanup() { + // daoFacade.removeBsqStateListener(this); + // button.setOnAction(null); } - private Optional getOptionalLockupType() { - return getOpReturnData() - .flatMap(BondConsensus::getLockupType); + // DaoStateListener + @Override + public void onNewBlockHeight(int blockHeight) { } - private Optional getOpReturnData() { - return daoFacade.getLockupOpReturnTxOutput(txId).map(BaseTxOutput::getOpReturnData); + @Override + public void onParseTxsComplete(Block block) { + update(); } - public String getInfo() { - Optional optionalRoleType = bondedRolesService.getBondedRoleType(txId); - if (optionalRoleType.isPresent()) { - return optionalRoleType.get().getDisplayString(); - } else { - Optional optionalLockupType = getOptionalLockupType(); - if (optionalLockupType.isPresent()) { - LockupType lockupType = optionalLockupType.get(); - if (lockupType == LockupType.REPUTATION) - return Res.get("dao.bonding.unlock.reputation"); - } - } - return Res.get("shared.na"); + @Override + public void onParseBlockChainComplete() { } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java index 50baa043a1c..75238c84c12 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java @@ -28,12 +28,10 @@ import bisq.core.btc.listeners.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.btc.wallet.BtcWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.model.blockchain.Block; -import bisq.core.dao.state.model.blockchain.TxType; import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; @@ -61,12 +59,9 @@ import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; -import javafx.collections.transformation.FilteredList; import javafx.util.Callback; -import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -75,7 +70,6 @@ public class BondsView extends ActivatableView implements BsqBal private TableView tableView; private final BsqWalletService bsqWalletService; - private final BtcWalletService btcWalletService; private final BsqFormatter bsqFormatter; private final BsqBalanceUtil bsqBalanceUtil; private final BsqValidator bsqValidator; @@ -87,7 +81,6 @@ public class BondsView extends ActivatableView implements BsqBal private int gridRow = 0; private final ObservableList observableList = FXCollections.observableArrayList(); - private final FilteredList lockupTxs = new FilteredList<>(observableList); private ListChangeListener walletBsqTransactionsListener; private ChangeListener walletChainHeightListener; @@ -99,7 +92,6 @@ public class BondsView extends ActivatableView implements BsqBal @Inject private BondsView(BsqWalletService bsqWalletService, - BtcWalletService btcWalletService, BsqFormatter bsqFormatter, BsqBalanceUtil bsqBalanceUtil, BsqValidator bsqValidator, @@ -108,7 +100,6 @@ private BondsView(BsqWalletService bsqWalletService, DaoFacade daoFacade, Preferences preferences) { this.bsqWalletService = bsqWalletService; - this.btcWalletService = btcWalletService; this.bsqFormatter = bsqFormatter; this.bsqBalanceUtil = bsqBalanceUtil; this.bsqValidator = bsqValidator; @@ -124,14 +115,8 @@ public void initialize() { tableView = new TableView<>(); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - tableView.setPrefHeight(300); - addTxIdColumn(); - addInfoColumn(); - addAmountColumn(); - addLockTimeColumn(); - addUnlockColumn(); - - lockupTxs.setPredicate(BondListItem::isLockupAndUnspent); + addColumns(); + walletBsqTransactionsListener = change -> updateList(); walletChainHeightListener = (observable, oldValue, newValue) -> updateList(); @@ -157,9 +142,9 @@ protected void activate() { bsqWalletService.getWalletTransactions().addListener(walletBsqTransactionsListener); bsqWalletService.addBsqBalanceListener(this); - btcWalletService.getChainHeightProperty().addListener(walletChainHeightListener); + bsqWalletService.getChainHeightProperty().addListener(walletChainHeightListener); - tableView.setItems(lockupTxs); + tableView.setItems(observableList); daoFacade.addBsqStateListener(this); @@ -171,13 +156,12 @@ protected void deactivate() { bsqBalanceUtil.deactivate(); bsqWalletService.removeBsqBalanceListener(this); - lockupTxs.predicateProperty().unbind(); bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); bsqWalletService.removeBsqBalanceListener(this); - btcWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); + bsqWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); daoFacade.removeBsqStateListener(this); - observableList.forEach(BondListItem::cleanup); + // observableList.forEach(BondListItem::cleanup); } @@ -224,22 +208,17 @@ private void openTxInBlockExplorer(BondListItem item) { } private void updateList() { - observableList.forEach(BondListItem::cleanup); - - // copy list to avoid ConcurrentModificationException - final List walletTransactions = new ArrayList<>(bsqWalletService.getWalletTransactions()); - List items = walletTransactions.stream() - .map(transaction -> { - return new BondListItem(transaction, - bsqWalletService, - btcWalletService, + List items = daoFacade.getAllActiveBonds().stream() + .map(bond -> { + return new BondListItem(bond, daoFacade, bondedRolesService, - transaction.getUpdateTime(), + bondingViewUtils, bsqFormatter); }) .collect(Collectors.toList()); observableList.setAll(items); + GUIUtil.setFitToRowsForTableView(tableView, 37, 28, 2, 10); } @@ -247,46 +226,10 @@ private void updateList() { // Table columns /////////////////////////////////////////////////////////////////////////////////////////// - private void addTxIdColumn() { - TableColumn column = new AutoTooltipTableColumn<>(Res.get("shared.txId")); + private void addColumns() { + TableColumn column; - column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(60); - column.setCellFactory( - new Callback<>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell<>() { - private HyperlinkWithIcon hyperlinkWithIcon; - - @Override - public void updateItem(final BondListItem item, boolean empty) { - super.updateItem(item, empty); - - //noinspection Duplicates - if (item != null && !empty) { - String transactionId = item.getTxId(); - hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(item)); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId))); - setGraphic(hyperlinkWithIcon); - } else { - setGraphic(null); - if (hyperlinkWithIcon != null) - hyperlinkWithIcon.setOnAction(null); - } - } - }; - } - }); - tableView.getColumns().add(column); - } - - private void addInfoColumn() { - TableColumn column = - new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.type")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.hash")); column.setMinWidth(160); column.setMaxWidth(column.getMinWidth()); @@ -310,11 +253,8 @@ public void updateItem(final BondListItem item, boolean empty) { } }); tableView.getColumns().add(column); - } - private void addAmountColumn() { - TableColumn column = - new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", "BSQ")); + column = new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", "BSQ")); column.setMinWidth(120); column.setMaxWidth(column.getMinWidth()); @@ -330,10 +270,7 @@ public TableCell call(TableColumn 0 && txType.ordinal() > TxType.INVALID.ordinal() ? - bsqFormatter.formatCoin(item.getAmount()) : - Res.get("shared.na")); + setText(item.getAmount()); } else setText(""); } @@ -341,12 +278,9 @@ public void updateItem(final BondListItem item, boolean empty) { } }); tableView.getColumns().add(column); - } - private void addLockTimeColumn() { - TableColumn column = - new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.time")); - column.setMinWidth(120); + column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.time")); + column.setMinWidth(140); column.setMaxWidth(column.getMinWidth()); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); @@ -361,10 +295,7 @@ public TableCell call(TableColumn 0 && txType.ordinal() > TxType.INVALID.ordinal() ? - Integer.toString(item.getLockTime()) : - Res.get("shared.na")); + setText(item.getLockTime()); } else setText(""); } @@ -372,45 +303,70 @@ public void updateItem(final BondListItem item, boolean empty) { } }); tableView.getColumns().add(column); - } - private void addUnlockColumn() { - TableColumn unlockColumn = new TableColumn<>(); - unlockColumn.setMinWidth(130); - unlockColumn.setMaxWidth(unlockColumn.getMinWidth()); - unlockColumn.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); - unlockColumn.setCellFactory(new Callback<>() { - @Override - public TableCell call(TableColumn column) { - return new TableCell<>() { - Button button; + column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.bonds.table.lockupTxId")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(60); + column.setCellFactory( + new Callback<>() { @Override - public void updateItem(final BondListItem item, boolean empty) { - super.updateItem(item, empty); + public TableCell call(TableColumn column) { + return new TableCell<>() { + private HyperlinkWithIcon hyperlinkWithIcon; - if (item != null && !empty) { - if (button == null) { - button = item.getButton(); - button.setOnAction(e -> bondingViewUtils.unLock(item.getTxId(), txId -> { - //TODO - button.setDisable(true); - })); - setGraphic(button); + @Override + public void updateItem(final BondListItem item, boolean empty) { + super.updateItem(item, empty); + + //noinspection Duplicates + if (item != null && !empty) { + String transactionId = item.getTxId(); + hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(item)); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId))); + setGraphic(hyperlinkWithIcon); + } else { + setGraphic(null); + if (hyperlinkWithIcon != null) + hyperlinkWithIcon.setOnAction(null); + } } - } else { - setGraphic(null); - if (button != null) { - button.setOnAction(null); - button = null; + }; + } + }); + tableView.getColumns().add(column); + + column = new TableColumn<>(); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(80); + column.setCellFactory( + new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + Button button; + + @Override + public void updateItem(final BondListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + if (button == null) { + button = item.getButton(); + setGraphic(button); + } + } else { + setGraphic(null); + if (button != null) + button = null; + } } - } + }; } - }; - } - }); - unlockColumn.setComparator(Comparator.comparing(BondListItem::getConfirmations)); - tableView.getColumns().add(unlockColumn); + }); + tableView.getColumns().add(column); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java new file mode 100644 index 00000000000..a176b5f2d05 --- /dev/null +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java @@ -0,0 +1,132 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding.reputation; + +import bisq.desktop.components.AutoTooltipButton; +import bisq.desktop.main.dao.bonding.BondingViewUtils; + +import bisq.core.dao.DaoFacade; +import bisq.core.dao.governance.bond.BondState; +import bisq.core.dao.governance.bond.reputation.MyBondedReputation; +import bisq.core.dao.governance.bond.reputation.MyReputation; +import bisq.core.dao.state.DaoStateListener; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import bisq.common.util.Utilities; + +import org.bitcoinj.core.Coin; + +import javafx.scene.control.Label; + +import java.util.Date; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@EqualsAndHashCode +@Data +@Slf4j +class MyBondedReputationListItem implements DaoStateListener { + private final MyBondedReputation myBondedReputation; + private final DaoFacade daoFacade; + private final BsqFormatter bsqFormatter; + private final String hash, salt; + private final String txId; + private final String amount; + private final String lockupDate; + private final String lockTime; + + @Getter + private final AutoTooltipButton button; + @Getter + private final Label stateLabel; + + MyBondedReputationListItem(MyBondedReputation myBondedReputation, + DaoFacade daoFacade, + BondingViewUtils bondingViewUtils, + BsqFormatter bsqFormatter) { + this.myBondedReputation = myBondedReputation; + this.daoFacade = daoFacade; + this.bsqFormatter = bsqFormatter; + + MyReputation myReputation = myBondedReputation.getBondedAsset(); + hash = Utilities.bytesAsHexString(myReputation.getHash()); + salt = Utilities.bytesAsHexString(myReputation.getSalt()); + txId = myBondedReputation.getLockupTxId(); + amount = bsqFormatter.formatCoin(Coin.valueOf(myBondedReputation.getAmount())); + lockupDate = bsqFormatter.formatDateTime(new Date(myBondedReputation.getLockupDate())); + lockTime = Integer.toString(myBondedReputation.getLockTime()); + + daoFacade.addBsqStateListener(this); + + button = new AutoTooltipButton(); + stateLabel = new Label(); + + button.setOnAction(e -> { + if (myBondedReputation.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { + bondingViewUtils.unLock(myBondedReputation.getLockupTxId(), + txId -> { + myBondedReputation.setUnlockTxId(txId); + myBondedReputation.setBondState(BondState.UNLOCK_TX_PENDING); + update(); + button.setDisable(true); + }); + } + }); + + update(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // DaoStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onParseTxsComplete(Block block) { + update(); + } + + @Override + public void onParseBlockChainComplete() { + } + + void cleanup() { + daoFacade.removeBsqStateListener(this); + button.setOnAction(null); + } + + private void update() { + stateLabel.setText(Res.get("dao.bond.bondState." + myBondedReputation.getBondState().name())); + + boolean showButton = myBondedReputation.getBondState() == BondState.LOCKUP_TX_CONFIRMED; + if (showButton) + button.updateText(Res.get("dao.bond.table.button.unlock")); + + button.setVisible(showButton); + button.setManaged(showButton); + } +} diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.fxml b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.fxml similarity index 97% rename from desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.fxml rename to desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.fxml index 869dfe78c70..4e175d3fae7 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.fxml +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.fxml @@ -21,7 +21,7 @@ -. + */ + +package bisq.desktop.main.dao.bonding.reputation; + +import bisq.desktop.common.view.ActivatableView; +import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.AutoTooltipTableColumn; +import bisq.desktop.components.HyperlinkWithIcon; +import bisq.desktop.components.InputTextField; +import bisq.desktop.components.TitledGroupBg; +import bisq.desktop.main.dao.bonding.BondingViewUtils; +import bisq.desktop.util.FormBuilder; +import bisq.desktop.util.GUIUtil; +import bisq.desktop.util.Layout; +import bisq.desktop.util.validation.BsqValidator; + +import bisq.core.btc.listeners.BsqBalanceListener; +import bisq.core.btc.wallet.BsqWalletService; +import bisq.core.dao.DaoFacade; +import bisq.core.dao.governance.bond.BondConsensus; +import bisq.core.dao.state.DaoStateListener; +import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.locale.Res; +import bisq.core.user.Preferences; +import bisq.core.util.BsqFormatter; +import bisq.core.util.validation.HexStringValidator; +import bisq.core.util.validation.IntegerValidator; + +import bisq.common.crypto.Hash; +import bisq.common.util.Utilities; + +import org.bitcoinj.core.Coin; +import org.bitcoinj.core.Transaction; + +import javax.inject.Inject; + +import com.google.common.base.Charsets; + +import de.jensd.fx.fontawesome.AwesomeIcon; + +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.control.TableCell; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.Tooltip; +import javafx.scene.layout.GridPane; +import javafx.scene.layout.VBox; + +import javafx.geometry.Insets; + +import javafx.beans.property.ReadOnlyObjectWrapper; +import javafx.beans.value.ChangeListener; + +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; + +import javafx.util.Callback; + +import java.util.Comparator; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; +import static bisq.desktop.util.FormBuilder.addInputTextField; +import static bisq.desktop.util.FormBuilder.addTitledGroupBg; + +@FxmlView +public class MyBondedReputationView extends ActivatableView implements DaoStateListener, BsqBalanceListener { + private final BsqWalletService bsqWalletService; + private final BsqFormatter bsqFormatter; + private final BondingViewUtils bondingViewUtils; + private final HexStringValidator hexStringValidator; + private final BsqValidator bsqValidator; + private final DaoFacade daoFacade; + private final Preferences preferences; + private final IntegerValidator timeInputTextFieldValidator; + + private int gridRow = 0; + private InputTextField amountInputTextField, timeInputTextField, saltInputTextField; + private Button lockupButton; + private TableView tableView; + private ChangeListener amountFocusOutListener, timeFocusOutListener, saltFocusOutListener; + private ChangeListener amountInputTextFieldListener, timeInputTextFieldListener, saltInputTextFieldListener; + private final ObservableList observableList = FXCollections.observableArrayList(); + private ListChangeListener walletBsqTransactionsListener; + private ChangeListener walletChainHeightListener; + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Constructor, lifecycle + /////////////////////////////////////////////////////////////////////////////////////////// + + @Inject + private MyBondedReputationView(BsqWalletService bsqWalletService, + BsqFormatter bsqFormatter, + BondingViewUtils bondingViewUtils, + HexStringValidator hexStringValidator, + BsqValidator bsqValidator, + DaoFacade daoFacade, + Preferences preferences) { + this.bsqWalletService = bsqWalletService; + this.bsqFormatter = bsqFormatter; + this.bondingViewUtils = bondingViewUtils; + this.hexStringValidator = hexStringValidator; + this.bsqValidator = bsqValidator; + this.daoFacade = daoFacade; + this.preferences = preferences; + + timeInputTextFieldValidator = new IntegerValidator(); + timeInputTextFieldValidator.setMinValue(BondConsensus.getMinLockTime()); + timeInputTextFieldValidator.setMaxValue(BondConsensus.getMaxLockTime()); + } + + @Override + public void initialize() { + int columnSpan = 3; + TitledGroupBg titledGroupBg = addTitledGroupBg(root, gridRow, 3, Res.get("dao.bonding.reputation.header")); + GridPane.setColumnSpan(titledGroupBg, columnSpan); + + amountInputTextField = addInputTextField(root, gridRow, Res.get("dao.bonding.lock.amount"), + Layout.FIRST_ROW_DISTANCE); + amountInputTextField.setValidator(bsqValidator); + GridPane.setColumnSpan(amountInputTextField, columnSpan); + + timeInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time")); + GridPane.setColumnSpan(timeInputTextField, columnSpan); + timeInputTextField.setValidator(timeInputTextFieldValidator); + + saltInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.salt")); + GridPane.setColumnSpan(saltInputTextField, columnSpan); + saltInputTextField.setValidator(hexStringValidator); + + lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); + + createTableView(columnSpan); + + createListeners(); + } + + @Override + protected void activate() { + amountInputTextField.textProperty().addListener(amountInputTextFieldListener); + amountInputTextField.focusedProperty().addListener(amountFocusOutListener); + + timeInputTextField.textProperty().addListener(timeInputTextFieldListener); + timeInputTextField.focusedProperty().addListener(timeFocusOutListener); + + saltInputTextField.textProperty().addListener(saltInputTextFieldListener); + saltInputTextField.focusedProperty().addListener(saltFocusOutListener); + + bsqWalletService.getWalletTransactions().addListener(walletBsqTransactionsListener); + bsqWalletService.addBsqBalanceListener(this); + bsqWalletService.getChainHeightProperty().addListener(walletChainHeightListener); + + lockupButton.setOnAction((event) -> { + Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); + int lockupTime = Integer.parseInt(timeInputTextField.getText()); + byte[] salt = Utilities.decodeFromHex(saltInputTextField.getText()); + bondingViewUtils.lockupBondForReputation(lockupAmount, + lockupTime, + salt, + txId -> { + }); + amountInputTextField.setText(""); + timeInputTextField.setText(""); + setNewRandomSalt(); + }); + + daoFacade.addBsqStateListener(this); + + amountInputTextField.resetValidation(); + timeInputTextField.resetValidation(); + setNewRandomSalt(); + + tableView.setItems(observableList); + + onUpdateBalances(); + updateList(); + } + + @Override + protected void deactivate() { + observableList.forEach(MyBondedReputationListItem::cleanup); + + amountInputTextField.textProperty().removeListener(amountInputTextFieldListener); + amountInputTextField.focusedProperty().removeListener(amountFocusOutListener); + + timeInputTextField.textProperty().removeListener(timeInputTextFieldListener); + timeInputTextField.focusedProperty().removeListener(timeFocusOutListener); + + saltInputTextField.textProperty().removeListener(saltInputTextFieldListener); + saltInputTextField.focusedProperty().removeListener(saltFocusOutListener); + + bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); + bsqWalletService.addBsqBalanceListener(this); + bsqWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); + + lockupButton.setOnAction(null); + + daoFacade.removeBsqStateListener(this); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // DaoStateListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onParseTxsComplete(Block block) { + updateList(); + } + + @Override + public void onParseBlockChainComplete() { + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // BsqBalanceListener + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void onUpdateBalances(Coin confirmedBalance, + Coin availableNonBsqBalance, + Coin pendingBalance, + Coin lockedForVotingBalance, + Coin lockupBondsBalance, + Coin unlockingBondsBalance) { + bsqValidator.setAvailableBalance(confirmedBalance); + updateButtonState(); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + + private void createListeners() { + amountFocusOutListener = (observable, oldValue, newValue) -> { + if (!newValue) { + updateButtonState(); + onUpdateBalances(); + } + }; + timeFocusOutListener = (observable, oldValue, newValue) -> { + if (!newValue) { + updateButtonState(); + onUpdateBalances(); + } + }; + saltFocusOutListener = (observable, oldValue, newValue) -> { + if (!newValue) { + updateButtonState(); + onUpdateBalances(); + } + }; + + amountInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); + timeInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); + saltInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); + + walletBsqTransactionsListener = change -> updateList(); + walletChainHeightListener = (observable, oldValue, newValue) -> updateList(); + } + + private void createTableView(int columnSpan) { + TitledGroupBg titledGroupBg2 = addTitledGroupBg(root, ++gridRow, 2, Res.get("dao.bonding.reputation.list.header"), 20); + GridPane.setColumnSpan(titledGroupBg2, columnSpan); + + tableView = new TableView<>(); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + createColumns(); + + VBox vBox = new VBox(); + vBox.setSpacing(10); + GridPane.setRowIndex(vBox, ++gridRow); + GridPane.setColumnSpan(vBox, columnSpan); + GridPane.setMargin(vBox, new Insets(50, -10, 5, -10)); + vBox.getChildren().addAll(tableView); + root.getChildren().add(vBox); + } + + private void setNewRandomSalt() { + byte[] randomBytes = UUID.randomUUID().toString().getBytes(Charsets.UTF_8); + byte[] hashOfRandomBytes = Hash.getSha256Ripemd160hash(randomBytes); + saltInputTextField.setText(Utilities.bytesAsHexString(hashOfRandomBytes)); + saltInputTextField.resetValidation(); + } + + private void onUpdateBalances() { + onUpdateBalances(bsqWalletService.getAvailableBalance(), + bsqWalletService.getAvailableNonBsqBalance(), + bsqWalletService.getUnverifiedBalance(), + bsqWalletService.getLockedForVotingBalance(), + bsqWalletService.getLockupBondsBalance(), + bsqWalletService.getUnlockingBondsBalance()); + } + + private void updateButtonState() { + boolean isValid = bsqValidator.validate(amountInputTextField.getText()).isValid && + timeInputTextFieldValidator.validate(timeInputTextField.getText()).isValid && + hexStringValidator.validate(saltInputTextField.getText()).isValid; + lockupButton.setDisable(!isValid); + } + + private void openTxInBlockExplorer(MyBondedReputationListItem item) { + if (item.getTxId() != null) + GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); + } + + private void updateList() { + List items = daoFacade.getMyBondedReputations().stream() + .map(myBondedReputation -> { + return new MyBondedReputationListItem(myBondedReputation, daoFacade, bondingViewUtils, bsqFormatter); + }) + .sorted(Comparator.comparing(MyBondedReputationListItem::getLockupDate).reversed()) + .collect(Collectors.toList()); + observableList.setAll(items); + GUIUtil.setFitToRowsForTableView(tableView, 41, 28, 2, 4); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // Table columns + /////////////////////////////////////////////////////////////////////////////////////////// + + private void createColumns() { + TableColumn column; + + column = new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", "BSQ")); + column.setMinWidth(120); + column.setMaxWidth(column.getMinWidth()); + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory(new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + @Override + public void updateItem(final MyBondedReputationListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + setText(item.getAmount()); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockTime")); + column.setMinWidth(60); + column.setMaxWidth(column.getMinWidth()); + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory(new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + @Override + public void updateItem(final MyBondedReputationListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + setText(item.getLockTime()); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondState")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(120); + column.setCellFactory( + new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + Label label; + + @Override + public void updateItem(final MyBondedReputationListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + if (label == null) { + label = item.getStateLabel(); + setGraphic(label); + } + } else { + setGraphic(null); + if (label != null) + label = null; + } + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockupDate")); + column.setMinWidth(140); + column.setMaxWidth(column.getMinWidth()); + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory(new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + + @Override + public void updateItem(final MyBondedReputationListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + setText(item.getLockupDate()); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.bonds.table.lockupTxId")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(80); + column.setCellFactory( + new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + private HyperlinkWithIcon hyperlinkWithIcon; + + @Override + public void updateItem(final MyBondedReputationListItem item, boolean empty) { + super.updateItem(item, empty); + //noinspection Duplicates + if (item != null && !empty) { + String transactionId = item.getTxId(); + hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(item)); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId))); + setGraphic(hyperlinkWithIcon); + } else { + setGraphic(null); + if (hyperlinkWithIcon != null) + hyperlinkWithIcon.setOnAction(null); + } + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.salt")); + column.setMinWidth(80); + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory(new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + @Override + public void updateItem(final MyBondedReputationListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + setText(item.getSalt()); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.hash")); + column.setMinWidth(80); + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory(new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + @Override + public void updateItem(final MyBondedReputationListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + setText(item.getHash()); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + + column = new TableColumn<>(); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(60); + column.setCellFactory( + new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + Button button; + + @Override + public void updateItem(final MyBondedReputationListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + if (button == null) { + button = item.getButton(); + setGraphic(button); + } + } else { + setGraphic(null); + if (button != null) + button = null; + } + } + }; + } + }); + tableView.getColumns().add(column); + } +} diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.java deleted file mode 100644 index ea8002e59fc..00000000000 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/ReputationView.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.bonding.reputation; - -import bisq.desktop.common.view.ActivatableView; -import bisq.desktop.common.view.FxmlView; -import bisq.desktop.components.InputTextField; -import bisq.desktop.components.TitledGroupBg; -import bisq.desktop.main.dao.bonding.BondingViewUtils; -import bisq.desktop.main.dao.wallet.BsqBalanceUtil; -import bisq.desktop.util.FormBuilder; -import bisq.desktop.util.Layout; -import bisq.desktop.util.validation.BsqValidator; - -import bisq.core.btc.listeners.BsqBalanceListener; -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.governance.bond.BondConsensus; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; -import bisq.core.util.validation.HexStringValidator; -import bisq.core.util.validation.IntegerValidator; - -import bisq.common.crypto.Hash; -import bisq.common.util.Utilities; - -import org.bitcoinj.core.Coin; - -import javax.inject.Inject; - -import com.google.common.base.Charsets; - -import javafx.scene.control.Button; -import javafx.scene.layout.GridPane; - -import javafx.beans.value.ChangeListener; - -import java.util.UUID; - -import static bisq.desktop.util.FormBuilder.addButtonAfterGroup; -import static bisq.desktop.util.FormBuilder.addInputTextField; -import static bisq.desktop.util.FormBuilder.addTitledGroupBg; - -@FxmlView -public class ReputationView extends ActivatableView implements BsqBalanceListener { - private final BsqWalletService bsqWalletService; - private final BsqFormatter bsqFormatter; - private final BsqBalanceUtil bsqBalanceUtil; - private final BondingViewUtils bondingViewUtils; - private final HexStringValidator hexStringValidator; - private final BsqValidator bsqValidator; - private final IntegerValidator timeInputTextFieldValidator; - - private int gridRow = 0; - private InputTextField amountInputTextField, timeInputTextField, saltInputTextField; - private Button lockupButton; - private ChangeListener amountFocusOutListener, timeFocusOutListener, saltFocusOutListener; - private ChangeListener amountInputTextFieldListener, timeInputTextFieldListener, saltInputTextFieldListener; - - - /////////////////////////////////////////////////////////////////////////////////////////// - // Constructor, lifecycle - /////////////////////////////////////////////////////////////////////////////////////////// - - @Inject - private ReputationView(BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BsqBalanceUtil bsqBalanceUtil, - BondingViewUtils bondingViewUtils, - HexStringValidator hexStringValidator, - BsqValidator bsqValidator) { - this.bsqWalletService = bsqWalletService; - this.bsqFormatter = bsqFormatter; - this.bsqBalanceUtil = bsqBalanceUtil; - this.bondingViewUtils = bondingViewUtils; - this.hexStringValidator = hexStringValidator; - this.bsqValidator = bsqValidator; - - timeInputTextFieldValidator = new IntegerValidator(); - timeInputTextFieldValidator.setMinValue(BondConsensus.getMinLockTime()); - timeInputTextFieldValidator.setMaxValue(BondConsensus.getMaxLockTime()); - } - - @Override - public void initialize() { - gridRow = bsqBalanceUtil.addGroup(root, gridRow); - - int columnSpan = 3; - TitledGroupBg titledGroupBg = addTitledGroupBg(root, ++gridRow, 3, Res.get("dao.bonding.lock.lockBSQ"), - Layout.GROUP_DISTANCE); - GridPane.setColumnSpan(titledGroupBg, columnSpan); - - amountInputTextField = addInputTextField(root, gridRow, Res.get("dao.bonding.lock.amount"), - Layout.FIRST_ROW_AND_GROUP_DISTANCE); - //amountInputTextField.setPromptText(Res.get("dao.bonding.lock.setAmount", bsqFormatter.formatCoinWithCode(Restrictions.getMinNonDustOutput()))); - amountInputTextField.setValidator(bsqValidator); - GridPane.setColumnSpan(amountInputTextField, columnSpan); - - timeInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time")); - - saltInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.salt")); - GridPane.setColumnSpan(saltInputTextField, columnSpan); - saltInputTextField.setValidator(hexStringValidator); - - /* timeInputTextField.setPromptText(Res.get("dao.bonding.lock.setTime", - String.valueOf(BondConsensus.getMinLockTime()), String.valueOf(BondConsensus.getMaxLockTime())));*/ - - timeInputTextField.setValidator(timeInputTextFieldValidator); - GridPane.setColumnSpan(timeInputTextField, columnSpan); - - lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); - lockupButton.setOnAction((event) -> { - Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); - int lockupTime = Integer.parseInt(timeInputTextField.getText()); - byte[] salt = Utilities.decodeFromHex(saltInputTextField.getText()); - bondingViewUtils.lockupBondForReputation(lockupAmount, - lockupTime, - salt, - txId -> { - amountInputTextField.setText(""); - timeInputTextField.setText(""); - }); - }); - - amountFocusOutListener = (observable, oldValue, newValue) -> { - if (!newValue) { - updateButtonState(); - onUpdateBalances(); - } - }; - timeFocusOutListener = (observable, oldValue, newValue) -> { - if (!newValue) { - updateButtonState(); - onUpdateBalances(); - } - }; - saltFocusOutListener = (observable, oldValue, newValue) -> { - if (!newValue) { - updateButtonState(); - onUpdateBalances(); - } - }; - amountInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); - timeInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); - saltInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); - } - - @Override - protected void activate() { - bsqBalanceUtil.activate(); - - amountInputTextField.textProperty().addListener(amountInputTextFieldListener); - amountInputTextField.focusedProperty().addListener(amountFocusOutListener); - - timeInputTextField.textProperty().addListener(timeInputTextFieldListener); - timeInputTextField.focusedProperty().addListener(timeFocusOutListener); - - saltInputTextField.textProperty().addListener(saltInputTextFieldListener); - saltInputTextField.focusedProperty().addListener(saltFocusOutListener); - - bsqWalletService.addBsqBalanceListener(this); - - byte[] randomBytes = UUID.randomUUID().toString().getBytes(Charsets.UTF_8); - byte[] hashOfRandomBytes = Hash.getSha256Ripemd160hash(randomBytes); - saltInputTextField.setText(Utilities.bytesAsHexString(hashOfRandomBytes)); - - onUpdateBalances(); - } - - @Override - protected void deactivate() { - bsqBalanceUtil.deactivate(); - - amountInputTextField.textProperty().removeListener(amountInputTextFieldListener); - amountInputTextField.focusedProperty().removeListener(amountFocusOutListener); - - timeInputTextField.textProperty().removeListener(timeInputTextFieldListener); - timeInputTextField.focusedProperty().removeListener(timeFocusOutListener); - - saltInputTextField.textProperty().removeListener(saltInputTextFieldListener); - saltInputTextField.focusedProperty().removeListener(saltFocusOutListener); - - bsqWalletService.removeBsqBalanceListener(this); - } - - @Override - public void onUpdateBalances(Coin confirmedBalance, - Coin availableNonBsqBalance, - Coin pendingBalance, - Coin lockedForVotingBalance, - Coin lockupBondsBalance, - Coin unlockingBondsBalance) { - bsqValidator.setAvailableBalance(confirmedBalance); - boolean isValid = bsqValidator.validate(amountInputTextField.getText()).isValid; - lockupButton.setDisable(!isValid); - } - - private void onUpdateBalances() { - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getUnverifiedBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockupBondsBalance(), - bsqWalletService.getUnlockingBondsBalance()); - } - - private void updateButtonState() { - boolean isValid = bsqValidator.validate(amountInputTextField.getText()).isValid && - timeInputTextFieldValidator.validate(timeInputTextField.getText()).isValid && - hexStringValidator.validate(saltInputTextField.getText()).isValid; - - lockupButton.setDisable(!isValid); - } -} diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java index 4bc011da946..6e4032ba282 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java @@ -63,8 +63,8 @@ class BondedRolesListItem implements DaoStateListener { this.bondingViewUtils = bondingViewUtils; this.bsqFormatter = bsqFormatter; - role = bondedRole.getRole(); - isMyRole = daoFacade.isMyRole(bondedRole.getRole()); + role = bondedRole.getBondedAsset(); + isMyRole = daoFacade.isMyRole(role); daoFacade.addBsqStateListener(this); @@ -96,14 +96,14 @@ class BondedRolesListItem implements DaoStateListener { } public String getStartDate() { - return bondedRole.getStartDate() > 0 ? - bsqFormatter.formatDateTime(new Date(bondedRole.getStartDate())) : + return bondedRole.getLockupDate() > 0 ? + bsqFormatter.formatDateTime(new Date(bondedRole.getLockupDate())) : "-"; } public String getRevokeDate() { - return bondedRole.getRevokeDate() > 0 ? - bsqFormatter.formatDateTime(new Date(bondedRole.getRevokeDate())) : + return bondedRole.getUnlockDate() > 0 ? + bsqFormatter.formatDateTime(new Date(bondedRole.getUnlockDate())) : "-"; } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java index 09134020717..1580697bc4c 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java @@ -154,7 +154,7 @@ public void onParseBlockChainComplete() { private void updateList() { observableList.forEach(BondedRolesListItem::cleanup); observableList.setAll(daoFacade.getBondedRoles().stream() - .map(bondedRole -> new BondedRolesListItem(bondedRole, daoFacade, bondingViewUtils, bsqFormatter)) + .map(bond -> new BondedRolesListItem(bond, daoFacade, bondingViewUtils, bsqFormatter)) .collect(Collectors.toList())); } @@ -175,13 +175,12 @@ private void createColumns() { column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(80); column.setCellFactory( - new Callback, TableCell>() { + new Callback<>() { @Override public TableCell call(TableColumn column) { - return new TableCell() { + return new TableCell<>() { @Override public void updateItem(final BondedRolesListItem item, boolean empty) { super.updateItem(item, empty); @@ -199,13 +198,12 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(60); column.setCellFactory( - new Callback, TableCell>() { + new Callback<>() { @Override public TableCell call(TableColumn column) { - return new TableCell() { + return new TableCell<>() { private HyperlinkWithIcon hyperlinkWithIcon; @Override @@ -232,13 +230,12 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(80); column.setCellFactory( - new Callback, TableCell>() { + new Callback<>() { @Override public TableCell call(TableColumn column) { - return new TableCell() { + return new TableCell<>() { private Hyperlink hyperlink; @Override @@ -265,7 +262,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.startDate")); + /* column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.startDate")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(120); column.setCellFactory( @@ -395,18 +392,17 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { }; } }); - tableView.getColumns().add(column); + tableView.getColumns().add(column);*/ column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondState")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(120); column.setCellFactory( - new Callback, TableCell>() { + new Callback<>() { @Override public TableCell call(TableColumn column) { - return new TableCell() { + return new TableCell<>() { Label label; @Override diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java index 8ca4599aac1..0934431aea4 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java @@ -27,6 +27,7 @@ import bisq.core.btc.BaseCurrencyNetwork; import bisq.core.dao.DaoFacade; +import bisq.core.dao.governance.bond.Bond; import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.ProposalType; import bisq.core.dao.governance.proposal.param.ChangeParamInputValidator; @@ -111,7 +112,7 @@ public class ProposalDisplay { @Nullable public ComboBox paramComboBox; @Nullable - public ComboBox confiscateBondComboBox; + public ComboBox confiscateBondComboBox; @Nullable public ComboBox bondedRoleTypeComboBox; @Nullable @@ -299,19 +300,20 @@ public BondedRoleType fromString(String string) { break; case CONFISCATE_BOND: - confiscateBondComboBox = FormBuilder.addComboBox(gridPane, ++gridRow, + confiscateBondComboBox = FormBuilder.addComboBox(gridPane, ++gridRow, Res.get("dao.proposal.display.confiscateBondComboBox.label")); comboBoxValueTextFieldIndex = gridRow; checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); - confiscateBondComboBox.setItems(FXCollections.observableArrayList(daoFacade.getActiveBondedRoles())); + + confiscateBondComboBox.setItems(FXCollections.observableArrayList(daoFacade.getAllActiveBonds())); confiscateBondComboBox.setConverter(new StringConverter<>() { @Override - public String toString(Role role) { - return role != null ? role.getDisplayString() : ""; + public String toString(Bond bond) { + return bond != null ? bond.getDisplayString() : ""; } @Override - public Role fromString(String string) { + public Bond fromString(String string) { return null; } }); @@ -481,11 +483,13 @@ public void applyProposalPayload(Proposal proposal) { ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) proposal; checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); - daoFacade.getBondedRoleFromHash(confiscateBondProposal.getHash()) + //TODO + /* daoFacade.getBondedRoleFromHash(confiscateBondProposal.getHash()) .ifPresent(bondedRole -> { confiscateBondComboBox.getSelectionModel().select(bondedRole); comboBoxValueTextField.setText(confiscateBondComboBox.getConverter().toString(bondedRole)); - }); + });*/ + } else if (proposal instanceof GenericProposal) { // do nothing } else if (proposal instanceof RemoveAssetProposal) { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java index 25372fffdbe..12d5efacea0 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java @@ -304,10 +304,12 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) case CONFISCATE_BOND: checkNotNull(proposalDisplay.confiscateBondComboBox, "proposalDisplay.confiscateBondComboBox must not be null"); - role = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); + + //TODO + /* role = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); return daoFacade.getConfiscateBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.linkInputTextField.getText(), - role.getHash()); + role.getHash());*/ case GENERIC: return daoFacade.getGenericProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.linkInputTextField.getText()); From 6218da062383d32b8ebb05f3d3642c39084c32a5 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 5 Nov 2018 20:22:57 -0500 Subject: [PATCH 19/27] Support state update for unconfirmed reputation bond txs. --- common/src/main/proto/pb.proto | 3 +- .../core/btc/wallet/BsqWalletService.java | 6 ++ .../main/java/bisq/core/dao/DaoFacade.java | 5 +- .../dao/governance/bond/BondConsensus.java | 4 - .../core/dao/governance/bond/BondService.java | 97 ++++++++++--------- .../governance/bond/lockup/LockupService.java | 26 +---- .../reputation/BondedReputationService.java | 19 ++-- .../reputation/MyBondedReputationService.java | 69 ++++++------- .../bond/reputation/MyReputation.java | 32 ++++-- .../main/dao/bonding/BondingViewUtils.java | 56 +++++++---- .../MyBondedReputationListItem.java | 4 - .../reputation/MyBondedReputationView.java | 2 +- 12 files changed, 162 insertions(+), 161 deletions(-) diff --git a/common/src/main/proto/pb.proto b/common/src/main/proto/pb.proto index 51e0f1be1ec..435a98eccd2 100644 --- a/common/src/main/proto/pb.proto +++ b/common/src/main/proto/pb.proto @@ -1547,7 +1547,8 @@ message Role { } message MyReputation { - bytes salt = 1; + string uid = 1; + bytes salt = 2; } message MyReputationList { diff --git a/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java b/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java index 7bd348897eb..6297b5da6a0 100644 --- a/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java +++ b/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java @@ -64,6 +64,7 @@ import java.util.concurrent.CopyOnWriteArraySet; import java.util.function.Function; import java.util.stream.Collectors; +import java.util.stream.Stream; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -299,6 +300,11 @@ public ObservableList getWalletTransactions() { return walletTransactions; } + public Stream getPendingWalletTransactionsStream() { + return walletTransactions.stream() + .filter(transaction -> transaction.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.PENDING); + } + private void updateBsqWalletTransactions() { walletTransactions.setAll(getTransactions(false)); // walletTransactions.setAll(getBsqWalletTransactions()); diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index 95e449f5ebd..acbc7677391 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -25,7 +25,6 @@ import bisq.core.dao.governance.blindvote.BlindVoteConsensus; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; import bisq.core.dao.governance.bond.Bond; -import bisq.core.dao.governance.bond.BondedAsset; import bisq.core.dao.governance.bond.lockup.LockupService; import bisq.core.dao.governance.bond.lockup.LockupType; import bisq.core.dao.governance.bond.reputation.BondedReputation; @@ -493,9 +492,9 @@ public int getChainHeight() { // Use case: Bonding /////////////////////////////////////////////////////////////////////////////////////////// - public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, BondedAsset bondedAsset, + public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, byte[] hash, Consumer resultHandler, ExceptionHandler exceptionHandler) { - lockupService.publishLockupTx(lockupAmount, lockTime, lockupType, bondedAsset, resultHandler, exceptionHandler); + lockupService.publishLockupTx(lockupAmount, lockTime, lockupType, hash, resultHandler, exceptionHandler); } public void publishUnlockTx(String lockupTxId, Consumer resultHandler, diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java b/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java index f0d77b5564a..820a9c13ca9 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java @@ -87,8 +87,4 @@ public static boolean isLockTimeOver(long unlockBlockHeight, long currentBlockHe public static byte[] getHashFromOpReturnData(byte[] opReturnData) { return Arrays.copyOfRange(opReturnData, 5, 25); } - - public static byte[] getHash(BondedAsset bondedAsset) { - return bondedAsset.getHash(); - } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondService.java b/core/src/main/java/bisq/core/dao/governance/bond/BondService.java index c7ec3978e9e..2902ff5f23e 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondService.java @@ -24,11 +24,11 @@ import bisq.core.dao.state.model.blockchain.BaseTxOutput; import bisq.core.dao.state.model.blockchain.Block; import bisq.core.dao.state.model.blockchain.SpentInfo; +import bisq.core.dao.state.model.blockchain.Tx; import bisq.core.dao.state.model.blockchain.TxOutput; import bisq.core.dao.state.model.blockchain.TxType; import org.bitcoinj.core.Transaction; -import org.bitcoinj.core.TransactionConfidence; import org.bitcoinj.core.TransactionInput; import org.bitcoinj.core.TransactionOutput; @@ -124,37 +124,43 @@ public void updateBond(T bond, R bondedAsset, TxOutput lockupTxOutput) { // unique binding of the tx to the data object. byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); Optional candidate = findBondedAssetByHash(hash); - if (candidate.isPresent() && bondedAsset.equals(candidate.get())) { - bond.setBondState(BondState.LOCKUP_TX_CONFIRMED); - bond.setLockupTxId(lockupTx.getId()); - // We use the tx time as we want to have a unique time for all users - bond.setLockupDate(lockupTx.getTime()); - bond.setAmount(lockupTx.getLockedAmount()); - bond.setLockTime(lockupTx.getLockTime()); - if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { - // Lockup is already spent (in unlock tx) - daoStateService.getSpentInfo(lockupTxOutput) - .map(SpentInfo::getTxId) - .flatMap(daoStateService::getTx) - .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) - .ifPresent(unlockTx -> { - // cross check if it is in daoStateService.getUnlockTxOutputs() ? - String unlockTxId = unlockTx.getId(); - bond.setUnlockTxId(unlockTxId); - bond.setBondState(BondState.UNLOCK_TX_CONFIRMED); - bond.setUnlockDate(unlockTx.getTime()); - boolean unlocking = daoStateService.isUnlocking(unlockTxId); - if (unlocking) { - bond.setBondState(BondState.UNLOCKING); - } else { - bond.setBondState(BondState.UNLOCKED); - } - }); - } - } + if (candidate.isPresent() && bondedAsset.equals(candidate.get())) + applyBondState(daoStateService, bond, lockupTx, lockupTxOutput); }); } + public static void applyBondState(DaoStateService daoStateService, Bond bond, Tx lockupTx, TxOutput lockupTxOutput) { + if (bond.getBondState() != BondState.LOCKUP_TX_PENDING || bond.getBondState() != BondState.UNLOCK_TX_PENDING) + bond.setBondState(BondState.LOCKUP_TX_CONFIRMED); + + bond.setLockupTxId(lockupTx.getId()); + // We use the tx time as we want to have a unique time for all users + bond.setLockupDate(lockupTx.getTime()); + bond.setAmount(lockupTx.getLockedAmount()); + bond.setLockTime(lockupTx.getLockTime()); + + if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { + // Lockup is already spent (in unlock tx) + daoStateService.getSpentInfo(lockupTxOutput) + .map(SpentInfo::getTxId) + .flatMap(daoStateService::getTx) + .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) + .ifPresent(unlockTx -> { + // cross check if it is in daoStateService.getUnlockTxOutputs() ? + String unlockTxId = unlockTx.getId(); + bond.setUnlockTxId(unlockTxId); + bond.setBondState(BondState.UNLOCK_TX_CONFIRMED); + bond.setUnlockDate(unlockTx.getTime()); + boolean unlocking = daoStateService.isUnlocking(unlockTxId); + if (unlocking) { + bond.setBondState(BondState.UNLOCKING); + } else { + bond.setBondState(BondState.UNLOCKED); + } + }); + } + } + protected abstract T createBond(R bondedAsset); @Override @@ -195,29 +201,33 @@ public Optional findBondedAssetByHash(byte[] hash) { } + /////////////////////////////////////////////////////////////////////////////////////////// + // Protected + /////////////////////////////////////////////////////////////////////////////////////////// + + abstract protected Stream getBondedAssetStream(); + + /////////////////////////////////////////////////////////////////////////////////////////// // Private /////////////////////////////////////////////////////////////////////////////////////////// private void updateBondStateFromUnconfirmedLockupTxs() { - getBondedAssetStream().filter(this::isLockupTxUnconfirmed) + getBondedAssetStream().filter(bondedAsset -> isLockupTxUnconfirmed(bsqWalletService, bondedAsset)) .map(bondedAsset -> bondByUidMap.get(bondedAsset.getUid())) .filter(bond -> bond.getBondState() == BondState.READY_FOR_LOCKUP) .forEach(bond -> bond.setBondState(BondState.LOCKUP_TX_PENDING)); } private void updateBondStateFromUnconfirmedUnlockTxs() { - getBondedAssetStream().filter(this::isUnlockTxUnconfirmed) + getBondedAssetStream().filter(bondedAsset -> isUnlockTxUnconfirmed(bsqWalletService, daoStateService, bondedAsset)) .map(bondedAsset -> bondByUidMap.get(bondedAsset.getUid())) .filter(bond -> bond.getBondState() == BondState.LOCKUP_TX_CONFIRMED) .forEach(bond -> bond.setBondState(BondState.UNLOCK_TX_PENDING)); } - abstract protected Stream getBondedAssetStream(); - - - public boolean isLockupTxUnconfirmed(R bondedAsset) { - return getPendingWalletTransactionsStream() + public static boolean isLockupTxUnconfirmed(BsqWalletService bsqWalletService, BondedAsset bondedAsset) { + return bsqWalletService.getPendingWalletTransactionsStream() .map(transaction -> transaction.getOutputs().get(transaction.getOutputs().size() - 1)) .filter(lastOutput -> lastOutput.getScriptPubKey().isOpReturn()) .map(lastOutput -> lastOutput.getScriptPubKey().getChunks()) @@ -226,22 +236,19 @@ public boolean isLockupTxUnconfirmed(R bondedAsset) { .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondedAsset.getHash())); } - private boolean isUnlockTxUnconfirmed(R bondedAsset) { - return getPendingWalletTransactionsStream() + public static boolean isUnlockTxUnconfirmed(BsqWalletService bsqWalletService, DaoStateService daoStateService, BondedAsset bondedAsset) { + return bsqWalletService.getPendingWalletTransactionsStream() .filter(transaction -> transaction.getInputs().size() > 1) - .map(transaction -> transaction.getInputs().get(0)) + .flatMap(transaction -> transaction.getInputs().stream()) // We need to iterate all inputs .map(TransactionInput::getConnectedOutput) .filter(Objects::nonNull) + .filter(transactionOutput -> transactionOutput.getIndex() == 0) // The output at the lockupTx must be index 0 .map(TransactionOutput::getParentTransaction) .filter(Objects::nonNull) .map(Transaction::getHashAsString) - .flatMap(lockupTxId -> daoStateService.getLockupOpReturnTxOutput(lockupTxId).stream()) + .map(lockupTxId -> daoStateService.getLockupOpReturnTxOutput(lockupTxId).orElse(null)) + .filter(Objects::nonNull) .map(BaseTxOutput::getOpReturnData) .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondedAsset.getHash())); } - - private Stream getPendingWalletTransactionsStream() { - return bsqWalletService.getWalletTransactions().stream() - .filter(transaction -> transaction.getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.PENDING); - } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java index 2e95c44e410..bc72fa8c214 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java @@ -26,11 +26,6 @@ import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsManager; import bisq.core.dao.governance.bond.BondConsensus; -import bisq.core.dao.governance.bond.BondedAsset; -import bisq.core.dao.governance.bond.reputation.MyReputation; -import bisq.core.dao.governance.bond.reputation.MyReputationListService; -import bisq.core.dao.governance.bond.role.BondedRolesService; -import bisq.core.dao.state.model.governance.Role; import bisq.common.handlers.ExceptionHandler; @@ -53,8 +48,6 @@ public class LockupService { private final WalletsManager walletsManager; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; - private final MyReputationListService myReputationListService; - private final BondedRolesService bondedRolesService; /////////////////////////////////////////////////////////////////////////////////////////// @@ -64,31 +57,16 @@ public class LockupService { @Inject public LockupService(WalletsManager walletsManager, BsqWalletService bsqWalletService, - BtcWalletService btcWalletService, - MyReputationListService myReputationListService, - BondedRolesService bondedRolesService) { + BtcWalletService btcWalletService) { this.walletsManager = walletsManager; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; - this.myReputationListService = myReputationListService; - this.bondedRolesService = bondedRolesService; } - public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, BondedAsset bondedAsset, + public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, byte[] hash, Consumer resultHandler, ExceptionHandler exceptionHandler) { checkArgument(lockTime <= BondConsensus.getMaxLockTime() && lockTime >= BondConsensus.getMinLockTime(), "lockTime not in rage"); - if (bondedAsset instanceof Role) { - Role role = (Role) bondedAsset; - if (bondedRolesService.wasBondedAssetAlreadyBonded(role)) { - exceptionHandler.handleException(new RuntimeException("The role has been used already for a lockup tx.")); - return; - } - } else if (bondedAsset instanceof MyReputation) { - myReputationListService.addReputation((MyReputation) bondedAsset); - } - - byte[] hash = BondConsensus.getHash(bondedAsset); try { byte[] opReturnData = BondConsensus.getLockupOpReturnData(lockTime, lockupType, hash); Transaction lockupTx = createLockupTx(lockupAmount, opReturnData); diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java index 44ebafdb93d..61deed63273 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java @@ -90,26 +90,28 @@ protected Stream getBondedAssetStream() { @Override protected void updateMap() { - bondByUidMap.clear(); + //TODO + /* bondByUidMap.clear(); getBondedReputationStream().forEach(bondedReputation -> { bondByUidMap.put(bondedReputation.getBondedAsset().getUid(), bondedReputation); - }); + });*/ } private Stream getBondedReputationStream() { return daoStateService.getLockupTxOutputs().stream() .map(lockupTxOutput -> { - String txId = lockupTxOutput.getTxId(); - // long time = daoStateService.getTx(txId).map(BaseTx::getTime).orElse(0L); + String lockupTxId = lockupTxOutput.getTxId(); + // long time = daoStateService.getTx(lockupTxId).map(BaseTx::getTime).orElse(0L); // lockupTxOutput is first output, but we need the data from the opReturn - Optional optionalOpReturnTxOutput = daoStateService.getLockupOpReturnTxOutput(txId); + Optional optionalOpReturnTxOutput = daoStateService.getLockupOpReturnTxOutput(lockupTxId); if (optionalOpReturnTxOutput.isPresent()) { TxOutput opReturnTxOutput = optionalOpReturnTxOutput.get(); byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnTxOutput.getOpReturnData()); Reputation reputation = new Reputation(hash); BondedReputation bondedReputation = new BondedReputation(reputation); - updateBond(bondedReputation, reputation, lockupTxOutput); + //TODO + //updateBond(bondedReputation, reputation, lockupTxOutput); return bondedReputation; } else { return null; @@ -118,9 +120,4 @@ private Stream getBondedReputationStream() { }) .filter(Objects::nonNull); } - - @Override - public Optional findBondedAssetByHash(byte[] hash) { - return Optional.of(new Reputation(hash)); - } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java index cd8da8118bf..d404eaf2c47 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java @@ -17,26 +17,29 @@ package bisq.core.dao.governance.bond.reputation; +import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoSetupService; import bisq.core.dao.governance.bond.BondConsensus; +import bisq.core.dao.governance.bond.BondService; import bisq.core.dao.governance.bond.BondState; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.model.blockchain.SpentInfo; -import bisq.core.dao.state.model.blockchain.TxType; import javax.inject.Inject; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; @Slf4j public class MyBondedReputationService implements DaoSetupService { private final DaoStateService daoStateService; + private final BsqWalletService bsqWalletService; private final MyReputationListService myReputationListService; @@ -46,8 +49,10 @@ public class MyBondedReputationService implements DaoSetupService { @Inject public MyBondedReputationService(DaoStateService daoStateService, + BsqWalletService bsqWalletService, MyReputationListService myReputationListService) { this.daoStateService = daoStateService; + this.bsqWalletService = bsqWalletService; this.myReputationListService = myReputationListService; } @@ -70,15 +75,31 @@ public void start() { /////////////////////////////////////////////////////////////////////////////////////////// public List getMyBondedReputations() { - return myReputationListService.getMyReputationList().stream() - .map(myReputation -> getMyBondedReputation(myReputation).orElse(null)) - .filter(Objects::nonNull) + // It can be that the same salt/hash is in several lockupTxs, so we use a map to eliminate duplicates by the + // collection algorithm. + Map map = new HashMap<>(); + myReputationListService.getMyReputationList().stream() + .flatMap(this::getMyBondedReputation) + .forEach(e -> map.putIfAbsent(e.getLockupTxId(), e)); + + return map.values().stream() + .peek(myBondedReputation -> { + // We don't have a UI use case for showing LOCKUP_TX_PENDING yet, but lets keep the code so if needed + // its there. + if (BondService.isLockupTxUnconfirmed(bsqWalletService, myBondedReputation.getBondedAsset()) && + myBondedReputation.getBondState() == BondState.READY_FOR_LOCKUP) { + myBondedReputation.setBondState(BondState.LOCKUP_TX_PENDING); + } else if (BondService.isUnlockTxUnconfirmed(bsqWalletService, daoStateService, myBondedReputation.getBondedAsset()) && + myBondedReputation.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { + myBondedReputation.setBondState(BondState.UNLOCK_TX_PENDING); + } + }) .collect(Collectors.toList()); } - private Optional getMyBondedReputation(MyReputation myReputation) { + private Stream getMyBondedReputation(MyReputation myReputation) { return daoStateService.getLockupTxOutputs().stream() - .map(lockupTxOutput -> { + .flatMap(lockupTxOutput -> { String lockupTxId = lockupTxOutput.getTxId(); return daoStateService.getTx(lockupTxId) .map(lockupTx -> { @@ -86,40 +107,14 @@ private Optional getMyBondedReputation(MyReputation myReputa byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); if (Arrays.equals(hash, myReputation.getHash())) { MyBondedReputation myBondedReputation = new MyBondedReputation(myReputation); - myBondedReputation.setLockTime(lockupTx.getLockTime()); - myBondedReputation.setBondState(BondState.LOCKUP_TX_CONFIRMED); - myBondedReputation.setLockupTxId(lockupTx.getId()); - // We use the tx time as we want to have a unique time for all users - myBondedReputation.setLockupDate(lockupTx.getTime()); - myBondedReputation.setAmount(lockupTx.getLockedAmount()); - if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { - // Lockup is already spent (in unlock tx) - daoStateService.getSpentInfo(lockupTxOutput) - .map(SpentInfo::getTxId) - .flatMap(daoStateService::getTx) - .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) - .ifPresent(unlockTx -> { - // cross check if it is in daoStateService.getUnlockTxOutputs() ? - String unlockTxId = unlockTx.getId(); - myBondedReputation.setUnlockTxId(unlockTxId); - myBondedReputation.setBondState(BondState.UNLOCK_TX_CONFIRMED); - myBondedReputation.setUnlockDate(unlockTx.getTime()); - boolean unlocking = daoStateService.isUnlocking(unlockTxId); - if (unlocking) { - myBondedReputation.setBondState(BondState.UNLOCKING); - } else { - myBondedReputation.setBondState(BondState.UNLOCKED); - } - }); - } + BondService.applyBondState(daoStateService, myBondedReputation, lockupTx, lockupTxOutput); return myBondedReputation; } else { return null; } }) - .orElse(null); + .stream(); }) - .filter(Objects::nonNull) - .findAny(); + .filter(Objects::nonNull); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java index 2edfaace643..b7311c0a7db 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java @@ -29,6 +29,8 @@ import com.google.protobuf.ByteString; import java.util.Arrays; +import java.util.Objects; +import java.util.UUID; import lombok.Value; import lombok.extern.slf4j.Slf4j; @@ -39,13 +41,12 @@ @Value @Slf4j public final class MyReputation implements PersistablePayload, NetworkPayload, BondedAsset { + private final String uid; private final byte[] salt; private final transient byte[] hash; // not persisted as it is derived from salt. Stored for caching purpose only. - public MyReputation(byte[] salt) { - this.salt = salt; - this.hash = Hash.getSha256Ripemd160hash(salt); + this(UUID.randomUUID().toString(), salt); } @@ -53,13 +54,22 @@ public MyReputation(byte[] salt) { // PROTO BUFFER /////////////////////////////////////////////////////////////////////////////////////////// + private MyReputation(String uid, byte[] salt) { + this.uid = uid; + this.salt = salt; + this.hash = Hash.getSha256Ripemd160hash(salt); + } + @Override public PB.MyReputation toProtoMessage() { - return PB.MyReputation.newBuilder().setSalt(ByteString.copyFrom(salt)).build(); + return PB.MyReputation.newBuilder() + .setUid(uid) + .setSalt(ByteString.copyFrom(salt)) + .build(); } public static MyReputation fromProto(PB.MyReputation proto) { - return new MyReputation(proto.getSalt().toByteArray()); + return new MyReputation(proto.getUid(), proto.getSalt().toByteArray()); } @@ -88,23 +98,25 @@ public boolean equals(Object o) { if (!(o instanceof MyReputation)) return false; if (!super.equals(o)) return false; MyReputation that = (MyReputation) o; - return Arrays.equals(hash, that.hash); + return Objects.equals(uid, that.uid) && + Arrays.equals(salt, that.salt); } @Override public int hashCode() { - int result = super.hashCode(); - result = 31 * result + Arrays.hashCode(hash); + + int result = Objects.hash(super.hashCode(), uid); + result = 31 * result + Arrays.hashCode(salt); return result; } - - /////////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////// // API /////////////////////////////////////////////////////////////////////////////////////////// @Override public String toString() { return "MyReputation{" + + "\n uid=" + uid + "\n salt=" + Utilities.bytesAsHexString(salt) + "\n hash=" + Utilities.bytesAsHexString(hash) + "\n}"; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java index 03f26b0eeef..9aa2bdc6c75 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java @@ -26,9 +26,10 @@ import bisq.core.btc.setup.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.BondedAsset; import bisq.core.dao.governance.bond.lockup.LockupType; import bisq.core.dao.governance.bond.reputation.MyReputation; +import bisq.core.dao.governance.bond.reputation.MyReputationListService; +import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.state.model.blockchain.TxOutput; import bisq.core.dao.state.model.governance.BondedRoleType; import bisq.core.dao.state.model.governance.Role; @@ -53,24 +54,49 @@ @Slf4j public class BondingViewUtils { - private final P2PService p2PService; + private final MyReputationListService myReputationListService; + private final BondedRolesService bondedRolesService; private final WalletsSetup walletsSetup; private final DaoFacade daoFacade; private final Navigation navigation; private final BsqFormatter bsqFormatter; @Inject - public BondingViewUtils(P2PService p2PService, WalletsSetup walletsSetup, DaoFacade daoFacade, - Navigation navigation, BsqFormatter bsqFormatter) { + public BondingViewUtils(P2PService p2PService, + MyReputationListService myReputationListService, + BondedRolesService bondedRolesService, + WalletsSetup walletsSetup, + DaoFacade daoFacade, + Navigation navigation, + BsqFormatter bsqFormatter) { this.p2PService = p2PService; + this.myReputationListService = myReputationListService; + this.bondedRolesService = bondedRolesService; this.walletsSetup = walletsSetup; this.daoFacade = daoFacade; this.navigation = navigation; this.bsqFormatter = bsqFormatter; } - private void lockupBond(BondedAsset bondedAsset, Coin lockupAmount, int lockupTime, LockupType lockupType, + public void lockupBondForBondedRole(Role role, Consumer resultHandler) { + BondedRoleType bondedRoleType = role.getBondedRoleType(); + Coin lockupAmount = Coin.valueOf(bondedRoleType.getRequiredBond()); + int lockupTime = bondedRoleType.getUnlockTimeInBlocks(); + if (!bondedRolesService.wasBondedAssetAlreadyBonded(role)) { + lockupBond(role.getHash(), lockupAmount, lockupTime, LockupType.BONDED_ROLE, resultHandler); + } else { + handleError(new RuntimeException("The role has been used already for a lockup tx.")); + } + } + + public void lockupBondForReputation(Coin lockupAmount, int lockupTime, byte[] salt, Consumer resultHandler) { + MyReputation myReputation = new MyReputation(salt); + lockupBond(myReputation.getHash(), lockupAmount, lockupTime, LockupType.REPUTATION, resultHandler); + myReputationListService.addReputation(myReputation); + } + + private void lockupBond(byte[] hash, Coin lockupAmount, int lockupTime, LockupType lockupType, Consumer resultHandler) { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { if (!DevEnv.isDevMode()) { @@ -80,22 +106,22 @@ private void lockupBond(BondedAsset bondedAsset, Coin lockupAmount, int lockupTi lockupTime )) .actionButtonText(Res.get("shared.yes")) - .onAction(() -> publishLockupTx(bondedAsset, lockupAmount, lockupTime, lockupType, resultHandler)) + .onAction(() -> publishLockupTx(hash, lockupAmount, lockupTime, lockupType, resultHandler)) .closeButtonText(Res.get("shared.cancel")) .show(); } else { - publishLockupTx(bondedAsset, lockupAmount, lockupTime, lockupType, resultHandler); + publishLockupTx(hash, lockupAmount, lockupTime, lockupType, resultHandler); } } else { GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); } } - private void publishLockupTx(BondedAsset bondedAsset, Coin lockupAmount, int lockupTime, LockupType lockupType, Consumer resultHandler) { + private void publishLockupTx(byte[] hash, Coin lockupAmount, int lockupTime, LockupType lockupType, Consumer resultHandler) { daoFacade.publishLockupTx(lockupAmount, lockupTime, lockupType, - bondedAsset, + hash, txId -> { if (!DevEnv.isDevMode()) new Popup<>().feedback(Res.get("dao.tx.published.success")).show(); @@ -107,18 +133,6 @@ private void publishLockupTx(BondedAsset bondedAsset, Coin lockupAmount, int loc ); } - public void lockupBondForBondedRole(Role role, Consumer resultHandler) { - BondedRoleType bondedRoleType = role.getBondedRoleType(); - Coin lockupAmount = Coin.valueOf(bondedRoleType.getRequiredBond()); - int lockupTime = bondedRoleType.getUnlockTimeInBlocks(); - lockupBond(role, lockupAmount, lockupTime, LockupType.BONDED_ROLE, resultHandler); - } - - public void lockupBondForReputation(Coin lockupAmount, int lockupTime, byte[] salt, Consumer resultHandler) { - MyReputation myReputation = new MyReputation(salt); - lockupBond(myReputation, lockupAmount, lockupTime, LockupType.REPUTATION, resultHandler); - } - public void unLock(String lockupTxId, Consumer resultHandler) { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { Optional lockupTxOutput = daoFacade.getLockupTxOutput(lockupTxId); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java index a176b5f2d05..3df6578cfe6 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java @@ -85,10 +85,6 @@ class MyBondedReputationListItem implements DaoStateListener { if (myBondedReputation.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { bondingViewUtils.unLock(myBondedReputation.getLockupTxId(), txId -> { - myBondedReputation.setUnlockTxId(txId); - myBondedReputation.setBondState(BondState.UNLOCK_TX_PENDING); - update(); - button.setDisable(true); }); } }); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java index db9ed2d93fe..0a57620c46d 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java @@ -338,7 +338,7 @@ private void updateList() { .sorted(Comparator.comparing(MyBondedReputationListItem::getLockupDate).reversed()) .collect(Collectors.toList()); observableList.setAll(items); - GUIUtil.setFitToRowsForTableView(tableView, 41, 28, 2, 4); + GUIUtil.setFitToRowsForTableView(tableView, 41, 28, 2, 10); } From 8e3864589a13c6638523956b6fbf024753a79554 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Mon, 5 Nov 2018 21:26:00 -0500 Subject: [PATCH 20/27] Complete bonds view --- .../main/java/bisq/core/dao/DaoFacade.java | 10 +- .../core/dao/governance/bond/BondService.java | 4 + .../reputation/BondedReputationService.java | 56 +++--- .../resources/i18n/displayStrings.properties | 6 +- .../i18n/displayStrings_de.properties | 4 +- .../i18n/displayStrings_el.properties | 4 +- .../i18n/displayStrings_es.properties | 4 +- .../i18n/displayStrings_fa.properties | 4 +- .../i18n/displayStrings_hu.properties | 4 +- .../i18n/displayStrings_pt.properties | 4 +- .../i18n/displayStrings_ro.properties | 4 +- .../i18n/displayStrings_ru.properties | 4 +- .../i18n/displayStrings_sr.properties | 4 +- .../i18n/displayStrings_th.properties | 4 +- .../i18n/displayStrings_vi.properties | 4 +- .../i18n/displayStrings_zh.properties | 4 +- .../main/dao/bonding/bonds/BondListItem.java | 67 +++---- .../main/dao/bonding/bonds/BondsView.fxml | 4 +- .../main/dao/bonding/bonds/BondsView.java | 168 ++++++++++-------- .../reputation/MyBondedReputationView.java | 8 +- .../dao/bonding/roles/BondedRolesView.java | 26 +-- .../main/dao/governance/ProposalDisplay.java | 2 +- 22 files changed, 197 insertions(+), 202 deletions(-) diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index acbc7677391..08d0b7b70d9 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -522,11 +522,11 @@ public List getActiveBondedRoles() { return bondedRolesService.getActiveBonds(); } - public List getAllActiveBonds() { - List activeReputations = bondedReputationService.getActiveBonds(); - List activeRoles = bondedRolesService.getActiveBonds(); - List bonds = new ArrayList<>(activeReputations); - bonds.addAll(activeRoles); + public List getAllBonds() { + List bondedReputations = bondedReputationService.getAllBonds(); + List bondedRoles = bondedRolesService.getAllBonds(); + List bonds = new ArrayList<>(bondedReputations); + bonds.addAll(bondedRoles); return bonds; } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondService.java b/core/src/main/java/bisq/core/dao/governance/bond/BondService.java index 2902ff5f23e..9a5afed82b8 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondService.java @@ -182,6 +182,10 @@ public List getActiveBonds() { .collect(Collectors.toList()); } + public List getAllBonds() { + return new ArrayList<>(bondByUidMap.values()); + } + public Optional findBondByLockupTxId(String lockupTxId) { return bondByUidMap.values().stream() .filter(bond -> lockupTxId.equals(bond.getLockupTxId())) diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java index 61deed63273..5e9f1958762 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java @@ -21,15 +21,15 @@ import bisq.core.dao.governance.bond.Bond; import bisq.core.dao.governance.bond.BondConsensus; import bisq.core.dao.governance.bond.BondService; +import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.model.blockchain.TxOutput; import javax.inject.Inject; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -37,40 +37,18 @@ @Slf4j public class BondedReputationService extends BondService { + private final BondedRolesService bondedRolesService; /////////////////////////////////////////////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public BondedReputationService(DaoStateService daoStateService, BsqWalletService bsqWalletService) { + public BondedReputationService(DaoStateService daoStateService, BsqWalletService bsqWalletService, + BondedRolesService bondedRolesService) { super(daoStateService, bsqWalletService); - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // API - /////////////////////////////////////////////////////////////////////////////////////////// - - public List getActiveBondedReputations() { - return bondByUidMap.values().stream() - .filter(e -> e.isActive()) - .collect(Collectors.toList()); - } - - public List getAllBondedReputations() { - return new ArrayList<>(bondByUidMap.values()); - } - - public List getUnconfirmedBondedReputations() { - //TODO - /* Set myWalletTransactionIds = bsqWalletService.getWalletTransactions().stream() - .map(Transaction::getHashAsString) - .collect(Collectors.toSet()); -*/ - return bondByUidMap.values().stream() - .filter(e -> e.isActive()) - .collect(Collectors.toList()); + this.bondedRolesService = bondedRolesService; } @@ -90,15 +68,14 @@ protected Stream getBondedAssetStream() { @Override protected void updateMap() { - //TODO - /* bondByUidMap.clear(); + bondByUidMap.clear(); getBondedReputationStream().forEach(bondedReputation -> { bondByUidMap.put(bondedReputation.getBondedAsset().getUid(), bondedReputation); - });*/ + }); } - private Stream getBondedReputationStream() { + Set bondedRolesLockupTxIdSet = bondedRolesService.getAllBonds().stream().map(e -> e.getLockupTxId()).collect(Collectors.toSet()); return daoStateService.getLockupTxOutputs().stream() .map(lockupTxOutput -> { String lockupTxId = lockupTxOutput.getTxId(); @@ -110,14 +87,23 @@ private Stream getBondedReputationStream() { byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnTxOutput.getOpReturnData()); Reputation reputation = new Reputation(hash); BondedReputation bondedReputation = new BondedReputation(reputation); - //TODO - //updateBond(bondedReputation, reputation, lockupTxOutput); + updateBond(bondedReputation, reputation, lockupTxOutput); return bondedReputation; } else { return null; } }) - .filter(Objects::nonNull); + .filter(Objects::nonNull) + .filter(e -> !bondedRolesLockupTxIdSet.contains(e.getLockupTxId())); + } + + @Override + public void updateBond(BondedReputation bond, Reputation bondedAsset, TxOutput lockupTxOutput) { + // Lets see if we have a lock up tx. + String lockupTxId = lockupTxOutput.getTxId(); + daoStateService.getTx(lockupTxId).ifPresent(lockupTx -> { + applyBondState(daoStateService, bond, lockupTx, lockupTxOutput); + }); } } diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 55b34cb239a..10c86269788 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -1333,6 +1333,7 @@ dao.bonding.dashboard.bondsHeadline=Bonded BSQ dao.bonding.dashboard.lockupAmount=Lockup funds dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over) dao.bonding.bonds.table.lockupTxId=Lockup tx ID +dao.bonding.bonds.table.header=All bonds dao.bonding.info=Lockup Tx ID: {0} / {1} dao.bonding.reputation.salt.info=Salt: {0} @@ -1386,11 +1387,12 @@ dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holder dao.bond.bondedRoleType.details.blocks={0} blocks dao.bond.bondedReputation=Bonded Reputation +dao.bond.bondedRoles=Bonded roles -dao.bond.table.header=Bonded roles dao.bond.table.column.header.name=Name dao.bond.table.column.header.link=Link -dao.bond.table.column.header.bondedRoleType=Role +dao.bond.table.column.header.bondType=Bond type +dao.bond.table.column.header.details=Details dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/core/src/main/resources/i18n/displayStrings_de.properties b/core/src/main/resources/i18n/displayStrings_de.properties index 9cee89f2691..824d0390208 100644 --- a/core/src/main/resources/i18n/displayStrings_de.properties +++ b/core/src/main/resources/i18n/displayStrings_de.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link zur Rollenbeschreibung dao.bond.bondedRoleType.details.isSingleton=Kann von mehreren Rollenhalter genommen werden dao.bond.bondedRoleType.details.blocks={0} Blöcke -dao.bond.table.header=Gekoppelte Rollen +dao.bond.bondedRoles=Gekoppelte Rollen dao.bond.table.column.header.name=Name dao.bond.table.column.header.link=Konto -dao.bond.table.column.header.bondedRoleType=Rolle +dao.bond.table.column.header.bondType=Rolle dao.bond.table.column.header.startDate=Gestartet dao.bond.table.column.header.lockupTxId=Sperrung Tx ID dao.bond.table.column.header.revokeDate=Widerrufen diff --git a/core/src/main/resources/i18n/displayStrings_el.properties b/core/src/main/resources/i18n/displayStrings_el.properties index 878d35883cb..b12d93874fb 100644 --- a/core/src/main/resources/i18n/displayStrings_el.properties +++ b/core/src/main/resources/i18n/displayStrings_el.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link to role description dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders dao.bond.bondedRoleType.details.blocks={0} blocks -dao.bond.table.header=Bonded roles +dao.bond.bondedRoles=Bonded roles dao.bond.table.column.header.name=Όνομα dao.bond.table.column.header.link=Λογαριασμός -dao.bond.table.column.header.bondedRoleType=Ρόλος +dao.bond.table.column.header.bondType=Ρόλος dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/core/src/main/resources/i18n/displayStrings_es.properties b/core/src/main/resources/i18n/displayStrings_es.properties index a01ad8cb744..af4b5862eff 100644 --- a/core/src/main/resources/i18n/displayStrings_es.properties +++ b/core/src/main/resources/i18n/displayStrings_es.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link to role description dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders dao.bond.bondedRoleType.details.blocks={0} blocks -dao.bond.table.header=Bonded roles +dao.bond.bondedRoles=Bonded roles dao.bond.table.column.header.name=Nombre dao.bond.table.column.header.link=Cuenta -dao.bond.table.column.header.bondedRoleType=Rol +dao.bond.table.column.header.bondType=Rol dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/core/src/main/resources/i18n/displayStrings_fa.properties b/core/src/main/resources/i18n/displayStrings_fa.properties index 0106d34e69c..b04ad168199 100644 --- a/core/src/main/resources/i18n/displayStrings_fa.properties +++ b/core/src/main/resources/i18n/displayStrings_fa.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link to role description dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders dao.bond.bondedRoleType.details.blocks={0} blocks -dao.bond.table.header=Bonded roles +dao.bond.bondedRoles=Bonded roles dao.bond.table.column.header.name=نام dao.bond.table.column.header.link=حساب -dao.bond.table.column.header.bondedRoleType=نقش +dao.bond.table.column.header.bondType=نقش dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/core/src/main/resources/i18n/displayStrings_hu.properties b/core/src/main/resources/i18n/displayStrings_hu.properties index 8a5527ae47d..5d0f417f341 100644 --- a/core/src/main/resources/i18n/displayStrings_hu.properties +++ b/core/src/main/resources/i18n/displayStrings_hu.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link to role description dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders dao.bond.bondedRoleType.details.blocks={0} blocks -dao.bond.table.header=Bonded roles +dao.bond.bondedRoles=Bonded roles dao.bond.table.column.header.name=Név dao.bond.table.column.header.link=Fiók -dao.bond.table.column.header.bondedRoleType=Szerep +dao.bond.table.column.header.bondType=Szerep dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/core/src/main/resources/i18n/displayStrings_pt.properties b/core/src/main/resources/i18n/displayStrings_pt.properties index 2376a9c8a3b..b881a6def40 100644 --- a/core/src/main/resources/i18n/displayStrings_pt.properties +++ b/core/src/main/resources/i18n/displayStrings_pt.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link to role description dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders dao.bond.bondedRoleType.details.blocks={0} blocks -dao.bond.table.header=Bonded roles +dao.bond.bondedRoles=Bonded roles dao.bond.table.column.header.name=Nome dao.bond.table.column.header.link=Conta -dao.bond.table.column.header.bondedRoleType=Função +dao.bond.table.column.header.bondType=Função dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/core/src/main/resources/i18n/displayStrings_ro.properties b/core/src/main/resources/i18n/displayStrings_ro.properties index c58f1557dbd..9e5439f20fe 100644 --- a/core/src/main/resources/i18n/displayStrings_ro.properties +++ b/core/src/main/resources/i18n/displayStrings_ro.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link to role description dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders dao.bond.bondedRoleType.details.blocks={0} blocks -dao.bond.table.header=Bonded roles +dao.bond.bondedRoles=Bonded roles dao.bond.table.column.header.name=Nume dao.bond.table.column.header.link=Cont -dao.bond.table.column.header.bondedRoleType=Rol +dao.bond.table.column.header.bondType=Rol dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/core/src/main/resources/i18n/displayStrings_ru.properties b/core/src/main/resources/i18n/displayStrings_ru.properties index 72f45fe859e..7871b5d3ad5 100644 --- a/core/src/main/resources/i18n/displayStrings_ru.properties +++ b/core/src/main/resources/i18n/displayStrings_ru.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Ссылка на подробности р dao.bond.bondedRoleType.details.isSingleton=Может быть принято несколькими держателями роли dao.bond.bondedRoleType.details.blocks={0} блоков -dao.bond.table.header=Обеспеченные роли +dao.bond.bondedRoles=Обеспеченные роли dao.bond.table.column.header.name=Имя dao.bond.table.column.header.link=Счёт -dao.bond.table.column.header.bondedRoleType=Роль +dao.bond.table.column.header.bondType=Роль dao.bond.table.column.header.startDate=Начато dao.bond.table.column.header.lockupTxId=Транз. идент. блокировки dao.bond.table.column.header.revokeDate=Аннулировано diff --git a/core/src/main/resources/i18n/displayStrings_sr.properties b/core/src/main/resources/i18n/displayStrings_sr.properties index 5cc99db11fe..74732beef2c 100644 --- a/core/src/main/resources/i18n/displayStrings_sr.properties +++ b/core/src/main/resources/i18n/displayStrings_sr.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link to role description dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders dao.bond.bondedRoleType.details.blocks={0} blocks -dao.bond.table.header=Bonded roles +dao.bond.bondedRoles=Bonded roles dao.bond.table.column.header.name=Ime dao.bond.table.column.header.link=Nalog -dao.bond.table.column.header.bondedRoleType=Uloga +dao.bond.table.column.header.bondType=Uloga dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/core/src/main/resources/i18n/displayStrings_th.properties b/core/src/main/resources/i18n/displayStrings_th.properties index d44cd51ab70..e8370961009 100644 --- a/core/src/main/resources/i18n/displayStrings_th.properties +++ b/core/src/main/resources/i18n/displayStrings_th.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link to role description dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders dao.bond.bondedRoleType.details.blocks={0} blocks -dao.bond.table.header=Bonded roles +dao.bond.bondedRoles=Bonded roles dao.bond.table.column.header.name=ชื่อ dao.bond.table.column.header.link=บัญชี -dao.bond.table.column.header.bondedRoleType=บทบาท +dao.bond.table.column.header.bondType=บทบาท dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/core/src/main/resources/i18n/displayStrings_vi.properties b/core/src/main/resources/i18n/displayStrings_vi.properties index 9c70e2dfa13..b70aa050885 100644 --- a/core/src/main/resources/i18n/displayStrings_vi.properties +++ b/core/src/main/resources/i18n/displayStrings_vi.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link to role description dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders dao.bond.bondedRoleType.details.blocks={0} blocks -dao.bond.table.header=Bonded roles +dao.bond.bondedRoles=Bonded roles dao.bond.table.column.header.name=Tên dao.bond.table.column.header.link=Tài khoản -dao.bond.table.column.header.bondedRoleType=Vai trò +dao.bond.table.column.header.bondType=Vai trò dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/core/src/main/resources/i18n/displayStrings_zh.properties b/core/src/main/resources/i18n/displayStrings_zh.properties index d4f86541e55..a7d1865639f 100644 --- a/core/src/main/resources/i18n/displayStrings_zh.properties +++ b/core/src/main/resources/i18n/displayStrings_zh.properties @@ -1161,10 +1161,10 @@ dao.bond.bondedRoleType.details.link=Link to role description dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders dao.bond.bondedRoleType.details.blocks={0} blocks -dao.bond.table.header=Bonded roles +dao.bond.bondedRoles=Bonded roles dao.bond.table.column.header.name=名称 dao.bond.table.column.header.link=账户 -dao.bond.table.column.header.bondedRoleType=角色 +dao.bond.table.column.header.bondType=角色 dao.bond.table.column.header.startDate=Started dao.bond.table.column.header.lockupTxId=Lockup Tx ID dao.bond.table.column.header.revokeDate=Revoked diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java index 5a6b0ccd97a..9911b155569 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java @@ -17,19 +17,23 @@ package bisq.desktop.main.dao.bonding.bonds; -import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.main.dao.bonding.BondingViewUtils; import bisq.core.dao.DaoFacade; import bisq.core.dao.governance.bond.Bond; +import bisq.core.dao.governance.bond.role.BondedRole; import bisq.core.dao.governance.bond.role.BondedRolesService; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; +import bisq.common.util.Utilities; + import org.bitcoinj.core.Coin; import javafx.scene.control.Button; +import javafx.scene.control.Label; import java.util.Date; @@ -47,10 +51,13 @@ class BondListItem implements DaoStateListener { private final BondedRolesService bondedRolesService; private final BondingViewUtils bondingViewUtils; private final BsqFormatter bsqFormatter; - private final String info; + private final String bondType; private final String txId; private final String amount; + private final String lockupDate; private final String lockTime; + private final Label stateLabel; + private final String bondDetails; @Getter private Button button; @@ -67,56 +74,30 @@ class BondListItem implements DaoStateListener { this.bsqFormatter = bsqFormatter; - info = bond.getBondedAsset().getDisplayString(); - txId = bond.getLockupTxId(); amount = bsqFormatter.formatCoin(Coin.valueOf(bond.getAmount())); - lockTime = bsqFormatter.formatDateTime(new Date(bond.getLockupDate())); + lockTime = Integer.toString(bond.getLockTime()); + if (bond instanceof BondedRole) { + bondType = Res.get("dao.bond.bondedRoles"); + bondDetails = bond.getBondedAsset().getDisplayString(); + } else { + bondType = Res.get("dao.bond.bondedReputation"); + bondDetails = Utilities.bytesAsHexString(bond.getBondedAsset().getHash()); + } + lockupDate = bsqFormatter.formatDateTime(new Date(bond.getLockupDate())); + txId = bond.getLockupTxId(); + + stateLabel = new Label(); - button = new AutoTooltipButton(); - button.setMinWidth(70); - // label = new Label(); -/* daoFacade.addBsqStateListener(this); - button.setOnAction(e -> { - if (bondedRole.getBondState() == BondState.READY_FOR_LOCKUP) { - bondingViewUtils.lockupBondForBondedRole(role, - txId -> { - bondedRole.setLockupTxId(txId); - bondedRole.setBondState(BondState.LOCKUP_TX_PENDING); - update(); - button.setDisable(true); - }); - } else if (bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { - bondingViewUtils.unLock(bondedRole.getLockupTxId(), - txId -> { - bondedRole.setUnlockTxId(txId); - bondedRole.setBondState(BondState.UNLOCK_TX_PENDING); - update(); - button.setDisable(true); - }); - } - });*/ + update(); } private void update() { - /* label.setText(Res.get("dao.bond.bondState." + bondedRole.getBondState().name())); - - boolean showLockup = bondedRole.getBondState() == BondState.READY_FOR_LOCKUP; - boolean showRevoke = bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED; - if (showLockup) - button.updateText(Res.get("dao.bond.table.button.lockup")); - else if (showRevoke) - button.updateText(Res.get("dao.bond.table.button.revoke")); - - - boolean showButton = isMyRole && (showLockup || showRevoke); - button.setVisible(showButton); - button.setManaged(showButton);*/ + stateLabel.setText(Res.get("dao.bond.bondState." + bond.getBondState().name())); } public void cleanup() { - // daoFacade.removeBsqStateListener(this); - // button.setOnAction(null); + daoFacade.removeBsqStateListener(this); } // DaoStateListener diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.fxml b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.fxml index b7d03d7bd5f..7da6f9ec12b 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.fxml +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.fxml @@ -27,9 +27,7 @@ AnchorPane.rightAnchor="25.0" AnchorPane.topAnchor="20.0" xmlns:fx="http://javafx.com/fxml"> - - - + diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java index 75238c84c12..4d44297a666 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java @@ -22,7 +22,6 @@ import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.main.dao.bonding.BondingViewUtils; -import bisq.desktop.main.dao.wallet.BsqBalanceUtil; import bisq.desktop.util.GUIUtil; import bisq.desktop.util.validation.BsqValidator; @@ -43,13 +42,12 @@ import de.jensd.fx.fontawesome.AwesomeIcon; -import javafx.scene.control.Button; +import javafx.scene.control.Label; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.Tooltip; import javafx.scene.layout.GridPane; -import javafx.scene.layout.VBox; import javafx.geometry.Insets; @@ -59,19 +57,22 @@ import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; +import javafx.collections.transformation.SortedList; import javafx.util.Callback; +import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; +import static bisq.desktop.util.FormBuilder.addTitledGroupBg; + @FxmlView public class BondsView extends ActivatableView implements BsqBalanceListener, DaoStateListener { private TableView tableView; private final BsqWalletService bsqWalletService; private final BsqFormatter bsqFormatter; - private final BsqBalanceUtil bsqBalanceUtil; private final BsqValidator bsqValidator; private final BondingViewUtils bondingViewUtils; private final BondedRolesService bondedRolesService; @@ -81,6 +82,7 @@ public class BondsView extends ActivatableView implements BsqBal private int gridRow = 0; private final ObservableList observableList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(observableList); private ListChangeListener walletBsqTransactionsListener; private ChangeListener walletChainHeightListener; @@ -93,7 +95,6 @@ public class BondsView extends ActivatableView implements BsqBal @Inject private BondsView(BsqWalletService bsqWalletService, BsqFormatter bsqFormatter, - BsqBalanceUtil bsqBalanceUtil, BsqValidator bsqValidator, BondingViewUtils bondingViewUtils, BondedRolesService bondedRolesService, @@ -101,7 +102,6 @@ private BondsView(BsqWalletService bsqWalletService, Preferences preferences) { this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; - this.bsqBalanceUtil = bsqBalanceUtil; this.bsqValidator = bsqValidator; this.bondingViewUtils = bondingViewUtils; this.bondedRolesService = bondedRolesService; @@ -111,27 +111,21 @@ private BondsView(BsqWalletService bsqWalletService, @Override public void initialize() { - gridRow = bsqBalanceUtil.addGroup(root, gridRow); + addTitledGroupBg(root, gridRow, 2, Res.get("dao.bonding.bonds.table.header")); tableView = new TableView<>(); + GridPane.setRowIndex(tableView, ++gridRow); + GridPane.setMargin(tableView, new Insets(30, -10, 5, -10)); + root.getChildren().add(tableView); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); addColumns(); walletBsqTransactionsListener = change -> updateList(); walletChainHeightListener = (observable, oldValue, newValue) -> updateList(); - - VBox vBox = new VBox(); - vBox.setSpacing(10); - GridPane.setRowIndex(vBox, ++gridRow); - GridPane.setColumnSpan(vBox, 3); - GridPane.setMargin(vBox, new Insets(40, -10, 5, -10)); - vBox.getChildren().addAll(tableView); - root.getChildren().add(vBox); } @Override protected void activate() { - bsqBalanceUtil.activate(); bsqWalletService.addBsqBalanceListener(this); onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getAvailableNonBsqBalance(), @@ -144,7 +138,8 @@ protected void activate() { bsqWalletService.addBsqBalanceListener(this); bsqWalletService.getChainHeightProperty().addListener(walletChainHeightListener); - tableView.setItems(observableList); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + tableView.setItems(sortedList); daoFacade.addBsqStateListener(this); @@ -153,7 +148,6 @@ protected void activate() { @Override protected void deactivate() { - bsqBalanceUtil.deactivate(); bsqWalletService.removeBsqBalanceListener(this); bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); @@ -161,7 +155,9 @@ protected void deactivate() { bsqWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); daoFacade.removeBsqStateListener(this); - // observableList.forEach(BondListItem::cleanup); + sortedList.comparatorProperty().unbind(); + + observableList.forEach(BondListItem::cleanup); } @@ -208,7 +204,7 @@ private void openTxInBlockExplorer(BondListItem item) { } private void updateList() { - List items = daoFacade.getAllActiveBonds().stream() + List items = daoFacade.getAllBonds().stream() .map(bond -> { return new BondListItem(bond, daoFacade, @@ -216,6 +212,7 @@ private void updateList() { bondingViewUtils, bsqFormatter); }) + .sorted(Comparator.comparing(BondListItem::getLockupDate).reversed()) .collect(Collectors.toList()); observableList.setAll(items); GUIUtil.setFitToRowsForTableView(tableView, 37, 28, 2, 10); @@ -229,23 +226,38 @@ private void updateList() { private void addColumns() { TableColumn column; - column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.hash")); - column.setMinWidth(160); - column.setMaxWidth(column.getMinWidth()); - + column = new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", "BSQ")); + column.setMinWidth(80); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { - @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { + @Override + public void updateItem(final BondListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + setText(item.getAmount()); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockTime")); + column.setMinWidth(40); + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory(new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { @Override public void updateItem(final BondListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - setText(item.getInfo()); + setText(item.getLockTime()); } else setText(""); } @@ -254,23 +266,71 @@ public void updateItem(final BondListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", "BSQ")); - column.setMinWidth(120); - column.setMaxWidth(column.getMinWidth()); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondState")); + column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setMinWidth(80); + column.setCellFactory( + new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + Label label; + @Override + public void updateItem(final BondListItem item, boolean empty) { + super.updateItem(item, empty); + + if (item != null && !empty) { + if (label == null) { + label = item.getStateLabel(); + setGraphic(label); + } + } else { + setGraphic(null); + if (label != null) + label = null; + } + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondType")); + column.setMinWidth(100); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { + @Override + public TableCell call(TableColumn column) { + return new TableCell<>() { + @Override + public void updateItem(final BondListItem item, boolean empty) { + super.updateItem(item, empty); + if (item != null && !empty) { + setText(item.getBondType()); + } else + setText(""); + } + }; + } + }); + tableView.getColumns().add(column); + + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.details")); + column.setMinWidth(100); + column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); + column.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { @Override public void updateItem(final BondListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - setText(item.getAmount()); + setText(item.getBondDetails()); } else setText(""); } @@ -279,23 +339,20 @@ public void updateItem(final BondListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.time")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockupDate")); column.setMinWidth(140); - column.setMaxWidth(column.getMinWidth()); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { - @Override public void updateItem(final BondListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - setText(item.getLockTime()); + setText(item.getLockupDate()); } else setText(""); } @@ -337,36 +394,5 @@ public void updateItem(final BondListItem item, boolean empty) { } }); tableView.getColumns().add(column); - - column = new TableColumn<>(); - column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(80); - column.setCellFactory( - new Callback<>() { - @Override - public TableCell call(TableColumn column) { - return new TableCell<>() { - Button button; - - @Override - public void updateItem(final BondListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - if (button == null) { - button = item.getButton(); - setGraphic(button); - } - } else { - setGraphic(null); - if (button != null) - button = null; - } - } - }; - } - }); - tableView.getColumns().add(column); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java index 0a57620c46d..1bc4318b6ea 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java @@ -70,6 +70,7 @@ import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; +import javafx.collections.transformation.SortedList; import javafx.util.Callback; @@ -100,6 +101,7 @@ public class MyBondedReputationView extends ActivatableView impl private ChangeListener amountFocusOutListener, timeFocusOutListener, saltFocusOutListener; private ChangeListener amountInputTextFieldListener, timeInputTextFieldListener, saltInputTextFieldListener; private final ObservableList observableList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(observableList); private ListChangeListener walletBsqTransactionsListener; private ChangeListener walletChainHeightListener; @@ -190,7 +192,8 @@ protected void activate() { timeInputTextField.resetValidation(); setNewRandomSalt(); - tableView.setItems(observableList); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + tableView.setItems(sortedList); onUpdateBalances(); updateList(); @@ -215,6 +218,8 @@ protected void deactivate() { lockupButton.setOnAction(null); + sortedList.comparatorProperty().unbind(); + daoFacade.removeBsqStateListener(this); } @@ -291,6 +296,7 @@ private void createTableView(int columnSpan) { tableView = new TableView<>(); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); createColumns(); VBox vBox = new VBox(); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java index 1580697bc4c..b03fbaae301 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.java @@ -22,9 +22,7 @@ import bisq.desktop.components.AutoTooltipLabel; import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; -import bisq.desktop.components.TableGroupHeadline; import bisq.desktop.main.dao.bonding.BondingViewUtils; -import bisq.desktop.main.dao.wallet.BsqBalanceUtil; import bisq.desktop.util.GUIUtil; import bisq.core.dao.DaoFacade; @@ -60,6 +58,8 @@ import java.util.stream.Collectors; +import static bisq.desktop.util.FormBuilder.addTitledGroupBg; + @FxmlView public class BondedRolesView extends ActivatableView implements DaoStateListener { private TableView tableView; @@ -79,7 +79,6 @@ public class BondedRolesView extends ActivatableView implements @Inject private BondedRolesView(BsqFormatter bsqFormatter, - BsqBalanceUtil bsqBalanceUtil, BondingViewUtils bondingViewUtils, DaoFacade daoFacade, Preferences preferences) { @@ -91,31 +90,23 @@ private BondedRolesView(BsqFormatter bsqFormatter, @Override public void initialize() { - TableGroupHeadline headline = new TableGroupHeadline(Res.get("dao.bond.table.header")); int gridRow = 0; - GridPane.setRowIndex(headline, gridRow); - GridPane.setMargin(headline, new Insets(0, -10, -10, -10)); - GridPane.setColumnSpan(headline, 2); - root.getChildren().add(headline); + addTitledGroupBg(root, gridRow, 2, Res.get("dao.bond.bondedRoles")); tableView = new TableView<>(); + GridPane.setRowIndex(tableView, ++gridRow); + GridPane.setMargin(tableView, new Insets(30, -10, 5, -10)); + root.getChildren().add(tableView); tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - createColumns(); - - GridPane.setRowIndex(tableView, gridRow); - GridPane.setMargin(tableView, new Insets(20, -10, 5, -10)); - GridPane.setColumnSpan(tableView, 2); - root.getChildren().add(tableView); - - sortedList.comparatorProperty().bind(tableView.comparatorProperty()); tableView.setItems(sortedList); } @Override protected void activate() { daoFacade.addBsqStateListener(this); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); updateList(); } @@ -123,6 +114,7 @@ protected void activate() { @Override protected void deactivate() { daoFacade.removeBsqStateListener(this); + sortedList.comparatorProperty().unbind(); observableList.forEach(BondedRolesListItem::cleanup); } @@ -226,7 +218,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondedRoleType")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondType")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(80); column.setCellFactory( diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java index 0934431aea4..b5b3c971611 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java @@ -305,7 +305,7 @@ public BondedRoleType fromString(String string) { comboBoxValueTextFieldIndex = gridRow; checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); - confiscateBondComboBox.setItems(FXCollections.observableArrayList(daoFacade.getAllActiveBonds())); + confiscateBondComboBox.setItems(FXCollections.observableArrayList(daoFacade.getAllBonds())); confiscateBondComboBox.setConverter(new StringConverter<>() { @Override public String toString(Bond bond) { From c5630eec0f3f4dd3e3c45043faa23b4eb849dcd6 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 6 Nov 2018 00:42:17 -0500 Subject: [PATCH 21/27] Add support for confiscation of bonds --- common/src/main/proto/pb.proto | 4 +- .../core/btc/wallet/BsqWalletService.java | 2 +- .../main/java/bisq/core/dao/DaoFacade.java | 8 +- .../core/dao/governance/bond/BondService.java | 25 +++- .../core/dao/governance/bond/BondState.java | 1 + .../dao/governance/bond/ConfiscateBond.java | 22 +-- .../reputation/MyBondedReputationService.java | 21 ++- .../ConfiscateBondProposalFactory.java | 8 +- .../voteresult/VoteResultService.java | 4 +- .../java/bisq/core/dao/node/full/RawTx.java | 12 +- .../bisq/core/dao/node/full/RawTxOutput.java | 14 +- .../core/dao/node/parser/TxInputParser.java | 138 +++++++++--------- .../core/dao/node/parser/TxOutputParser.java | 41 +++--- .../bisq/core/dao/state/DaoStateService.java | 90 +++++++++--- .../core/dao/state/model/blockchain/Tx.java | 2 +- .../governance/ConfiscateBondProposal.java | 22 ++- .../resources/i18n/displayStrings.properties | 2 + .../bonding/roles/BondedRolesListItem.java | 8 +- .../main/dao/governance/ProposalDisplay.java | 26 +++- .../dao/governance/make/MakeProposalView.java | 10 +- 20 files changed, 278 insertions(+), 182 deletions(-) diff --git a/common/src/main/proto/pb.proto b/common/src/main/proto/pb.proto index 435a98eccd2..798dfc51ee9 100644 --- a/common/src/main/proto/pb.proto +++ b/common/src/main/proto/pb.proto @@ -1521,7 +1521,7 @@ message RoleProposal { } message ConfiscateBondProposal { - bytes hash = 1; + string lockup_tx_id = 1; } message GenericProposal { @@ -1594,7 +1594,7 @@ message ParamChange { } message ConfiscateBond { - bytes hash = 1; + string lockup_tx_id = 1; } message MyVote { diff --git a/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java b/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java index 6297b5da6a0..1df2b3a6183 100644 --- a/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java +++ b/core/src/main/java/bisq/core/btc/wallet/BsqWalletService.java @@ -238,7 +238,7 @@ private void updateBsqBalance() { return (connectedOutput.isMine(wallet) && (daoStateService.isLockupOutput(key) - || daoStateService.isUnlockingOutput(key))); + || daoStateService.isUnlockingAndUnspent(key))); } } return false; diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index 08d0b7b70d9..0bc623c46a5 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -266,11 +266,11 @@ public ProposalWithTransaction getParamProposalWithTransaction(String name, public ProposalWithTransaction getConfiscateBondProposalWithTransaction(String name, String link, - byte[] hash) + String lockupTxId) throws ValidationException, InsufficientMoneyException, TxException { return confiscateBondProposalFactory.createProposalWithTransaction(name, link, - hash); + lockupTxId); } public ProposalWithTransaction getBondedRoleProposalWithTransaction(Role role) @@ -663,4 +663,8 @@ public void resyncDao(Runnable resultHandler) { public boolean isMyRole(Role role) { return bondedRolesService.isMyRole(role); } + + public Optional getBondByLockupTxId(String lockupTxId) { + return getAllBonds().stream().filter(e -> e.getLockupTxId().equals(lockupTxId)).findAny(); + } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondService.java b/core/src/main/java/bisq/core/dao/governance/bond/BondService.java index 9a5afed82b8..9cfdd6a9417 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondService.java @@ -151,7 +151,7 @@ public static void applyBondState(DaoStateService daoStateService, Bond bond, Tx bond.setUnlockTxId(unlockTxId); bond.setBondState(BondState.UNLOCK_TX_CONFIRMED); bond.setUnlockDate(unlockTx.getTime()); - boolean unlocking = daoStateService.isUnlocking(unlockTxId); + boolean unlocking = daoStateService.isUnlockingAndUnspent(unlockTxId); if (unlocking) { bond.setBondState(BondState.UNLOCKING); } else { @@ -159,6 +159,11 @@ public static void applyBondState(DaoStateService daoStateService, Bond bond, Tx } }); } + + if ((bond.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(bond.getLockupTxId())) || + (bond.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(bond.getUnlockTxId()))) { + bond.setBondState(BondState.CONFISCATED); + } } protected abstract T createBond(R bondedAsset); @@ -220,14 +225,28 @@ private void updateBondStateFromUnconfirmedLockupTxs() { getBondedAssetStream().filter(bondedAsset -> isLockupTxUnconfirmed(bsqWalletService, bondedAsset)) .map(bondedAsset -> bondByUidMap.get(bondedAsset.getUid())) .filter(bond -> bond.getBondState() == BondState.READY_FOR_LOCKUP) - .forEach(bond -> bond.setBondState(BondState.LOCKUP_TX_PENDING)); + .forEach(bond -> { + if ((bond.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(bond.getLockupTxId())) || + (bond.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(bond.getUnlockTxId()))) { + bond.setBondState(BondState.CONFISCATED); + } else { + bond.setBondState(BondState.LOCKUP_TX_PENDING); + } + }); } private void updateBondStateFromUnconfirmedUnlockTxs() { getBondedAssetStream().filter(bondedAsset -> isUnlockTxUnconfirmed(bsqWalletService, daoStateService, bondedAsset)) .map(bondedAsset -> bondByUidMap.get(bondedAsset.getUid())) .filter(bond -> bond.getBondState() == BondState.LOCKUP_TX_CONFIRMED) - .forEach(bond -> bond.setBondState(BondState.UNLOCK_TX_PENDING)); + .forEach(bond -> { + if ((bond.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(bond.getLockupTxId())) || + (bond.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(bond.getUnlockTxId()))) { + bond.setBondState(BondState.CONFISCATED); + } else { + bond.setBondState(BondState.UNLOCK_TX_PENDING); + } + }); } public static boolean isLockupTxUnconfirmed(BsqWalletService bsqWalletService, BondedAsset bondedAsset) { diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondState.java b/core/src/main/java/bisq/core/dao/governance/bond/BondState.java index aaf06b181a7..32843661371 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondState.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondState.java @@ -26,4 +26,5 @@ public enum BondState { UNLOCK_TX_CONFIRMED, UNLOCKING, // lock time not expired UNLOCKED, + CONFISCATED } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java b/core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java index 867140a2321..382e0e7a7c3 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java @@ -21,8 +21,6 @@ import io.bisq.generated.protobuffer.PB; -import com.google.protobuf.ByteString; - import lombok.Value; import javax.annotation.concurrent.Immutable; @@ -33,12 +31,10 @@ @Immutable @Value public class ConfiscateBond implements PersistablePayload { - // Hash can be anything which identifies a bond. - // TODO concept not finalized yet... - private final byte[] hash; + private final String lockupTxId; - public ConfiscateBond(byte[] hash) { - this.hash = hash; + public ConfiscateBond(String lockupTxId) { + this.lockupTxId = lockupTxId; } /////////////////////////////////////////////////////////////////////////////////////////// @@ -49,11 +45,19 @@ public ConfiscateBond(byte[] hash) { @Override public PB.ConfiscateBond toProtoMessage() { return PB.ConfiscateBond.newBuilder() - .setHash(ByteString.copyFrom(hash)) + .setLockupTxId(lockupTxId) .build(); } public static ConfiscateBond fromProto(PB.ConfiscateBond proto) { - return new ConfiscateBond(proto.getHash().toByteArray()); + return new ConfiscateBond(proto.getLockupTxId()); + } + + + @Override + public String toString() { + return "ConfiscateBond{" + + "\n lockupTxId='" + lockupTxId + '\'' + + "\n}"; } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java index d404eaf2c47..2cec71a8614 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java @@ -84,14 +84,19 @@ public List getMyBondedReputations() { return map.values().stream() .peek(myBondedReputation -> { - // We don't have a UI use case for showing LOCKUP_TX_PENDING yet, but lets keep the code so if needed - // its there. - if (BondService.isLockupTxUnconfirmed(bsqWalletService, myBondedReputation.getBondedAsset()) && - myBondedReputation.getBondState() == BondState.READY_FOR_LOCKUP) { - myBondedReputation.setBondState(BondState.LOCKUP_TX_PENDING); - } else if (BondService.isUnlockTxUnconfirmed(bsqWalletService, daoStateService, myBondedReputation.getBondedAsset()) && - myBondedReputation.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { - myBondedReputation.setBondState(BondState.UNLOCK_TX_PENDING); + if ((myBondedReputation.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(myBondedReputation.getLockupTxId())) || + (myBondedReputation.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(myBondedReputation.getUnlockTxId()))) { + myBondedReputation.setBondState(BondState.CONFISCATED); + } else { + // We don't have a UI use case for showing LOCKUP_TX_PENDING yet, but lets keep the code so if needed + // its there. + if (BondService.isLockupTxUnconfirmed(bsqWalletService, myBondedReputation.getBondedAsset()) && + myBondedReputation.getBondState() == BondState.READY_FOR_LOCKUP) { + myBondedReputation.setBondState(BondState.LOCKUP_TX_PENDING); + } else if (BondService.isUnlockTxUnconfirmed(bsqWalletService, daoStateService, myBondedReputation.getBondedAsset()) && + myBondedReputation.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { + myBondedReputation.setBondState(BondState.UNLOCK_TX_PENDING); + } } }) .collect(Collectors.toList()); diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalFactory.java b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalFactory.java index 59ebcf5337e..72fc31fab78 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalFactory.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/confiscatebond/ConfiscateBondProposalFactory.java @@ -37,7 +37,7 @@ */ @Slf4j public class ConfiscateBondProposalFactory extends BaseProposalFactory { - private byte[] hash; + private String lockupTxId; /////////////////////////////////////////////////////////////////////////////////////////// @@ -57,9 +57,9 @@ public ConfiscateBondProposalFactory(BsqWalletService bsqWalletService, public ProposalWithTransaction createProposalWithTransaction(String name, String link, - byte[] hash) + String lockupTxId) throws ValidationException, InsufficientMoneyException, TxException { - this.hash = hash; + this.lockupTxId = lockupTxId; return super.createProposalWithTransaction(name, link); } @@ -69,6 +69,6 @@ protected ConfiscateBondProposal createProposalWithoutTxId() { return new ConfiscateBondProposal( name, link, - hash); + lockupTxId); } } diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java index b90474fcc58..4e8b37a25e7 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java @@ -661,12 +661,12 @@ private void applyConfiscateBond(Set acceptedEvaluatedProposa acceptedEvaluatedProposals.forEach(evaluatedProposal -> { if (evaluatedProposal.getProposal() instanceof ConfiscateBondProposal) { ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) evaluatedProposal.getProposal(); - daoStateService.confiscateBond(new ConfiscateBond(confiscateBondProposal.getHash())); + daoStateService.confiscateBond(new ConfiscateBond(confiscateBondProposal.getLockupTxId())); StringBuilder sb = new StringBuilder(); sb.append("\n################################################################################\n"); sb.append("We confiscated a bond. ProposalTxId=").append(confiscateBondProposal.getTxId()) - .append("\nHashOfBondId: ").append(Utilities.encodeToHex(confiscateBondProposal.getHash())) + .append("\nLockupTxId: ").append(confiscateBondProposal.getLockupTxId()) .append("\n################################################################################\n"); log.info(sb.toString()); } diff --git a/core/src/main/java/bisq/core/dao/node/full/RawTx.java b/core/src/main/java/bisq/core/dao/node/full/RawTx.java index 187fd21ca71..464e6432cf9 100644 --- a/core/src/main/java/bisq/core/dao/node/full/RawTx.java +++ b/core/src/main/java/bisq/core/dao/node/full/RawTx.java @@ -65,12 +65,12 @@ public static RawTx fromTx(Tx tx) { private final ImmutableList rawTxOutputs; // The RPC service is creating a RawTx. - RawTx(String id, - int blockHeight, - String blockHash, - long time, - ImmutableList txInputs, - ImmutableList rawTxOutputs) { + public RawTx(String id, + int blockHeight, + String blockHash, + long time, + ImmutableList txInputs, + ImmutableList rawTxOutputs) { super(Version.BSQ_TX_VERSION, id, blockHeight, diff --git a/core/src/main/java/bisq/core/dao/node/full/RawTxOutput.java b/core/src/main/java/bisq/core/dao/node/full/RawTxOutput.java index 02b23f658b9..9b20cc577ce 100644 --- a/core/src/main/java/bisq/core/dao/node/full/RawTxOutput.java +++ b/core/src/main/java/bisq/core/dao/node/full/RawTxOutput.java @@ -51,13 +51,13 @@ public static RawTxOutput fromTxOutput(TxOutput txOutput) { txOutput.getBlockHeight()); } - RawTxOutput(int index, - long value, - String txId, - @Nullable PubKeyScript pubKeyScript, - @Nullable String address, - @Nullable byte[] opReturnData, - int blockHeight) { + public RawTxOutput(int index, + long value, + String txId, + @Nullable PubKeyScript pubKeyScript, + @Nullable String address, + @Nullable byte[] opReturnData, + int blockHeight) { super(index, value, txId, diff --git a/core/src/main/java/bisq/core/dao/node/parser/TxInputParser.java b/core/src/main/java/bisq/core/dao/node/parser/TxInputParser.java index 9fe65596209..c842f9efc39 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/TxInputParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/TxInputParser.java @@ -68,73 +68,77 @@ public TxInputParser(DaoStateService daoStateService) { /////////////////////////////////////////////////////////////////////////////////////////// void process(TxOutputKey txOutputKey, int blockHeight, String txId, int inputIndex) { - daoStateService.getUnspentTxOutput(txOutputKey) - .ifPresent(connectedTxOutput -> { - long inputValue = connectedTxOutput.getValue(); - accumulatedInputValue += inputValue; - - // If we are spending an output from a blind vote tx marked as VOTE_STAKE_OUTPUT we save it in our parsingModel - // for later verification at the outputs of a reveal tx. - TxOutputType connectedTxOutputType = connectedTxOutput.getTxOutputType(); - switch (connectedTxOutputType) { - case UNDEFINED_OUTPUT: - case GENESIS_OUTPUT: - case BSQ_OUTPUT: - case BTC_OUTPUT: - case PROPOSAL_OP_RETURN_OUTPUT: - case COMP_REQ_OP_RETURN_OUTPUT: - case REIMBURSEMENT_OP_RETURN_OUTPUT: - case CONFISCATE_BOND_OP_RETURN_OUTPUT: - case ISSUANCE_CANDIDATE_OUTPUT: - break; - case BLIND_VOTE_LOCK_STAKE_OUTPUT: - numVoteRevealInputs++; - // The connected tx output of the blind vote tx is our input for the reveal tx. - // We allow only one input from any blind vote tx otherwise the vote reveal tx is invalid. - if (!isVoteRevealInputValid()) { - log.warn("We have a tx which has >1 connected txOutputs marked as BLIND_VOTE_LOCK_STAKE_OUTPUT. " + - "This is not a valid BSQ tx."); - } - break; - case BLIND_VOTE_OP_RETURN_OUTPUT: - case VOTE_REVEAL_UNLOCK_STAKE_OUTPUT: - case VOTE_REVEAL_OP_RETURN_OUTPUT: - break; - case LOCKUP_OUTPUT: - // A LOCKUP BSQ txOutput is spent to a corresponding UNLOCK - // txInput. The UNLOCK can only be spent after lockTime blocks has passed. - isUnLockInputValid = !optionalSpentLockupTxOutput.isPresent(); - if (isUnLockInputValid) { - optionalSpentLockupTxOutput = Optional.of(connectedTxOutput); - unlockBlockHeight = blockHeight + connectedTxOutput.getLockTime(); - } else { - log.warn("We have a tx which has >1 connected txOutputs marked as LOCKUP_OUTPUT. " + - "This is not a valid BSQ tx."); - } - break; - case LOCKUP_OP_RETURN_OUTPUT: - // Cannot happen - break; - case UNLOCK_OUTPUT: - // This txInput is Spending an UNLOCK txOutput - int unlockBlockHeight = connectedTxOutput.getUnlockBlockHeight(); - if (blockHeight < unlockBlockHeight) { - accumulatedInputValue -= inputValue; - burntBondValue += inputValue; - - log.warn("We got a tx which spends the output from an unlock tx but before the " + - "unlockTime has passed. That leads to burned BSQ! " + - "blockHeight={}, unLockHeight={}", blockHeight, unlockBlockHeight); - } - break; - case INVALID_OUTPUT: - default: - break; - } - - daoStateService.setSpentInfo(connectedTxOutput.getKey(), new SpentInfo(blockHeight, txId, inputIndex)); - daoStateService.removeUnspentTxOutput(connectedTxOutput); - }); + if (!daoStateService.isConfiscated(txOutputKey)) { + daoStateService.getUnspentTxOutput(txOutputKey) + .ifPresent(connectedTxOutput -> { + long inputValue = connectedTxOutput.getValue(); + accumulatedInputValue += inputValue; + + // If we are spending an output from a blind vote tx marked as VOTE_STAKE_OUTPUT we save it in our parsingModel + // for later verification at the outputs of a reveal tx. + TxOutputType connectedTxOutputType = connectedTxOutput.getTxOutputType(); + switch (connectedTxOutputType) { + case UNDEFINED_OUTPUT: + case GENESIS_OUTPUT: + case BSQ_OUTPUT: + case BTC_OUTPUT: + case PROPOSAL_OP_RETURN_OUTPUT: + case COMP_REQ_OP_RETURN_OUTPUT: + case REIMBURSEMENT_OP_RETURN_OUTPUT: + case CONFISCATE_BOND_OP_RETURN_OUTPUT: + case ISSUANCE_CANDIDATE_OUTPUT: + break; + case BLIND_VOTE_LOCK_STAKE_OUTPUT: + numVoteRevealInputs++; + // The connected tx output of the blind vote tx is our input for the reveal tx. + // We allow only one input from any blind vote tx otherwise the vote reveal tx is invalid. + if (!isVoteRevealInputValid()) { + log.warn("We have a tx which has >1 connected txOutputs marked as BLIND_VOTE_LOCK_STAKE_OUTPUT. " + + "This is not a valid BSQ tx."); + } + break; + case BLIND_VOTE_OP_RETURN_OUTPUT: + case VOTE_REVEAL_UNLOCK_STAKE_OUTPUT: + case VOTE_REVEAL_OP_RETURN_OUTPUT: + break; + case LOCKUP_OUTPUT: + // A LOCKUP BSQ txOutput is spent to a corresponding UNLOCK + // txInput. The UNLOCK can only be spent after lockTime blocks has passed. + isUnLockInputValid = !optionalSpentLockupTxOutput.isPresent(); + if (isUnLockInputValid) { + optionalSpentLockupTxOutput = Optional.of(connectedTxOutput); + unlockBlockHeight = blockHeight + connectedTxOutput.getLockTime(); + } else { + log.warn("We have a tx which has >1 connected txOutputs marked as LOCKUP_OUTPUT. " + + "This is not a valid BSQ tx."); + } + break; + case LOCKUP_OP_RETURN_OUTPUT: + // Cannot happen + break; + case UNLOCK_OUTPUT: + // This txInput is Spending an UNLOCK txOutput + int unlockBlockHeight = connectedTxOutput.getUnlockBlockHeight(); + if (blockHeight < unlockBlockHeight) { + accumulatedInputValue -= inputValue; + burntBondValue += inputValue; + + log.warn("We got a tx which spends the output from an unlock tx but before the " + + "unlockTime has passed. That leads to burned BSQ! " + + "blockHeight={}, unLockHeight={}", blockHeight, unlockBlockHeight); + } + break; + case INVALID_OUTPUT: + default: + break; + } + + daoStateService.setSpentInfo(connectedTxOutput.getKey(), new SpentInfo(blockHeight, txId, inputIndex)); + daoStateService.removeUnspentTxOutput(connectedTxOutput); + }); + } else { + log.warn("Connected txOutput {} at input {} of txId {} is confiscated ", txOutputKey, inputIndex, txId); + } } boolean isVoteRevealInputValid() { diff --git a/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java b/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java index a19893faa2d..ed93be47ff2 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java @@ -100,24 +100,31 @@ void processOpReturnOutput(TempTxOutput tempTxOutput) { } void processTxOutput(TempTxOutput tempTxOutput) { - // We don not expect here an opReturn output as we do not get called on the last output. Any opReturn at - // another output index is invalid. - if (tempTxOutput.isOpReturnOutput()) { - tempTxOutput.setTxOutputType(TxOutputType.INVALID_OUTPUT); - return; - } - - long txOutputValue = tempTxOutput.getValue(); - int index = tempTxOutput.getIndex(); - if (isUnlockBondTx(tempTxOutput.getValue(), index)) { - // We need to handle UNLOCK transactions separately as they don't follow the pattern on spending BSQ - // The LOCKUP BSQ is burnt unless the output exactly matches the input, that would cause the - // output to not be BSQ output at all - handleUnlockBondTx(tempTxOutput); - } else if (availableInputValue > 0 && availableInputValue >= txOutputValue) { - handleBsqOutput(tempTxOutput, index, txOutputValue); + if (!daoStateService.isConfiscated(tempTxOutput.getKey())) { + // We don not expect here an opReturn output as we do not get called on the last output. Any opReturn at + // another output index is invalid. + if (tempTxOutput.isOpReturnOutput()) { + tempTxOutput.setTxOutputType(TxOutputType.INVALID_OUTPUT); + return; + } + + long txOutputValue = tempTxOutput.getValue(); + int index = tempTxOutput.getIndex(); + if (isUnlockBondTx(tempTxOutput.getValue(), index)) { + // We need to handle UNLOCK transactions separately as they don't follow the pattern on spending BSQ + // The LOCKUP BSQ is burnt unless the output exactly matches the input, that would cause the + // output to not be BSQ output at all + handleUnlockBondTx(tempTxOutput); + } else if (availableInputValue > 0 && availableInputValue >= txOutputValue) { + handleBsqOutput(tempTxOutput, index, txOutputValue); + } else { + handleBtcOutput(tempTxOutput, index); + } } else { - handleBtcOutput(tempTxOutput, index); + log.warn("TxOutput {} is confiscated ", tempTxOutput.getKey()); + // We only burn that output + availableInputValue -= tempTxOutput.getValue(); + tempTxOutput.setTxOutputType(TxOutputType.BTC_OUTPUT); } } diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateService.java b/core/src/main/java/bisq/core/dao/state/DaoStateService.java index 6caf65b7c8d..e2fbfb54f39 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateService.java @@ -43,7 +43,6 @@ import javax.inject.Inject; import java.util.ArrayList; -import java.util.Arrays; import java.util.Comparator; import java.util.HashSet; import java.util.LinkedList; @@ -688,18 +687,19 @@ public long getTotalAmountOfUnLockingTxOutputs() { .sum(); } - public boolean isUnlockingOutput(TxOutputKey key) { + public boolean isUnlockingAndUnspent(TxOutputKey key) { Optional opTxOutput = getUnspentTxOutput(key); - return opTxOutput.isPresent() && isUnlockingOutput(opTxOutput.get()); + return opTxOutput.isPresent() && isUnlockingAndUnspent(opTxOutput.get()); } - public boolean isUnlocking(String unlockTxId) { + public boolean isUnlockingAndUnspent(String unlockTxId) { Optional optionalTx = getTx(unlockTxId); - return optionalTx.isPresent() && isUnlockingOutput(optionalTx.get().getTxOutputs().get(0)); + return optionalTx.isPresent() && isUnlockingAndUnspent(optionalTx.get().getTxOutputs().get(0)); } - public boolean isUnlockingOutput(TxOutput unlockTxOutput) { + public boolean isUnlockingAndUnspent(TxOutput unlockTxOutput) { return unlockTxOutput.getTxOutputType() == TxOutputType.UNLOCK_OUTPUT && + isUnspent(unlockTxOutput.getKey()) && !isLockTimeOverForUnlockTxOutput(unlockTxOutput); } @@ -743,29 +743,75 @@ public long getTotalAmountOfUnLockedTxOutputs() { // Confiscate bond public void confiscateBond(ConfiscateBond confiscateBond) { - if (confiscateBond.getHash().length == 0) { - // Disallow confiscation of empty bonds - return; + String lockupTxId = confiscateBond.getLockupTxId(); + Optional optionalTxOutput = getLockupTxOutput(lockupTxId); + if (optionalTxOutput.isPresent()) { + TxOutput lockupTxOutput = optionalTxOutput.get(); + if (isUnspent(lockupTxOutput.getKey())) { + log.warn("lockupTxOutput {} is still unspent. We confiscate it.", lockupTxOutput.getKey()); + confiscateBond(lockupTxOutput); + } else { + // We lookup for the unlock tx which need to be still in unlocking state + Optional optionalSpentInfo = getSpentInfo(lockupTxOutput); + checkArgument(optionalSpentInfo.isPresent(), "optionalSpentInfo must be present"); + String unlockTxId = optionalSpentInfo.get().getTxId(); + if (isUnlockingAndUnspent(unlockTxId)) { + // We found the unlock tx is still not spend + log.warn("lockupTxOutput {} is still unspent. We confiscate it.", lockupTxOutput.getKey()); + getUnspentUnlockingTxOutputsStream() + .filter(txOutput -> txOutput.getTxId().equals(unlockTxId)) + .forEach(this::confiscateBond); + } else { + // We could be more radical here and confiscate the output if it is unspent but lock time is over, + // but its probably better to stick to the rules that confiscation can only happen before lock time + // is over. + log.warn("We could not confiscate the bond because the unlock tx was already spent or lock time " + + "has exceeded. unlockTxId={}", unlockTxId); + } + } + } else { + log.warn("No lockupTxOutput found for lockupTxId {}", lockupTxId); } - getTxOutputStream() - .filter(txOutput -> isUnspent(txOutput.getKey())) - .filter(txOutput -> txOutput.getTxOutputType() == TxOutputType.LOCKUP_OUTPUT || - (isUnlockTxOutputAndLockTimeNotOver(txOutput))) - .filter(txOutput -> { - Optional hash = getLockupHash(txOutput); - return hash.isPresent() && Arrays.equals(hash.get(), confiscateBond.getHash()); - }) - .forEach(this::applyConfiscateBond); } - public void applyConfiscateBond(TxOutput txOutput) { + private void confiscateBond(TxOutput txOutput) { + // Can be txOutput from lockup or unlock tx + log.warn("txOutput {} added to confiscatedTxOutputMap.", txOutput.getKey()); daoState.getConfiscatedTxOutputMap().put(txOutput.getKey(), txOutput); + } + + public boolean isConfiscated(TxOutputKey txOutputKey) { + return daoState.getConfiscatedTxOutputMap().containsKey(txOutputKey); + } - // TODO SQ TxOutputType is immutable after parsing - // We need to add new checks if a txo is not confiscated by using the map similar like utxo map - // txOutput.setTxOutputType(TxOutputType.BTC_OUTPUT); + public boolean isConfiscatedLockupTxOutput(String lockupTxId) { + return getLockupTxOutput(lockupTxId) + .map(lockupTxIdxOutput -> isConfiscated(lockupTxIdxOutput.getKey())) + .orElse(false); } + public boolean isConfiscatedUnlockTxOutput(String unlockTxId) { + return getUnlockTxOutputs().stream() + .filter(unlockTxOutput -> unlockTxOutput.getTxId().equals(unlockTxId)) + .map(unlockTxOutput -> isConfiscated(unlockTxOutput.getKey())) + .findAny() + .orElse(false); + } + + //TODO do we want to check for both txs? + /* public boolean isConfiscatedUnlockTxOutput(String lockupTxId) { + boolean present = getLockupTxOutput(lockupTxId) + .flatMap(lockupTxIdxOutput -> getSpentInfo(lockupTxIdxOutput) + .map(SpentInfo::getTxId) + .flatMap(this::getTx) + .map(unlockTx -> unlockTx.getTxOutputs().get(0))) + .filter(firstTxOutput -> isConfiscated(firstTxOutput.getKey())) + .isPresent(); + log.error("lockupTxId {}, {}", lockupTxId, present); + //log.error("daoState.getConfiscatedTxOutputMap() {}", daoState.getConfiscatedTxOutputMap()); + return present; + }*/ + /////////////////////////////////////////////////////////////////////////////////////////// // Param diff --git a/core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java b/core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java index 0a5a449c592..af8e8b9f546 100644 --- a/core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java +++ b/core/src/main/java/bisq/core/dao/state/model/blockchain/Tx.java @@ -145,7 +145,7 @@ public long getLockedAmount() { } // The lockTime is stored in the first output of the LOCKUP tx. - private TxOutput getLockupOutput() { + public TxOutput getLockupOutput() { return txOutputs.get(0); } diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/ConfiscateBondProposal.java b/core/src/main/java/bisq/core/dao/state/model/governance/ConfiscateBondProposal.java index d5379a9e618..8c6b64d09b9 100644 --- a/core/src/main/java/bisq/core/dao/state/model/governance/ConfiscateBondProposal.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/ConfiscateBondProposal.java @@ -23,12 +23,9 @@ import bisq.core.dao.state.model.blockchain.TxType; import bisq.common.app.Version; -import bisq.common.util.Utilities; import io.bisq.generated.protobuffer.PB; -import com.google.protobuf.ByteString; - import java.util.Date; import lombok.EqualsAndHashCode; @@ -42,14 +39,14 @@ @EqualsAndHashCode(callSuper = true) @Value public final class ConfiscateBondProposal extends Proposal implements ImmutableDaoStateModel { - private final byte[] hash; + private final String lockupTxId; public ConfiscateBondProposal(String name, String link, - byte[] hash) { + String lockupTxId) { this(name, link, - hash, + lockupTxId, Version.PROPOSAL, new Date().getTime(), ""); @@ -62,7 +59,7 @@ public ConfiscateBondProposal(String name, private ConfiscateBondProposal(String name, String link, - byte[] hash, + String lockupTxId, byte version, long creationDate, String txId) { @@ -71,14 +68,13 @@ private ConfiscateBondProposal(String name, version, creationDate, txId); - - this.hash = hash; + this.lockupTxId = lockupTxId; } @Override public PB.Proposal.Builder getProposalBuilder() { final PB.ConfiscateBondProposal.Builder builder = PB.ConfiscateBondProposal.newBuilder() - .setHash(ByteString.copyFrom(hash)); + .setLockupTxId(lockupTxId); return super.getProposalBuilder().setConfiscateBondProposal(builder); } @@ -86,7 +82,7 @@ public static ConfiscateBondProposal fromProto(PB.Proposal proto) { final PB.ConfiscateBondProposal proposalProto = proto.getConfiscateBondProposal(); return new ConfiscateBondProposal(proto.getName(), proto.getLink(), - proposalProto.getHash().toByteArray(), + proposalProto.getLockupTxId(), (byte) proto.getVersion(), proto.getCreationDate(), proto.getTxId()); @@ -121,7 +117,7 @@ public TxType getTxType() { public Proposal cloneProposalAndAddTxId(String txId) { return new ConfiscateBondProposal(getName(), getLink(), - getHash(), + getLockupTxId(), getVersion(), getCreationDate().getTime(), txId); @@ -130,7 +126,7 @@ public Proposal cloneProposalAndAddTxId(String txId) { @Override public String toString() { return "ConfiscateBondProposal{" + - "\n hash=" + Utilities.bytesAsHexString(hash) + + "\n lockupTxId=" + lockupTxId + "\n} " + super.toString(); } } diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 10c86269788..e620a16bdd4 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -1423,6 +1423,8 @@ dao.bond.bondState.UNLOCK_TX_CONFIRMED=Unlock tx confirmed dao.bond.bondState.UNLOCKING=Bond unlocking # suppress inspection "UnusedProperty" dao.bond.bondState.UNLOCKED=Bond unlocked +# suppress inspection "UnusedProperty" +dao.bond.bondState.CONFISCATED=Bond confiscated # suppress inspection "UnusedProperty" dao.phase.UNDEFINED=Undefined diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java index 6e4032ba282..520e4bfd04e 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java @@ -76,18 +76,18 @@ class BondedRolesListItem implements DaoStateListener { if (bondedRole.getBondState() == BondState.READY_FOR_LOCKUP) { bondingViewUtils.lockupBondForBondedRole(role, txId -> { - bondedRole.setLockupTxId(txId); + /*bondedRole.setLockupTxId(txId); bondedRole.setBondState(BondState.LOCKUP_TX_PENDING); update(); - button.setDisable(true); + button.setDisable(true);*/ }); } else if (bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { bondingViewUtils.unLock(bondedRole.getLockupTxId(), txId -> { - bondedRole.setUnlockTxId(txId); + /*bondedRole.setUnlockTxId(txId); bondedRole.setBondState(BondState.UNLOCK_TX_PENDING); update(); - button.setDisable(true); + button.setDisable(true);*/ }); } }); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java index b5b3c971611..ad732028f1d 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/ProposalDisplay.java @@ -28,6 +28,7 @@ import bisq.core.btc.BaseCurrencyNetwork; import bisq.core.dao.DaoFacade; import bisq.core.dao.governance.bond.Bond; +import bisq.core.dao.governance.bond.role.BondedRole; import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.ProposalType; import bisq.core.dao.governance.proposal.param.ChangeParamInputValidator; @@ -55,6 +56,7 @@ import bisq.asset.Asset; import bisq.common.util.Tuple3; +import bisq.common.util.Utilities; import org.bitcoinj.core.Coin; @@ -309,7 +311,17 @@ public BondedRoleType fromString(String string) { confiscateBondComboBox.setConverter(new StringConverter<>() { @Override public String toString(Bond bond) { - return bond != null ? bond.getDisplayString() : ""; + String bondType; + String bondDetails; + if (bond instanceof BondedRole) { + bondType = Res.get("dao.bond.bondedRoles"); + bondDetails = bond.getBondedAsset().getDisplayString(); + } else { + bondType = Res.get("dao.bond.bondedReputation"); + bondDetails = Utilities.bytesAsHexString(bond.getBondedAsset().getHash()); + } + + return bondType + ": " + bondDetails; } @Override @@ -482,13 +494,11 @@ public void applyProposalPayload(Proposal proposal) { } else if (proposal instanceof ConfiscateBondProposal) { ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) proposal; checkNotNull(confiscateBondComboBox, "confiscateBondComboBox must not be null"); - - //TODO - /* daoFacade.getBondedRoleFromHash(confiscateBondProposal.getHash()) - .ifPresent(bondedRole -> { - confiscateBondComboBox.getSelectionModel().select(bondedRole); - comboBoxValueTextField.setText(confiscateBondComboBox.getConverter().toString(bondedRole)); - });*/ + daoFacade.getBondByLockupTxId(confiscateBondProposal.getLockupTxId()) + .ifPresent(bond -> { + confiscateBondComboBox.getSelectionModel().select(bond); + comboBoxValueTextField.setText(confiscateBondComboBox.getConverter().toString(bond)); + }); } else if (proposal instanceof GenericProposal) { // do nothing diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java index 12d5efacea0..c2356c7532f 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java @@ -32,6 +32,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.exceptions.ValidationException; +import bisq.core.dao.governance.bond.Bond; import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.proposal.ProposalType; import bisq.core.dao.governance.proposal.ProposalWithTransaction; @@ -254,7 +255,6 @@ private void doPublishMyProposal(Proposal proposal, Transaction transaction) { private ProposalWithTransaction getProposalWithTransaction(ProposalType type) throws InsufficientMoneyException, ValidationException, TxException { - Role role; switch (type) { case COMPENSATION_REQUEST: checkNotNull(proposalDisplay.requestedBsqTextField, @@ -297,19 +297,17 @@ private ProposalWithTransaction getProposalWithTransaction(ProposalType type) case BONDED_ROLE: checkNotNull(proposalDisplay.bondedRoleTypeComboBox, "proposalDisplay.bondedRoleTypeComboBox must not be null"); - role = new Role(proposalDisplay.nameTextField.getText(), + Role role = new Role(proposalDisplay.nameTextField.getText(), proposalDisplay.linkInputTextField.getText(), proposalDisplay.bondedRoleTypeComboBox.getSelectionModel().getSelectedItem()); return daoFacade.getBondedRoleProposalWithTransaction(role); case CONFISCATE_BOND: checkNotNull(proposalDisplay.confiscateBondComboBox, "proposalDisplay.confiscateBondComboBox must not be null"); - - //TODO - /* role = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); + Bond bond = proposalDisplay.confiscateBondComboBox.getSelectionModel().getSelectedItem(); return daoFacade.getConfiscateBondProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.linkInputTextField.getText(), - role.getHash());*/ + bond.getLockupTxId()); case GENERIC: return daoFacade.getGenericProposalWithTransaction(proposalDisplay.nameTextField.getText(), proposalDisplay.linkInputTextField.getText()); From bee2d1ebd3c1451194fbe45df1ffb2a44b9dd0ce Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 6 Nov 2018 14:58:12 -0500 Subject: [PATCH 22/27] Cleanup bond domain --- .../main/java/bisq/core/dao/DaoFacade.java | 60 ++--- .../main/java/bisq/core/dao/DaoModule.java | 20 +- .../src/main/java/bisq/core/dao/DaoSetup.java | 18 +- .../bisq/core/dao/governance/bond/Bond.java | 30 ++- .../dao/governance/bond/BondConsensus.java | 18 +- .../{BondService.java => BondRepository.java} | 236 ++++++++---------- .../core/dao/governance/bond/BondState.java | 13 +- .../core/dao/governance/bond/BondedAsset.java | 2 +- .../dao/governance/bond/ConfiscateBond.java | 63 ----- .../{LockupType.java => LockupReason.java} | 27 +- ...ockupService.java => LockupTxService.java} | 22 +- .../bond/reputation/BondedReputation.java | 3 +- ...e.java => BondedReputationRepository.java} | 41 +-- .../bond/reputation/MyBondedReputation.java | 3 +- ...java => MyBondedReputationRepository.java} | 33 +-- .../bond/reputation/MyReputation.java | 7 +- .../bond/reputation/MyReputationList.java | 6 +- .../reputation/MyReputationListService.java | 15 +- .../bond/reputation/Reputation.java | 2 + ...ervice.java => BondedRolesRepository.java} | 40 ++- ...nlockService.java => UnlockTxService.java} | 30 ++- .../voteresult/VoteResultService.java | 11 +- .../core/dao/node/parser/OpReturnParser.java | 8 +- .../bisq/core/dao/state/DaoStateService.java | 4 +- .../model/governance/BondedRoleType.java | 10 +- .../resources/i18n/displayStrings.properties | 4 +- .../i18n/displayStrings_de.properties | 4 +- .../i18n/displayStrings_el.properties | 4 +- .../i18n/displayStrings_es.properties | 4 +- .../i18n/displayStrings_fa.properties | 4 +- .../i18n/displayStrings_hu.properties | 4 +- .../i18n/displayStrings_pt.properties | 4 +- .../i18n/displayStrings_ro.properties | 4 +- .../i18n/displayStrings_ru.properties | 4 +- .../i18n/displayStrings_sr.properties | 4 +- .../i18n/displayStrings_th.properties | 4 +- .../i18n/displayStrings_vi.properties | 4 +- .../i18n/displayStrings_zh.properties | 4 +- .../main/dao/bonding/BondingViewUtils.java | 26 +- .../main/dao/bonding/bonds/BondListItem.java | 8 +- .../main/dao/bonding/bonds/BondsView.java | 10 +- 41 files changed, 393 insertions(+), 425 deletions(-) rename core/src/main/java/bisq/core/dao/governance/bond/{BondService.java => BondRepository.java} (75%) delete mode 100644 core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java rename core/src/main/java/bisq/core/dao/governance/bond/lockup/{LockupType.java => LockupReason.java} (67%) rename core/src/main/java/bisq/core/dao/governance/bond/lockup/{LockupService.java => LockupTxService.java} (87%) rename core/src/main/java/bisq/core/dao/governance/bond/reputation/{BondedReputationService.java => BondedReputationRepository.java} (71%) rename core/src/main/java/bisq/core/dao/governance/bond/reputation/{MyBondedReputationService.java => MyBondedReputationRepository.java} (75%) rename core/src/main/java/bisq/core/dao/governance/bond/role/{BondedRolesService.java => BondedRolesRepository.java} (65%) rename core/src/main/java/bisq/core/dao/governance/bond/unlock/{UnlockService.java => UnlockTxService.java} (79%) diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index 0bc623c46a5..428d4799653 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -25,16 +25,16 @@ import bisq.core.dao.governance.blindvote.BlindVoteConsensus; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; import bisq.core.dao.governance.bond.Bond; -import bisq.core.dao.governance.bond.lockup.LockupService; -import bisq.core.dao.governance.bond.lockup.LockupType; +import bisq.core.dao.governance.bond.lockup.LockupReason; +import bisq.core.dao.governance.bond.lockup.LockupTxService; import bisq.core.dao.governance.bond.reputation.BondedReputation; -import bisq.core.dao.governance.bond.reputation.BondedReputationService; +import bisq.core.dao.governance.bond.reputation.BondedReputationRepository; import bisq.core.dao.governance.bond.reputation.MyBondedReputation; -import bisq.core.dao.governance.bond.reputation.MyBondedReputationService; +import bisq.core.dao.governance.bond.reputation.MyBondedReputationRepository; import bisq.core.dao.governance.bond.reputation.MyReputationListService; import bisq.core.dao.governance.bond.role.BondedRole; -import bisq.core.dao.governance.bond.role.BondedRolesService; -import bisq.core.dao.governance.bond.unlock.UnlockService; +import bisq.core.dao.governance.bond.role.BondedRolesRepository; +import bisq.core.dao.governance.bond.unlock.UnlockTxService; import bisq.core.dao.governance.myvote.MyVote; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.param.Param; @@ -119,12 +119,12 @@ public class DaoFacade implements DaoSetupService { private final RoleProposalFactory roleProposalFactory; private final GenericProposalFactory genericProposalFactory; private final RemoveAssetProposalFactory removeAssetProposalFactory; - private final BondedRolesService bondedRolesService; - private final BondedReputationService bondedReputationService; + private final BondedRolesRepository bondedRolesRepository; + private final BondedReputationRepository bondedReputationRepository; private final MyReputationListService myReputationListService; - private final MyBondedReputationService myBondedReputationService; - private final LockupService lockupService; - private final UnlockService unlockService; + private final MyBondedReputationRepository myBondedReputationRepository; + private final LockupTxService lockupTxService; + private final UnlockTxService unlockTxService; private final DaoStateStorageService daoStateStorageService; private final ObjectProperty phaseProperty = new SimpleObjectProperty<>(DaoPhase.Phase.UNDEFINED); @@ -145,12 +145,12 @@ public DaoFacade(MyProposalListService myProposalListService, RoleProposalFactory roleProposalFactory, GenericProposalFactory genericProposalFactory, RemoveAssetProposalFactory removeAssetProposalFactory, - BondedRolesService bondedRolesService, - BondedReputationService bondedReputationService, + BondedRolesRepository bondedRolesRepository, + BondedReputationRepository bondedReputationRepository, MyReputationListService myReputationListService, - MyBondedReputationService myBondedReputationService, - LockupService lockupService, - UnlockService unlockService, + MyBondedReputationRepository myBondedReputationRepository, + LockupTxService lockupTxService, + UnlockTxService unlockTxService, DaoStateStorageService daoStateStorageService) { this.proposalListPresentation = proposalListPresentation; this.ballotListService = ballotListService; @@ -167,12 +167,12 @@ public DaoFacade(MyProposalListService myProposalListService, this.roleProposalFactory = roleProposalFactory; this.genericProposalFactory = genericProposalFactory; this.removeAssetProposalFactory = removeAssetProposalFactory; - this.bondedRolesService = bondedRolesService; - this.bondedReputationService = bondedReputationService; + this.bondedRolesRepository = bondedRolesRepository; + this.bondedReputationRepository = bondedReputationRepository; this.myReputationListService = myReputationListService; - this.myBondedReputationService = myBondedReputationService; - this.lockupService = lockupService; - this.unlockService = unlockService; + this.myBondedReputationRepository = myBondedReputationRepository; + this.lockupTxService = lockupTxService; + this.unlockTxService = unlockTxService; this.daoStateStorageService = daoStateStorageService; } @@ -292,7 +292,7 @@ public ProposalWithTransaction getRemoveAssetProposalWithTransaction(String name } public List getBondedRoles() { - return bondedRolesService.getBonds(); + return bondedRolesRepository.getBonds(); } // Show fee @@ -492,14 +492,14 @@ public int getChainHeight() { // Use case: Bonding /////////////////////////////////////////////////////////////////////////////////////////// - public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, byte[] hash, + public void publishLockupTx(Coin lockupAmount, int lockTime, LockupReason lockupReason, byte[] hash, Consumer resultHandler, ExceptionHandler exceptionHandler) { - lockupService.publishLockupTx(lockupAmount, lockTime, lockupType, hash, resultHandler, exceptionHandler); + lockupTxService.publishLockupTx(lockupAmount, lockTime, lockupReason, hash, resultHandler, exceptionHandler); } public void publishUnlockTx(String lockupTxId, Consumer resultHandler, ExceptionHandler exceptionHandler) { - unlockService.publishUnlockTx(lockupTxId, resultHandler, exceptionHandler); + unlockTxService.publishUnlockTx(lockupTxId, resultHandler, exceptionHandler); } public long getTotalLockupAmount() { @@ -519,19 +519,19 @@ public Optional getLockTime(String txId) { } public List getActiveBondedRoles() { - return bondedRolesService.getActiveBonds(); + return bondedRolesRepository.getActiveBonds(); } public List getAllBonds() { - List bondedReputations = bondedReputationService.getAllBonds(); - List bondedRoles = bondedRolesService.getAllBonds(); + List bondedReputations = bondedReputationRepository.getBonds(); + List bondedRoles = bondedRolesRepository.getBonds(); List bonds = new ArrayList<>(bondedReputations); bonds.addAll(bondedRoles); return bonds; } public List getMyBondedReputations() { - return myBondedReputationService.getMyBondedReputations(); + return myBondedReputationRepository.getMyBondedReputations(); } @@ -661,7 +661,7 @@ public void resyncDao(Runnable resultHandler) { } public boolean isMyRole(Role role) { - return bondedRolesService.isMyRole(role); + return bondedRolesRepository.isMyRole(role); } public Optional getBondByLockupTxId(String lockupTxId) { diff --git a/core/src/main/java/bisq/core/dao/DaoModule.java b/core/src/main/java/bisq/core/dao/DaoModule.java index f29f582ac1b..42416c97142 100644 --- a/core/src/main/java/bisq/core/dao/DaoModule.java +++ b/core/src/main/java/bisq/core/dao/DaoModule.java @@ -26,12 +26,12 @@ import bisq.core.dao.governance.blindvote.network.RepublishGovernanceDataHandler; import bisq.core.dao.governance.blindvote.storage.BlindVoteStorageService; import bisq.core.dao.governance.blindvote.storage.BlindVoteStore; -import bisq.core.dao.governance.bond.lockup.LockupService; -import bisq.core.dao.governance.bond.reputation.BondedReputationService; -import bisq.core.dao.governance.bond.reputation.MyBondedReputationService; +import bisq.core.dao.governance.bond.lockup.LockupTxService; +import bisq.core.dao.governance.bond.reputation.BondedReputationRepository; +import bisq.core.dao.governance.bond.reputation.MyBondedReputationRepository; import bisq.core.dao.governance.bond.reputation.MyReputationListService; -import bisq.core.dao.governance.bond.role.BondedRolesService; -import bisq.core.dao.governance.bond.unlock.UnlockService; +import bisq.core.dao.governance.bond.role.BondedRolesRepository; +import bisq.core.dao.governance.bond.unlock.UnlockTxService; import bisq.core.dao.governance.myvote.MyVoteListService; import bisq.core.dao.governance.period.CycleService; import bisq.core.dao.governance.period.PeriodService; @@ -186,12 +186,12 @@ protected void configure() { bind(Integer.class).annotatedWith(Names.named(DaoOptionKeys.GENESIS_BLOCK_HEIGHT)).toInstance(genesisBlockHeight); // Bonds - bind(LockupService.class).in(Singleton.class); - bind(UnlockService.class).in(Singleton.class); - bind(BondedRolesService.class).in(Singleton.class); - bind(BondedReputationService.class).in(Singleton.class); + bind(LockupTxService.class).in(Singleton.class); + bind(UnlockTxService.class).in(Singleton.class); + bind(BondedRolesRepository.class).in(Singleton.class); + bind(BondedReputationRepository.class).in(Singleton.class); bind(MyReputationListService.class).in(Singleton.class); - bind(MyBondedReputationService.class).in(Singleton.class); + bind(MyBondedReputationRepository.class).in(Singleton.class); // Asset bind(AssetService.class).in(Singleton.class); diff --git a/core/src/main/java/bisq/core/dao/DaoSetup.java b/core/src/main/java/bisq/core/dao/DaoSetup.java index 438ca7384e3..b418d1d535e 100644 --- a/core/src/main/java/bisq/core/dao/DaoSetup.java +++ b/core/src/main/java/bisq/core/dao/DaoSetup.java @@ -20,10 +20,10 @@ import bisq.core.dao.governance.ballot.BallotListService; import bisq.core.dao.governance.blindvote.BlindVoteListService; import bisq.core.dao.governance.blindvote.MyBlindVoteListService; -import bisq.core.dao.governance.bond.reputation.BondedReputationService; -import bisq.core.dao.governance.bond.reputation.MyBondedReputationService; +import bisq.core.dao.governance.bond.reputation.BondedReputationRepository; +import bisq.core.dao.governance.bond.reputation.MyBondedReputationRepository; import bisq.core.dao.governance.bond.reputation.MyReputationListService; -import bisq.core.dao.governance.bond.role.BondedRolesService; +import bisq.core.dao.governance.bond.role.BondedRolesRepository; import bisq.core.dao.governance.period.CycleService; import bisq.core.dao.governance.proposal.ProposalService; import bisq.core.dao.governance.voteresult.MissingDataRequestService; @@ -60,10 +60,10 @@ public DaoSetup(BsqNodeProvider bsqNodeProvider, VoteRevealService voteRevealService, VoteResultService voteResultService, MissingDataRequestService missingDataRequestService, - BondedReputationService bondedReputationService, - BondedRolesService bondedRolesService, + BondedReputationRepository bondedReputationRepository, + BondedRolesRepository bondedRolesRepository, MyReputationListService myReputationListService, - MyBondedReputationService myBondedReputationService, + MyBondedReputationRepository myBondedReputationRepository, DaoFacade daoFacade, ExportJsonFilesService exportJsonFilesService) { @@ -79,10 +79,10 @@ public DaoSetup(BsqNodeProvider bsqNodeProvider, daoSetupServices.add(voteRevealService); daoSetupServices.add(voteResultService); daoSetupServices.add(missingDataRequestService); - daoSetupServices.add(bondedReputationService); - daoSetupServices.add(bondedRolesService); + daoSetupServices.add(bondedReputationRepository); + daoSetupServices.add(bondedRolesRepository); daoSetupServices.add(myReputationListService); - daoSetupServices.add(myBondedReputationService); + daoSetupServices.add(myBondedReputationRepository); daoSetupServices.add(daoFacade); daoSetupServices.add(exportJsonFilesService); daoSetupServices.add(bsqNodeProvider.getBsqNode()); diff --git a/core/src/main/java/bisq/core/dao/governance/bond/Bond.java b/core/src/main/java/bisq/core/dao/governance/bond/Bond.java index adbe0ce4567..d4c8cd5df6b 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/Bond.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/Bond.java @@ -17,7 +17,7 @@ package bisq.core.dao.governance.bond; -import bisq.core.locale.Res; +import java.util.Objects; import lombok.Getter; import lombok.Setter; @@ -25,7 +25,7 @@ import javax.annotation.Nullable; /** - * Base class for BondedRole and BondedAsset. Holds the bond state of the bonded asset. + * Base class for BondedRole and BondedReputation. Holds the state of the bonded asset. */ @Getter public abstract class Bond { @@ -48,8 +48,7 @@ public abstract class Bond { @Setter private int lockTime; - - public Bond(T bondedAsset) { + protected Bond(T bondedAsset) { this.bondedAsset = bondedAsset; } @@ -58,8 +57,26 @@ public boolean isActive() { bondState != BondState.UNLOCKED; } - public String getDisplayString() { - return Res.get("dao.bonding.info", lockupTxId, getBondedAsset().getDisplayString()); + // Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! + // The equals and hashCode methods cannot be overwritten in Enums. + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Bond)) return false; + Bond bond = (Bond) o; + return amount == bond.amount && + lockupDate == bond.lockupDate && + unlockDate == bond.unlockDate && + lockTime == bond.lockTime && + Objects.equals(bondedAsset, bond.bondedAsset) && + Objects.equals(lockupTxId, bond.lockupTxId) && + Objects.equals(unlockTxId, bond.unlockTxId) && + bondState.name().equals(bond.bondState.name()); + } + + @Override + public int hashCode() { + return Objects.hash(bondedAsset, lockupTxId, unlockTxId, bondState.name(), amount, lockupDate, unlockDate, lockTime); } @Override @@ -72,6 +89,7 @@ public String toString() { ",\n amount=" + amount + ",\n lockupDate=" + lockupDate + ",\n unlockDate=" + unlockDate + + ",\n lockTime=" + lockTime + "\n}"; } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java b/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java index 820a9c13ca9..25fd40deec3 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondConsensus.java @@ -17,7 +17,7 @@ package bisq.core.dao.governance.bond; -import bisq.core.dao.governance.bond.lockup.LockupType; +import bisq.core.dao.governance.bond.lockup.LockupReason; import bisq.core.dao.state.model.blockchain.OpReturnType; import bisq.common.app.Version; @@ -44,13 +44,13 @@ public class BondConsensus { @Getter private static int maxLockTime = 65535; - public static byte[] getLockupOpReturnData(int lockTime, LockupType type, byte[] hash) throws IOException { + public static byte[] getLockupOpReturnData(int lockTime, LockupReason type, byte[] hash) throws IOException { // PushData of <= 4 bytes is converted to int when returned from bitcoind and not handled the way we // require by btcd-cli4j, avoid opReturns with 4 bytes or less try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) { outputStream.write(OpReturnType.LOCKUP.getType()); outputStream.write(Version.LOCKUP); - outputStream.write(type.getType()); + outputStream.write(type.getId()); byte[] bytes = Utilities.integerToByteArray(lockTime, 2); outputStream.write(bytes[0]); outputStream.write(bytes[1]); @@ -72,19 +72,19 @@ public static int getLockTime(byte[] opReturnData) { return Utilities.byteArrayToInteger(Arrays.copyOfRange(opReturnData, 3, 5)); } + public static byte[] getHashFromOpReturnData(byte[] opReturnData) { + return Arrays.copyOfRange(opReturnData, 5, 25); + } + public static boolean isLockTimeInValidRange(int lockTime) { return lockTime >= BondConsensus.getMinLockTime() && lockTime <= BondConsensus.getMaxLockTime(); } - public static Optional getLockupType(byte[] opReturnData) { - return LockupType.getLockupType(opReturnData[2]); + public static Optional getLockupReason(byte[] opReturnData) { + return LockupReason.getLockupReason(opReturnData[2]); } public static boolean isLockTimeOver(long unlockBlockHeight, long currentBlockHeight) { return currentBlockHeight >= unlockBlockHeight; } - - public static byte[] getHashFromOpReturnData(byte[] opReturnData) { - return Arrays.copyOfRange(opReturnData, 5, 25); - } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondService.java b/core/src/main/java/bisq/core/dao/governance/bond/BondRepository.java similarity index 75% rename from core/src/main/java/bisq/core/dao/governance/bond/BondService.java rename to core/src/main/java/bisq/core/dao/governance/bond/BondRepository.java index 9cfdd6a9417..1e9f51f290b 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondRepository.java @@ -40,19 +40,90 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; -import static com.google.common.base.Preconditions.checkArgument; - /** - * Manages bonds. + * Collect bonds and bond asset data from other sources and provides access to the collection. */ @Slf4j -public abstract class BondService implements DaoStateListener, DaoSetupService { +public abstract class BondRepository implements DaoStateListener, DaoSetupService { + + /////////////////////////////////////////////////////////////////////////////////////////// + // Static + /////////////////////////////////////////////////////////////////////////////////////////// + + public static void applyBondState(DaoStateService daoStateService, Bond bond, Tx lockupTx, TxOutput lockupTxOutput) { + if (bond.getBondState() != BondState.LOCKUP_TX_PENDING || bond.getBondState() != BondState.UNLOCK_TX_PENDING) + bond.setBondState(BondState.LOCKUP_TX_CONFIRMED); + + bond.setLockupTxId(lockupTx.getId()); + // We use the tx time as we want to have a unique time for all users + bond.setLockupDate(lockupTx.getTime()); + bond.setAmount(lockupTx.getLockedAmount()); + bond.setLockTime(lockupTx.getLockTime()); + + if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { + // Lockup is already spent (in unlock tx) + daoStateService.getSpentInfo(lockupTxOutput) + .map(SpentInfo::getTxId) + .flatMap(daoStateService::getTx) + .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) + .ifPresent(unlockTx -> { + // cross check if it is in daoStateService.getUnlockTxOutputs() ? + String unlockTxId = unlockTx.getId(); + bond.setUnlockTxId(unlockTxId); + bond.setBondState(BondState.UNLOCK_TX_CONFIRMED); + bond.setUnlockDate(unlockTx.getTime()); + boolean unlocking = daoStateService.isUnlockingAndUnspent(unlockTxId); + if (unlocking) { + bond.setBondState(BondState.UNLOCKING); + } else { + bond.setBondState(BondState.UNLOCKED); + } + }); + } + + if ((bond.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(bond.getLockupTxId())) || + (bond.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(bond.getUnlockTxId()))) { + bond.setBondState(BondState.CONFISCATED); + } + } + + public static boolean isLockupTxUnconfirmed(BsqWalletService bsqWalletService, BondedAsset bondedAsset) { + return bsqWalletService.getPendingWalletTransactionsStream() + .map(transaction -> transaction.getOutputs().get(transaction.getOutputs().size() - 1)) + .filter(lastOutput -> lastOutput.getScriptPubKey().isOpReturn()) + .map(lastOutput -> lastOutput.getScriptPubKey().getChunks()) + .filter(chunks -> chunks.size() > 1) + .map(chunks -> chunks.get(1).data) + .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondedAsset.getHash())); + } + + public static boolean isUnlockTxUnconfirmed(BsqWalletService bsqWalletService, DaoStateService daoStateService, BondedAsset bondedAsset) { + return bsqWalletService.getPendingWalletTransactionsStream() + .filter(transaction -> transaction.getInputs().size() > 1) + .flatMap(transaction -> transaction.getInputs().stream()) // We need to iterate all inputs + .map(TransactionInput::getConnectedOutput) + .filter(Objects::nonNull) + .filter(transactionOutput -> transactionOutput.getIndex() == 0) // The output at the lockupTx must be index 0 + .map(TransactionOutput::getParentTransaction) + .filter(Objects::nonNull) + .map(Transaction::getHashAsString) + .map(lockupTxId -> daoStateService.getLockupOpReturnTxOutput(lockupTxId).orElse(null)) + .filter(Objects::nonNull) + .map(BaseTxOutput::getOpReturnData) + .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondedAsset.getHash())); + } + + public static boolean isConfiscated(Bond bond, DaoStateService daoStateService) { + return (bond.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(bond.getLockupTxId())) || + (bond.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(bond.getUnlockTxId())); + } + + protected final DaoStateService daoStateService; protected final BsqWalletService bsqWalletService; @@ -65,7 +136,7 @@ public abstract class BondService impleme /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public BondService(DaoStateService daoStateService, BsqWalletService bsqWalletService) { + public BondRepository(DaoStateService daoStateService, BsqWalletService bsqWalletService) { this.daoStateService = daoStateService; this.bsqWalletService = bsqWalletService; @@ -100,74 +171,6 @@ public void onParseTxsComplete(Block block) { updateMap(); } - protected void updateMap() { - getBondedAssetStream().forEach(bondedAsset -> { - String uid = bondedAsset.getUid(); - bondByUidMap.putIfAbsent(uid, createBond(bondedAsset)); - T bond = bondByUidMap.get(uid); - - daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> { - updateBond(bond, bondedAsset, lockupTxOutput); - }); - }); - - updateBondStateFromUnconfirmedLockupTxs(); - updateBondStateFromUnconfirmedUnlockTxs(); - } - - public void updateBond(T bond, R bondedAsset, TxOutput lockupTxOutput) { - // Lets see if we have a lock up tx. - String lockupTxId = lockupTxOutput.getTxId(); - daoStateService.getTx(lockupTxId).ifPresent(lockupTx -> { - byte[] opReturnData = lockupTx.getLastTxOutput().getOpReturnData(); - // We used the hash of th bonded bondedAsset object as our hash in OpReturn of the lock up tx to have a - // unique binding of the tx to the data object. - byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); - Optional candidate = findBondedAssetByHash(hash); - if (candidate.isPresent() && bondedAsset.equals(candidate.get())) - applyBondState(daoStateService, bond, lockupTx, lockupTxOutput); - }); - } - - public static void applyBondState(DaoStateService daoStateService, Bond bond, Tx lockupTx, TxOutput lockupTxOutput) { - if (bond.getBondState() != BondState.LOCKUP_TX_PENDING || bond.getBondState() != BondState.UNLOCK_TX_PENDING) - bond.setBondState(BondState.LOCKUP_TX_CONFIRMED); - - bond.setLockupTxId(lockupTx.getId()); - // We use the tx time as we want to have a unique time for all users - bond.setLockupDate(lockupTx.getTime()); - bond.setAmount(lockupTx.getLockedAmount()); - bond.setLockTime(lockupTx.getLockTime()); - - if (!daoStateService.isUnspent(lockupTxOutput.getKey())) { - // Lockup is already spent (in unlock tx) - daoStateService.getSpentInfo(lockupTxOutput) - .map(SpentInfo::getTxId) - .flatMap(daoStateService::getTx) - .filter(unlockTx -> unlockTx.getTxType() == TxType.UNLOCK) - .ifPresent(unlockTx -> { - // cross check if it is in daoStateService.getUnlockTxOutputs() ? - String unlockTxId = unlockTx.getId(); - bond.setUnlockTxId(unlockTxId); - bond.setBondState(BondState.UNLOCK_TX_CONFIRMED); - bond.setUnlockDate(unlockTx.getTime()); - boolean unlocking = daoStateService.isUnlockingAndUnspent(unlockTxId); - if (unlocking) { - bond.setBondState(BondState.UNLOCKING); - } else { - bond.setBondState(BondState.UNLOCKED); - } - }); - } - - if ((bond.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(bond.getLockupTxId())) || - (bond.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(bond.getUnlockTxId()))) { - bond.setBondState(BondState.CONFISCATED); - } - } - - protected abstract T createBond(R bondedAsset); - @Override public void onParseBlockChainComplete() { } @@ -187,26 +190,10 @@ public List getActiveBonds() { .collect(Collectors.toList()); } - public List getAllBonds() { - return new ArrayList<>(bondByUidMap.values()); - } - - public Optional findBondByLockupTxId(String lockupTxId) { - return bondByUidMap.values().stream() - .filter(bond -> lockupTxId.equals(bond.getLockupTxId())) - .findAny(); - } - - public boolean wasBondedAssetAlreadyBonded(R bondedAsset) { - T bond = bondByUidMap.get(bondedAsset.getUid()); - checkArgument(bond != null, "bond must not be null"); - return bond.getLockupTxId() != null; - } + public boolean isBondedAssetAlreadyInBond(R bondedAsset) { + boolean contains = bondByUidMap.containsKey(bondedAsset.getUid()); + return contains && bondByUidMap.get(bondedAsset.getUid()).getLockupTxId() != null; - public Optional findBondedAssetByHash(byte[] hash) { - return getBondedAssetStream() - .filter(bondedAsset -> Arrays.equals(bondedAsset.getHash(), hash)) - .findAny(); } @@ -214,8 +201,27 @@ public Optional findBondedAssetByHash(byte[] hash) { // Protected /////////////////////////////////////////////////////////////////////////////////////////// + abstract protected T createBond(R bondedAsset); + + abstract protected void updateBond(T bond, R bondedAsset, TxOutput lockupTxOutput); + abstract protected Stream getBondedAssetStream(); + protected void updateMap() { + getBondedAssetStream().forEach(bondedAsset -> { + String uid = bondedAsset.getUid(); + bondByUidMap.putIfAbsent(uid, createBond(bondedAsset)); + T bond = bondByUidMap.get(uid); + + daoStateService.getLockupTxOutputs().forEach(lockupTxOutput -> { + updateBond(bond, bondedAsset, lockupTxOutput); + }); + }); + + updateBondStateFromUnconfirmedLockupTxs(); + updateBondStateFromUnconfirmedUnlockTxs(); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Private @@ -225,53 +231,13 @@ private void updateBondStateFromUnconfirmedLockupTxs() { getBondedAssetStream().filter(bondedAsset -> isLockupTxUnconfirmed(bsqWalletService, bondedAsset)) .map(bondedAsset -> bondByUidMap.get(bondedAsset.getUid())) .filter(bond -> bond.getBondState() == BondState.READY_FOR_LOCKUP) - .forEach(bond -> { - if ((bond.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(bond.getLockupTxId())) || - (bond.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(bond.getUnlockTxId()))) { - bond.setBondState(BondState.CONFISCATED); - } else { - bond.setBondState(BondState.LOCKUP_TX_PENDING); - } - }); + .forEach(bond -> bond.setBondState(isConfiscated(bond, daoStateService) ? BondState.CONFISCATED : BondState.LOCKUP_TX_PENDING)); } private void updateBondStateFromUnconfirmedUnlockTxs() { getBondedAssetStream().filter(bondedAsset -> isUnlockTxUnconfirmed(bsqWalletService, daoStateService, bondedAsset)) .map(bondedAsset -> bondByUidMap.get(bondedAsset.getUid())) .filter(bond -> bond.getBondState() == BondState.LOCKUP_TX_CONFIRMED) - .forEach(bond -> { - if ((bond.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(bond.getLockupTxId())) || - (bond.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(bond.getUnlockTxId()))) { - bond.setBondState(BondState.CONFISCATED); - } else { - bond.setBondState(BondState.UNLOCK_TX_PENDING); - } - }); - } - - public static boolean isLockupTxUnconfirmed(BsqWalletService bsqWalletService, BondedAsset bondedAsset) { - return bsqWalletService.getPendingWalletTransactionsStream() - .map(transaction -> transaction.getOutputs().get(transaction.getOutputs().size() - 1)) - .filter(lastOutput -> lastOutput.getScriptPubKey().isOpReturn()) - .map(lastOutput -> lastOutput.getScriptPubKey().getChunks()) - .filter(chunks -> chunks.size() > 1) - .map(chunks -> chunks.get(1).data) - .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondedAsset.getHash())); - } - - public static boolean isUnlockTxUnconfirmed(BsqWalletService bsqWalletService, DaoStateService daoStateService, BondedAsset bondedAsset) { - return bsqWalletService.getPendingWalletTransactionsStream() - .filter(transaction -> transaction.getInputs().size() > 1) - .flatMap(transaction -> transaction.getInputs().stream()) // We need to iterate all inputs - .map(TransactionInput::getConnectedOutput) - .filter(Objects::nonNull) - .filter(transactionOutput -> transactionOutput.getIndex() == 0) // The output at the lockupTx must be index 0 - .map(TransactionOutput::getParentTransaction) - .filter(Objects::nonNull) - .map(Transaction::getHashAsString) - .map(lockupTxId -> daoStateService.getLockupOpReturnTxOutput(lockupTxId).orElse(null)) - .filter(Objects::nonNull) - .map(BaseTxOutput::getOpReturnData) - .anyMatch(data -> Arrays.equals(BondConsensus.getHashFromOpReturnData(data), bondedAsset.getHash())); + .forEach(bond -> bond.setBondState(isConfiscated(bond, daoStateService) ? BondState.CONFISCATED : BondState.UNLOCK_TX_PENDING)); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondState.java b/core/src/main/java/bisq/core/dao/governance/bond/BondState.java index 32843661371..1d74ed19965 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondState.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondState.java @@ -17,14 +17,17 @@ package bisq.core.dao.governance.bond; -// Used in string properties ("dao.bond.bondState.*") +/** + * Holds the different states of a bond. + * Used also in string properties ("dao.bond.bondState.*") + */ public enum BondState { - READY_FOR_LOCKUP, // Accepted by voting but no lockup tx made yet. + READY_FOR_LOCKUP, // Accepted by voting (if role) but no lockup tx made yet. LOCKUP_TX_PENDING, // Tx broadcasted but not confirmed. Used only by tx publisher. LOCKUP_TX_CONFIRMED, UNLOCK_TX_PENDING, // Tx broadcasted but not confirmed. Used only by tx publisher. UNLOCK_TX_CONFIRMED, - UNLOCKING, // lock time not expired - UNLOCKED, - CONFISCATED + UNLOCKING, // Lock time still not expired + UNLOCKED, // Fully unlocked + CONFISCATED // Bond got confiscated by DAO voting } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondedAsset.java b/core/src/main/java/bisq/core/dao/governance/bond/BondedAsset.java index 78689cc1770..46f5a7c5730 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondedAsset.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondedAsset.java @@ -18,7 +18,7 @@ package bisq.core.dao.governance.bond; /** - * Interface of the bonded asset like the Role or Reputation. + * Represents the bonded asset (e.g. Role or Reputation). */ public interface BondedAsset { byte[] getHash(); diff --git a/core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java b/core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java deleted file mode 100644 index 382e0e7a7c3..00000000000 --- a/core/src/main/java/bisq/core/dao/governance/bond/ConfiscateBond.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.core.dao.governance.bond; - -import bisq.common.proto.persistable.PersistablePayload; - -import io.bisq.generated.protobuffer.PB; - -import lombok.Value; - -import javax.annotation.concurrent.Immutable; - -/** - * Holds the hash of a confiscated bond. - */ -@Immutable -@Value -public class ConfiscateBond implements PersistablePayload { - private final String lockupTxId; - - public ConfiscateBond(String lockupTxId) { - this.lockupTxId = lockupTxId; - } - - /////////////////////////////////////////////////////////////////////////////////////////// - // PROTO BUFFER - /////////////////////////////////////////////////////////////////////////////////////////// - - - @Override - public PB.ConfiscateBond toProtoMessage() { - return PB.ConfiscateBond.newBuilder() - .setLockupTxId(lockupTxId) - .build(); - } - - public static ConfiscateBond fromProto(PB.ConfiscateBond proto) { - return new ConfiscateBond(proto.getLockupTxId()); - } - - - @Override - public String toString() { - return "ConfiscateBond{" + - "\n lockupTxId='" + lockupTxId + '\'' + - "\n}"; - } -} diff --git a/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupType.java b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupReason.java similarity index 67% rename from core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupType.java rename to core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupReason.java index 914ad31be6f..abf4ecde08c 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupType.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupReason.java @@ -17,33 +17,32 @@ package bisq.core.dao.governance.bond.lockup; -import bisq.core.locale.Res; - import java.util.Arrays; import java.util.Optional; import lombok.Getter; -public enum LockupType { +/** + * Reason for locking up a bond. + */ +public enum LockupReason { BONDED_ROLE((byte) 0x01), REPUTATION((byte) 0x02); @Getter - private byte type; + private byte id; - LockupType(byte type) { - this.type = type; + LockupReason(byte id) { + this.id = id; } - public String getDisplayString() { + /* public String getDisplayString() { return Res.get("dao.bond.lockupType." + name()); - } + }*/ - public static Optional getLockupType(byte type) { - return Arrays.stream(LockupType.values()) - .filter(lockupType -> lockupType.type == type) - .map(Optional::of) - .findAny() - .orElse(Optional.empty()); + public static Optional getLockupReason(byte id) { + return Arrays.stream(LockupReason.values()) + .filter(lockupType -> lockupType.id == id) + .findAny(); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupTxService.java similarity index 87% rename from core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java rename to core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupTxService.java index bc72fa8c214..d842f4c028c 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupTxService.java @@ -43,8 +43,11 @@ import static com.google.common.base.Preconditions.checkArgument; +/** + * Service for publishing the lockup transaction. + */ @Slf4j -public class LockupService { +public class LockupTxService { private final WalletsManager walletsManager; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; @@ -55,23 +58,22 @@ public class LockupService { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public LockupService(WalletsManager walletsManager, - BsqWalletService bsqWalletService, - BtcWalletService btcWalletService) { + public LockupTxService(WalletsManager walletsManager, + BsqWalletService bsqWalletService, + BtcWalletService btcWalletService) { this.walletsManager = walletsManager; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; } - public void publishLockupTx(Coin lockupAmount, int lockTime, LockupType lockupType, byte[] hash, + public void publishLockupTx(Coin lockupAmount, int lockTime, LockupReason lockupReason, byte[] hash, Consumer resultHandler, ExceptionHandler exceptionHandler) { checkArgument(lockTime <= BondConsensus.getMaxLockTime() && - lockTime >= BondConsensus.getMinLockTime(), "lockTime not in rage"); + lockTime >= BondConsensus.getMinLockTime(), "lockTime not in range"); try { - byte[] opReturnData = BondConsensus.getLockupOpReturnData(lockTime, lockupType, hash); + byte[] opReturnData = BondConsensus.getLockupOpReturnData(lockTime, lockupReason, hash); Transaction lockupTx = createLockupTx(lockupAmount, opReturnData); - //noinspection Duplicates walletsManager.publishAndCommitBsqTx(lockupTx, new TxBroadcaster.Callback() { @Override public void onSuccess(Transaction transaction) { @@ -99,6 +101,8 @@ private Transaction createLockupTx(Coin lockupAmount, byte[] opReturnData) throws InsufficientMoneyException, WalletException, TransactionVerificationException { Transaction preparedTx = bsqWalletService.getPreparedLockupTx(lockupAmount); Transaction txWithBtcFee = btcWalletService.completePreparedBsqTx(preparedTx, true, opReturnData); - return bsqWalletService.signTx(txWithBtcFee); + Transaction transaction = bsqWalletService.signTx(txWithBtcFee); + log.info("Lockup tx: " + transaction); + return transaction; } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java index 85053f5ac14..a6306727714 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputation.java @@ -29,11 +29,10 @@ @EqualsAndHashCode(callSuper = true) public final class BondedReputation extends Bond { - public BondedReputation(Reputation reputation) { + BondedReputation(Reputation reputation) { super(reputation); } - @Override public String toString() { return "BondedReputation{" + diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationRepository.java similarity index 71% rename from core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java rename to core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationRepository.java index 5e9f1958762..c5537c45ad7 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationRepository.java @@ -20,8 +20,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.governance.bond.Bond; import bisq.core.dao.governance.bond.BondConsensus; -import bisq.core.dao.governance.bond.BondService; -import bisq.core.dao.governance.bond.role.BondedRolesService; +import bisq.core.dao.governance.bond.BondRepository; +import bisq.core.dao.governance.bond.role.BondedRolesRepository; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.model.blockchain.TxOutput; @@ -35,20 +35,24 @@ import lombok.extern.slf4j.Slf4j; +/** + * Collect bonded reputations from the daoState blockchain data excluding bonded roles + * and provides access to the collection. + */ @Slf4j -public class BondedReputationService extends BondService { - private final BondedRolesService bondedRolesService; +public class BondedReputationRepository extends BondRepository { + private final BondedRolesRepository bondedRolesRepository; /////////////////////////////////////////////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public BondedReputationService(DaoStateService daoStateService, BsqWalletService bsqWalletService, - BondedRolesService bondedRolesService) { + public BondedReputationRepository(DaoStateService daoStateService, BsqWalletService bsqWalletService, + BondedRolesRepository bondedRolesRepository) { super(daoStateService, bsqWalletService); - this.bondedRolesService = bondedRolesService; + this.bondedRolesRepository = bondedRolesRepository; } @@ -69,18 +73,13 @@ protected Stream getBondedAssetStream() { @Override protected void updateMap() { bondByUidMap.clear(); - getBondedReputationStream().forEach(bondedReputation -> { - bondByUidMap.put(bondedReputation.getBondedAsset().getUid(), bondedReputation); - }); + getBondedReputationStream().forEach(bondedReputation -> bondByUidMap.put(bondedReputation.getBondedAsset().getUid(), bondedReputation)); } private Stream getBondedReputationStream() { - Set bondedRolesLockupTxIdSet = bondedRolesService.getAllBonds().stream().map(e -> e.getLockupTxId()).collect(Collectors.toSet()); - return daoStateService.getLockupTxOutputs().stream() + return getLockupTxOutputsForBondedReputation() .map(lockupTxOutput -> { String lockupTxId = lockupTxOutput.getTxId(); - // long time = daoStateService.getTx(lockupTxId).map(BaseTx::getTime).orElse(0L); - // lockupTxOutput is first output, but we need the data from the opReturn Optional optionalOpReturnTxOutput = daoStateService.getLockupOpReturnTxOutput(lockupTxId); if (optionalOpReturnTxOutput.isPresent()) { TxOutput opReturnTxOutput = optionalOpReturnTxOutput.get(); @@ -94,16 +93,22 @@ private Stream getBondedReputationStream() { } }) - .filter(Objects::nonNull) - .filter(e -> !bondedRolesLockupTxIdSet.contains(e.getLockupTxId())); + .filter(Objects::nonNull); + } + + private Stream getLockupTxOutputsForBondedReputation() { + // We exclude bonded roles, so we store those ina lookup set. + Set bondedRolesLockupTxIdSet = bondedRolesRepository.getBonds().stream().map(Bond::getLockupTxId).collect(Collectors.toSet()); + return daoStateService.getLockupTxOutputs().stream() + .filter(e -> !bondedRolesLockupTxIdSet.contains(e.getTxId())); } @Override - public void updateBond(BondedReputation bond, Reputation bondedAsset, TxOutput lockupTxOutput) { + protected void updateBond(BondedReputation bond, Reputation bondedAsset, TxOutput lockupTxOutput) { // Lets see if we have a lock up tx. String lockupTxId = lockupTxOutput.getTxId(); daoStateService.getTx(lockupTxId).ifPresent(lockupTx -> { - applyBondState(daoStateService, bond, lockupTx, lockupTxOutput); + BondRepository.applyBondState(daoStateService, bond, lockupTx, lockupTxOutput); }); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputation.java index 3c564510803..f9af093c4ad 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputation.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputation.java @@ -23,7 +23,8 @@ import lombok.Getter; /** - * Wrapper for reputation which contains the mutable state of a bonded reputation. Only kept in memory. + * Wrapper for reputation which contains the mutable state of my bonded reputation. Only kept in memory. + * As it carries MyReputation it has access to the private salt data. */ @Getter @EqualsAndHashCode(callSuper = true) diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationRepository.java similarity index 75% rename from core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java rename to core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationRepository.java index 2cec71a8614..871cac26096 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationRepository.java @@ -20,7 +20,7 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoSetupService; import bisq.core.dao.governance.bond.BondConsensus; -import bisq.core.dao.governance.bond.BondService; +import bisq.core.dao.governance.bond.BondRepository; import bisq.core.dao.governance.bond.BondState; import bisq.core.dao.state.DaoStateService; @@ -36,8 +36,11 @@ import lombok.extern.slf4j.Slf4j; +/** + * Collect MyBondedReputations from the myReputationListService and provides access to the collection. + */ @Slf4j -public class MyBondedReputationService implements DaoSetupService { +public class MyBondedReputationRepository implements DaoSetupService { private final DaoStateService daoStateService; private final BsqWalletService bsqWalletService; private final MyReputationListService myReputationListService; @@ -48,9 +51,9 @@ public class MyBondedReputationService implements DaoSetupService { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public MyBondedReputationService(DaoStateService daoStateService, - BsqWalletService bsqWalletService, - MyReputationListService myReputationListService) { + public MyBondedReputationRepository(DaoStateService daoStateService, + BsqWalletService bsqWalletService, + MyReputationListService myReputationListService) { this.daoStateService = daoStateService; this.bsqWalletService = bsqWalletService; this.myReputationListService = myReputationListService; @@ -75,25 +78,24 @@ public void start() { /////////////////////////////////////////////////////////////////////////////////////////// public List getMyBondedReputations() { - // It can be that the same salt/hash is in several lockupTxs, so we use a map to eliminate duplicates by the - // collection algorithm. - Map map = new HashMap<>(); + // It can be that the same salt/hash is in several lockupTxs, so we use the bondByLockupTxIdMap to eliminate + // duplicates by the collection algorithm. + Map bondByLockupTxIdMap = new HashMap<>(); myReputationListService.getMyReputationList().stream() .flatMap(this::getMyBondedReputation) - .forEach(e -> map.putIfAbsent(e.getLockupTxId(), e)); + .forEach(e -> bondByLockupTxIdMap.putIfAbsent(e.getLockupTxId(), e)); - return map.values().stream() + return bondByLockupTxIdMap.values().stream() .peek(myBondedReputation -> { - if ((myBondedReputation.getLockupTxId() != null && daoStateService.isConfiscatedLockupTxOutput(myBondedReputation.getLockupTxId())) || - (myBondedReputation.getUnlockTxId() != null && daoStateService.isConfiscatedUnlockTxOutput(myBondedReputation.getUnlockTxId()))) { + if (BondRepository.isConfiscated(myBondedReputation, daoStateService)) { myBondedReputation.setBondState(BondState.CONFISCATED); } else { // We don't have a UI use case for showing LOCKUP_TX_PENDING yet, but lets keep the code so if needed // its there. - if (BondService.isLockupTxUnconfirmed(bsqWalletService, myBondedReputation.getBondedAsset()) && + if (BondRepository.isLockupTxUnconfirmed(bsqWalletService, myBondedReputation.getBondedAsset()) && myBondedReputation.getBondState() == BondState.READY_FOR_LOCKUP) { myBondedReputation.setBondState(BondState.LOCKUP_TX_PENDING); - } else if (BondService.isUnlockTxUnconfirmed(bsqWalletService, daoStateService, myBondedReputation.getBondedAsset()) && + } else if (BondRepository.isUnlockTxUnconfirmed(bsqWalletService, daoStateService, myBondedReputation.getBondedAsset()) && myBondedReputation.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { myBondedReputation.setBondState(BondState.UNLOCK_TX_PENDING); } @@ -110,9 +112,10 @@ private Stream getMyBondedReputation(MyReputation myReputati .map(lockupTx -> { byte[] opReturnData = lockupTx.getLastTxOutput().getOpReturnData(); byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); + // There could be multiple txs with the same hash, so we collect a stream and not use an optional. if (Arrays.equals(hash, myReputation.getHash())) { MyBondedReputation myBondedReputation = new MyBondedReputation(myReputation); - BondService.applyBondState(daoStateService, myBondedReputation, lockupTx, lockupTxOutput); + BondRepository.applyBondState(daoStateService, myBondedReputation, lockupTx, lockupTxOutput); return myBondedReputation; } else { return null; diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java index b7311c0a7db..ac40f6cebee 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java @@ -37,13 +37,18 @@ import javax.annotation.concurrent.Immutable; +/** + * MyReputation is persisted locally and carries the private salt data. In contrast to Reputation which is the public + * data everyone can derive from the blockchain data (hash in opReturn). + */ @Immutable @Value @Slf4j public final class MyReputation implements PersistablePayload, NetworkPayload, BondedAsset { + // Uid is needed to be sure that 2 objects with the same salt are kept separate. private final String uid; private final byte[] salt; - private final transient byte[] hash; // not persisted as it is derived from salt. Stored for caching purpose only. + private final transient byte[] hash; // Not persisted as it is derived from salt. Stored for caching purpose only. public MyReputation(byte[] salt) { this(UUID.randomUUID().toString(), salt); diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationList.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationList.java index e2c1e46d1d1..5e426e999a1 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationList.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationList.java @@ -33,11 +33,11 @@ @EqualsAndHashCode(callSuper = true) public class MyReputationList extends PersistableList { - public MyReputationList(List list) { + private MyReputationList(List list) { super(list); } - public MyReputationList() { + MyReputationList() { super(); } @@ -51,7 +51,7 @@ public PB.PersistableEnvelope toProtoMessage() { return PB.PersistableEnvelope.newBuilder().setMyReputationList(getBuilder()).build(); } - public PB.MyReputationList.Builder getBuilder() { + private PB.MyReputationList.Builder getBuilder() { return PB.MyReputationList.newBuilder() .addAllMyReputation(getList().stream() .map(MyReputation::toProtoMessage) diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java index d9a07eb068e..8d5d39f63d4 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java @@ -31,10 +31,14 @@ import lombok.Getter; import lombok.extern.slf4j.Slf4j; +/** + * Manages the persistence of myReputation objects. + */ @Slf4j public class MyReputationListService implements PersistedDataHost, DaoSetupService { - public interface MyReputationListChangeListener { + @SuppressWarnings("unused") + interface MyReputationListChangeListener { void onListChanged(List list); } @@ -88,10 +92,6 @@ public void start() { // API /////////////////////////////////////////////////////////////////////////////////////////// - public void addListener(MyReputationListChangeListener listener) { - listeners.add(listener); - } - public void addReputation(MyReputation reputation) { if (!myReputationList.contains(reputation)) { myReputationList.add(reputation); @@ -103,6 +103,11 @@ public List getMyReputationList() { return myReputationList.getList(); } + @SuppressWarnings("unused") + public void addListener(MyReputationListChangeListener listener) { + listeners.add(listener); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Private diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java index 1cc5d9c0958..e7394604bed 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/Reputation.java @@ -30,6 +30,8 @@ /** * Reputation objects we found on the blockchain. We only know the hash of it. + * In contrast to MyReputation which represents the object we created and contains the + * private salt data. */ @Immutable @Value diff --git a/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesService.java b/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesRepository.java similarity index 65% rename from core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesService.java rename to core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesRepository.java index 86754757b97..21aab0b53fd 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/role/BondedRolesRepository.java @@ -18,10 +18,10 @@ package bisq.core.dao.governance.bond.role; import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.governance.bond.Bond; -import bisq.core.dao.governance.bond.BondService; +import bisq.core.dao.governance.bond.BondConsensus; +import bisq.core.dao.governance.bond.BondRepository; import bisq.core.dao.state.DaoStateService; -import bisq.core.dao.state.model.governance.BondedRoleType; +import bisq.core.dao.state.model.blockchain.TxOutput; import bisq.core.dao.state.model.governance.Proposal; import bisq.core.dao.state.model.governance.Role; import bisq.core.dao.state.model.governance.RoleProposal; @@ -30,6 +30,7 @@ import javax.inject.Inject; +import java.util.Arrays; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -38,17 +39,17 @@ import lombok.extern.slf4j.Slf4j; /** - * Manages bonded roles if they got accepted by voting. + * Collect bonded roles from the evaluatedProposals from the daoState and provides access to the collection. */ @Slf4j -public class BondedRolesService extends BondService { +public class BondedRolesRepository extends BondRepository { /////////////////////////////////////////////////////////////////////////////////////////// // Constructor /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public BondedRolesService(DaoStateService daoStateService, BsqWalletService bsqWalletService) { + public BondedRolesRepository(DaoStateService daoStateService, BsqWalletService bsqWalletService) { super(daoStateService, bsqWalletService); } @@ -67,12 +68,6 @@ public boolean isMyRole(Role role) { .anyMatch(myWalletTransactionIds::contains); } - public Optional getBondedRoleType(String lockUpTxId) { - return findBondByLockupTxId(lockUpTxId) - .map(Bond::getBondedAsset) - .map(Role::getBondedRoleType); - } - /////////////////////////////////////////////////////////////////////////////////////////// // Protected @@ -88,6 +83,27 @@ protected Stream getBondedAssetStream() { return getBondedRoleProposalStream().map(RoleProposal::getRole); } + @Override + protected void updateBond(BondedRole bond, Role bondedAsset, TxOutput lockupTxOutput) { + // Lets see if we have a lock up tx. + String lockupTxId = lockupTxOutput.getTxId(); + daoStateService.getTx(lockupTxId).ifPresent(lockupTx -> { + byte[] opReturnData = lockupTx.getLastTxOutput().getOpReturnData(); + // We used the hash of th bonded bondedAsset object as our hash in OpReturn of the lock up tx to have a + // unique binding of the tx to the data object. + byte[] hash = BondConsensus.getHashFromOpReturnData(opReturnData); + Optional candidate = findBondedAssetByHash(hash); + if (candidate.isPresent() && bondedAsset.equals(candidate.get())) + applyBondState(daoStateService, bond, lockupTx, lockupTxOutput); + }); + } + + private Optional findBondedAssetByHash(byte[] hash) { + return getBondedAssetStream() + .filter(bondedAsset -> Arrays.equals(bondedAsset.getHash(), hash)) + .findAny(); + } + private Stream getBondedRoleProposalStream() { return daoStateService.getEvaluatedProposalList().stream() .filter(evaluatedProposal -> evaluatedProposal.getProposal() instanceof RoleProposal) diff --git a/core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockService.java b/core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockTxService.java similarity index 79% rename from core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockService.java rename to core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockTxService.java index 4b37e7ebac8..4a9c1bc0e6d 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockTxService.java @@ -35,12 +35,18 @@ import javax.inject.Inject; +import java.util.Optional; import java.util.function.Consumer; import lombok.extern.slf4j.Slf4j; +import static com.google.common.base.Preconditions.checkArgument; + +/** + * Service for publishing the unlock transaction. + */ @Slf4j -public class UnlockService { +public class UnlockTxService { private final WalletsManager walletsManager; private final BsqWalletService bsqWalletService; private final BtcWalletService btcWalletService; @@ -52,23 +58,22 @@ public class UnlockService { /////////////////////////////////////////////////////////////////////////////////////////// @Inject - public UnlockService(WalletsManager walletsManager, - BsqWalletService bsqWalletService, - BtcWalletService btcWalletService, - DaoStateService daoStateService) { + public UnlockTxService(WalletsManager walletsManager, + BsqWalletService bsqWalletService, + BtcWalletService btcWalletService, + DaoStateService daoStateService) { this.walletsManager = walletsManager; this.bsqWalletService = bsqWalletService; this.btcWalletService = btcWalletService; this.daoStateService = daoStateService; } - public void publishUnlockTx(String lockupTxId, Consumer resultHandler, - ExceptionHandler exceptionHandler) { + public void publishUnlockTx(String lockupTxId, Consumer resultHandler, ExceptionHandler exceptionHandler) { try { - TxOutput lockupTxOutput = daoStateService.getLockupTxOutput(lockupTxId).get(); - final Transaction unlockTx = getUnlockTx(lockupTxOutput); - - //noinspection Duplicates + Optional optionalLockupTxOutput = daoStateService.getLockupTxOutput(lockupTxId); + checkArgument(optionalLockupTxOutput.isPresent(), "lockupTxOutput must be present"); + TxOutput lockupTxOutput = optionalLockupTxOutput.get(); + Transaction unlockTx = getUnlockTx(lockupTxOutput); walletsManager.publishAndCommitBsqTx(unlockTx, new TxBroadcaster.Callback() { @Override public void onSuccess(Transaction transaction) { @@ -94,8 +99,7 @@ private Transaction getUnlockTx(TxOutput lockupTxOutput) throws InsufficientMoneyException, WalletException, TransactionVerificationException { Transaction preparedTx = bsqWalletService.getPreparedUnlockTx(lockupTxOutput); Transaction txWithBtcFee = btcWalletService.completePreparedBsqTx(preparedTx, true, null); - final Transaction transaction = bsqWalletService.signTx(txWithBtcFee); - + Transaction transaction = bsqWalletService.signTx(txWithBtcFee); log.info("Unlock tx: " + transaction); return transaction; } diff --git a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java index 4e8b37a25e7..b0fad9b88ae 100644 --- a/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java +++ b/core/src/main/java/bisq/core/dao/governance/voteresult/VoteResultService.java @@ -25,8 +25,7 @@ import bisq.core.dao.governance.blindvote.BlindVoteListService; import bisq.core.dao.governance.blindvote.VoteWithProposalTxId; import bisq.core.dao.governance.blindvote.VoteWithProposalTxIdList; -import bisq.core.dao.governance.bond.ConfiscateBond; -import bisq.core.dao.governance.bond.role.BondedRolesService; +import bisq.core.dao.governance.bond.role.BondedRolesRepository; import bisq.core.dao.governance.merit.MeritConsensus; import bisq.core.dao.governance.period.PeriodService; import bisq.core.dao.governance.proposal.IssuanceProposal; @@ -103,7 +102,7 @@ public class VoteResultService implements DaoStateListener, DaoSetupService { private final PeriodService periodService; private final BallotListService ballotListService; private final BlindVoteListService blindVoteListService; - private final BondedRolesService bondedRolesService; + private final BondedRolesRepository bondedRolesRepository; private final IssuanceService issuanceService; private final AssetService assetService; private final MissingDataRequestService missingDataRequestService; @@ -122,7 +121,7 @@ public VoteResultService(VoteRevealService voteRevealService, PeriodService periodService, BallotListService ballotListService, BlindVoteListService blindVoteListService, - BondedRolesService bondedRolesService, + BondedRolesRepository bondedRolesRepository, IssuanceService issuanceService, AssetService assetService, MissingDataRequestService missingDataRequestService) { @@ -132,7 +131,7 @@ public VoteResultService(VoteRevealService voteRevealService, this.periodService = periodService; this.ballotListService = ballotListService; this.blindVoteListService = blindVoteListService; - this.bondedRolesService = bondedRolesService; + this.bondedRolesRepository = bondedRolesRepository; this.issuanceService = issuanceService; this.assetService = assetService; this.missingDataRequestService = missingDataRequestService; @@ -661,7 +660,7 @@ private void applyConfiscateBond(Set acceptedEvaluatedProposa acceptedEvaluatedProposals.forEach(evaluatedProposal -> { if (evaluatedProposal.getProposal() instanceof ConfiscateBondProposal) { ConfiscateBondProposal confiscateBondProposal = (ConfiscateBondProposal) evaluatedProposal.getProposal(); - daoStateService.confiscateBond(new ConfiscateBond(confiscateBondProposal.getLockupTxId())); + daoStateService.confiscateBond(confiscateBondProposal.getLockupTxId()); StringBuilder sb = new StringBuilder(); sb.append("\n################################################################################\n"); diff --git a/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java b/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java index b0dc5a1e196..75355c5fd56 100644 --- a/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java +++ b/core/src/main/java/bisq/core/dao/node/parser/OpReturnParser.java @@ -19,7 +19,7 @@ import bisq.core.dao.governance.blindvote.BlindVoteConsensus; import bisq.core.dao.governance.bond.BondConsensus; -import bisq.core.dao.governance.bond.lockup.LockupType; +import bisq.core.dao.governance.bond.lockup.LockupReason; import bisq.core.dao.governance.proposal.ProposalConsensus; import bisq.core.dao.governance.voteresult.VoteResultConsensus; import bisq.core.dao.node.parser.exceptions.InvalidParsingConditionException; @@ -107,9 +107,9 @@ static TxOutputType getTxOutputType(TempTxOutput tempTxOutput) { case LOCKUP: if (!BondConsensus.hasOpReturnDataValidLength(opReturnData)) return TxOutputType.INVALID_OUTPUT; - Optional lockupType = BondConsensus.getLockupType(opReturnData); - if (!lockupType.isPresent()) { - log.warn("No lockupType found for lockup tx, opReturnData=" + Utilities.encodeToHex(opReturnData)); + Optional optionalLockupReason = BondConsensus.getLockupReason(opReturnData); + if (!optionalLockupReason.isPresent()) { + log.warn("No lockupReason found for lockup tx, opReturnData=" + Utilities.encodeToHex(opReturnData)); return TxOutputType.INVALID_OUTPUT; } diff --git a/core/src/main/java/bisq/core/dao/state/DaoStateService.java b/core/src/main/java/bisq/core/dao/state/DaoStateService.java index e2fbfb54f39..acee24eb0cc 100644 --- a/core/src/main/java/bisq/core/dao/state/DaoStateService.java +++ b/core/src/main/java/bisq/core/dao/state/DaoStateService.java @@ -19,7 +19,6 @@ import bisq.core.dao.DaoSetupService; import bisq.core.dao.governance.bond.BondConsensus; -import bisq.core.dao.governance.bond.ConfiscateBond; import bisq.core.dao.governance.param.Param; import bisq.core.dao.state.model.DaoState; import bisq.core.dao.state.model.blockchain.Block; @@ -742,8 +741,7 @@ public long getTotalAmountOfUnLockedTxOutputs() { } // Confiscate bond - public void confiscateBond(ConfiscateBond confiscateBond) { - String lockupTxId = confiscateBond.getLockupTxId(); + public void confiscateBond(String lockupTxId) { Optional optionalTxOutput = getLockupTxOutput(lockupTxId); if (optionalTxOutput.isPresent()) { TxOutput lockupTxOutput = optionalTxOutput.get(); diff --git a/core/src/main/java/bisq/core/dao/state/model/governance/BondedRoleType.java b/core/src/main/java/bisq/core/dao/state/model/governance/BondedRoleType.java index 97f0e580fb7..b7381fa621d 100644 --- a/core/src/main/java/bisq/core/dao/state/model/governance/BondedRoleType.java +++ b/core/src/main/java/bisq/core/dao/state/model/governance/BondedRoleType.java @@ -21,10 +21,14 @@ import lombok.Getter; -// Data here must not be changed as it would break backward compatibility! In case we need to change we need to add a new -// entry and maintain the old one. Once all the role holders of an old deprecated role have revoked the role might get removed. -// Add entry to translation file "dao.bond.bondedRoleType...." +/** + * Data here must not be changed as it would break backward compatibility! In case we need to change we need to add a + * new entry and maintain the old one. Once all the role holders of an old deprecated role have revoked the + * role might get removed. + * + * Add entry to translation file "dao.bond.bondedRoleType...." + */ public enum BondedRoleType { // admins GITHUB_ADMIN(50_000, 60, "https://github.com/bisq-network/roles/issues/16", true), diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index fef82a49aa1..603036be595 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -1339,9 +1339,9 @@ dao.bonding.info=Lockup Tx ID: {0} / {1} dao.bonding.reputation.salt.info=Salt: {0} # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.GITHUB_ADMIN=Github admin diff --git a/core/src/main/resources/i18n/displayStrings_de.properties b/core/src/main/resources/i18n/displayStrings_de.properties index 824d0390208..e764e977d71 100644 --- a/core/src/main/resources/i18n/displayStrings_de.properties +++ b/core/src/main/resources/i18n/displayStrings_de.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Gesperrte Gelder dao.bonding.dashboard.unlockingAmount=Entsperre Gelder (Warten Sie bis die Sperrzeit vorbei ist): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Gekoppelte Rolle +dao.bond.lockupReason.BONDED_ROLE=Gekoppelte Rolle # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Gekoppeltes Ansehen +dao.bond.lockupReason.REPUTATION=Gekoppeltes Ansehen # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Vermittler # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_el.properties b/core/src/main/resources/i18n/displayStrings_el.properties index b12d93874fb..afd3ec597f0 100644 --- a/core/src/main/resources/i18n/displayStrings_el.properties +++ b/core/src/main/resources/i18n/displayStrings_el.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Lockup funds: dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_es.properties b/core/src/main/resources/i18n/displayStrings_es.properties index af4b5862eff..6bcc7307f1e 100644 --- a/core/src/main/resources/i18n/displayStrings_es.properties +++ b/core/src/main/resources/i18n/displayStrings_es.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Lockup funds: dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_fa.properties b/core/src/main/resources/i18n/displayStrings_fa.properties index b04ad168199..7449a1895b5 100644 --- a/core/src/main/resources/i18n/displayStrings_fa.properties +++ b/core/src/main/resources/i18n/displayStrings_fa.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Lockup funds: dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_hu.properties b/core/src/main/resources/i18n/displayStrings_hu.properties index 5d0f417f341..54fd678fb20 100644 --- a/core/src/main/resources/i18n/displayStrings_hu.properties +++ b/core/src/main/resources/i18n/displayStrings_hu.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Lockup funds: dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_pt.properties b/core/src/main/resources/i18n/displayStrings_pt.properties index b881a6def40..d82f3316b21 100644 --- a/core/src/main/resources/i18n/displayStrings_pt.properties +++ b/core/src/main/resources/i18n/displayStrings_pt.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Lockup funds: dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_ro.properties b/core/src/main/resources/i18n/displayStrings_ro.properties index 9e5439f20fe..45d61c69833 100644 --- a/core/src/main/resources/i18n/displayStrings_ro.properties +++ b/core/src/main/resources/i18n/displayStrings_ro.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Lockup funds: dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_ru.properties b/core/src/main/resources/i18n/displayStrings_ru.properties index 7871b5d3ad5..3260caafe5c 100644 --- a/core/src/main/resources/i18n/displayStrings_ru.properties +++ b/core/src/main/resources/i18n/displayStrings_ru.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Запереть средства: dao.bonding.dashboard.unlockingAmount=Разблокировка средств (дождитесь окончания времени блокировки): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Обеспеченная роль +dao.bond.lockupReason.BONDED_ROLE=Обеспеченная роль # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Обеспеченная репутация +dao.bond.lockupReason.REPUTATION=Обеспеченная репутация # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Арбитр # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_sr.properties b/core/src/main/resources/i18n/displayStrings_sr.properties index 74732beef2c..235d12c4a41 100644 --- a/core/src/main/resources/i18n/displayStrings_sr.properties +++ b/core/src/main/resources/i18n/displayStrings_sr.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Lockup funds: dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_th.properties b/core/src/main/resources/i18n/displayStrings_th.properties index e8370961009..c4be425891a 100644 --- a/core/src/main/resources/i18n/displayStrings_th.properties +++ b/core/src/main/resources/i18n/displayStrings_th.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Lockup funds: dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_vi.properties b/core/src/main/resources/i18n/displayStrings_vi.properties index b70aa050885..207dcc5cef1 100644 --- a/core/src/main/resources/i18n/displayStrings_vi.properties +++ b/core/src/main/resources/i18n/displayStrings_vi.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Lockup funds: dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator # suppress inspection "UnusedProperty" diff --git a/core/src/main/resources/i18n/displayStrings_zh.properties b/core/src/main/resources/i18n/displayStrings_zh.properties index a7d1865639f..a85664b837b 100644 --- a/core/src/main/resources/i18n/displayStrings_zh.properties +++ b/core/src/main/resources/i18n/displayStrings_zh.properties @@ -1143,9 +1143,9 @@ dao.bonding.dashboard.lockupAmount=Lockup funds: dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" -dao.bond.lockupType.BONDED_ROLE=Bonded role +dao.bond.lockupReason.BONDED_ROLE=Bonded role # suppress inspection "UnusedProperty" -dao.bond.lockupType.REPUTATION=Bonded reputation +dao.bond.lockupReason.REPUTATION=Bonded reputation # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator # suppress inspection "UnusedProperty" diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java index 9aa2bdc6c75..5f1e927ffa4 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java @@ -26,10 +26,10 @@ import bisq.core.btc.setup.WalletsSetup; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.lockup.LockupType; +import bisq.core.dao.governance.bond.lockup.LockupReason; import bisq.core.dao.governance.bond.reputation.MyReputation; import bisq.core.dao.governance.bond.reputation.MyReputationListService; -import bisq.core.dao.governance.bond.role.BondedRolesService; +import bisq.core.dao.governance.bond.role.BondedRolesRepository; import bisq.core.dao.state.model.blockchain.TxOutput; import bisq.core.dao.state.model.governance.BondedRoleType; import bisq.core.dao.state.model.governance.Role; @@ -56,7 +56,7 @@ public class BondingViewUtils { private final P2PService p2PService; private final MyReputationListService myReputationListService; - private final BondedRolesService bondedRolesService; + private final BondedRolesRepository bondedRolesRepository; private final WalletsSetup walletsSetup; private final DaoFacade daoFacade; private final Navigation navigation; @@ -65,14 +65,14 @@ public class BondingViewUtils { @Inject public BondingViewUtils(P2PService p2PService, MyReputationListService myReputationListService, - BondedRolesService bondedRolesService, + BondedRolesRepository bondedRolesRepository, WalletsSetup walletsSetup, DaoFacade daoFacade, Navigation navigation, BsqFormatter bsqFormatter) { this.p2PService = p2PService; this.myReputationListService = myReputationListService; - this.bondedRolesService = bondedRolesService; + this.bondedRolesRepository = bondedRolesRepository; this.walletsSetup = walletsSetup; this.daoFacade = daoFacade; this.navigation = navigation; @@ -83,8 +83,8 @@ public void lockupBondForBondedRole(Role role, Consumer resultHandler) { BondedRoleType bondedRoleType = role.getBondedRoleType(); Coin lockupAmount = Coin.valueOf(bondedRoleType.getRequiredBond()); int lockupTime = bondedRoleType.getUnlockTimeInBlocks(); - if (!bondedRolesService.wasBondedAssetAlreadyBonded(role)) { - lockupBond(role.getHash(), lockupAmount, lockupTime, LockupType.BONDED_ROLE, resultHandler); + if (!bondedRolesRepository.isBondedAssetAlreadyInBond(role)) { + lockupBond(role.getHash(), lockupAmount, lockupTime, LockupReason.BONDED_ROLE, resultHandler); } else { handleError(new RuntimeException("The role has been used already for a lockup tx.")); } @@ -92,11 +92,11 @@ public void lockupBondForBondedRole(Role role, Consumer resultHandler) { public void lockupBondForReputation(Coin lockupAmount, int lockupTime, byte[] salt, Consumer resultHandler) { MyReputation myReputation = new MyReputation(salt); - lockupBond(myReputation.getHash(), lockupAmount, lockupTime, LockupType.REPUTATION, resultHandler); + lockupBond(myReputation.getHash(), lockupAmount, lockupTime, LockupReason.REPUTATION, resultHandler); myReputationListService.addReputation(myReputation); } - private void lockupBond(byte[] hash, Coin lockupAmount, int lockupTime, LockupType lockupType, + private void lockupBond(byte[] hash, Coin lockupAmount, int lockupTime, LockupReason lockupReason, Consumer resultHandler) { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { if (!DevEnv.isDevMode()) { @@ -106,21 +106,21 @@ private void lockupBond(byte[] hash, Coin lockupAmount, int lockupTime, LockupTy lockupTime )) .actionButtonText(Res.get("shared.yes")) - .onAction(() -> publishLockupTx(hash, lockupAmount, lockupTime, lockupType, resultHandler)) + .onAction(() -> publishLockupTx(hash, lockupAmount, lockupTime, lockupReason, resultHandler)) .closeButtonText(Res.get("shared.cancel")) .show(); } else { - publishLockupTx(hash, lockupAmount, lockupTime, lockupType, resultHandler); + publishLockupTx(hash, lockupAmount, lockupTime, lockupReason, resultHandler); } } else { GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup); } } - private void publishLockupTx(byte[] hash, Coin lockupAmount, int lockupTime, LockupType lockupType, Consumer resultHandler) { + private void publishLockupTx(byte[] hash, Coin lockupAmount, int lockupTime, LockupReason lockupReason, Consumer resultHandler) { daoFacade.publishLockupTx(lockupAmount, lockupTime, - lockupType, + lockupReason, hash, txId -> { if (!DevEnv.isDevMode()) diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java index 9911b155569..99d9e1e5c68 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java @@ -22,7 +22,7 @@ import bisq.core.dao.DaoFacade; import bisq.core.dao.governance.bond.Bond; import bisq.core.dao.governance.bond.role.BondedRole; -import bisq.core.dao.governance.bond.role.BondedRolesService; +import bisq.core.dao.governance.bond.role.BondedRolesRepository; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.model.blockchain.Block; import bisq.core.locale.Res; @@ -48,7 +48,7 @@ class BondListItem implements DaoStateListener { private final Bond bond; private final DaoFacade daoFacade; - private final BondedRolesService bondedRolesService; + private final BondedRolesRepository bondedRolesRepository; private final BondingViewUtils bondingViewUtils; private final BsqFormatter bsqFormatter; private final String bondType; @@ -64,12 +64,12 @@ class BondListItem implements DaoStateListener { BondListItem(Bond bond, DaoFacade daoFacade, - BondedRolesService bondedRolesService, + BondedRolesRepository bondedRolesRepository, BondingViewUtils bondingViewUtils, BsqFormatter bsqFormatter) { this.bond = bond; this.daoFacade = daoFacade; - this.bondedRolesService = bondedRolesService; + this.bondedRolesRepository = bondedRolesRepository; this.bondingViewUtils = bondingViewUtils; this.bsqFormatter = bsqFormatter; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java index 4d44297a666..c0095175258 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java @@ -28,7 +28,7 @@ import bisq.core.btc.listeners.BsqBalanceListener; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.role.BondedRolesService; +import bisq.core.dao.governance.bond.role.BondedRolesRepository; import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.model.blockchain.Block; import bisq.core.locale.Res; @@ -75,7 +75,7 @@ public class BondsView extends ActivatableView implements BsqBal private final BsqFormatter bsqFormatter; private final BsqValidator bsqValidator; private final BondingViewUtils bondingViewUtils; - private final BondedRolesService bondedRolesService; + private final BondedRolesRepository bondedRolesRepository; private final DaoFacade daoFacade; private final Preferences preferences; @@ -97,14 +97,14 @@ private BondsView(BsqWalletService bsqWalletService, BsqFormatter bsqFormatter, BsqValidator bsqValidator, BondingViewUtils bondingViewUtils, - BondedRolesService bondedRolesService, + BondedRolesRepository bondedRolesRepository, DaoFacade daoFacade, Preferences preferences) { this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; this.bsqValidator = bsqValidator; this.bondingViewUtils = bondingViewUtils; - this.bondedRolesService = bondedRolesService; + this.bondedRolesRepository = bondedRolesRepository; this.daoFacade = daoFacade; this.preferences = preferences; } @@ -208,7 +208,7 @@ private void updateList() { .map(bond -> { return new BondListItem(bond, daoFacade, - bondedRolesService, + bondedRolesRepository, bondingViewUtils, bsqFormatter); }) From ceee3562afe5ef783c8056f1e296d9c316b4c4fc Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 6 Nov 2018 19:56:11 -0500 Subject: [PATCH 23/27] Remove onTxMalleability methods --- .../dao/governance/blindvote/MyBlindVoteListService.java | 8 -------- .../core/dao/governance/bond/lockup/LockupTxService.java | 6 ------ .../core/dao/governance/bond/unlock/UnlockTxService.java | 6 ------ .../dao/governance/proposal/MyProposalListService.java | 6 ------ .../dao/governance/votereveal/VoteRevealService.java | 9 --------- .../bisq/desktop/main/dao/wallet/send/BsqSendView.java | 7 ------- 6 files changed, 42 deletions(-) diff --git a/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java b/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java index b9b55d40b77..36461621bf3 100644 --- a/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java +++ b/core/src/main/java/bisq/core/dao/governance/blindvote/MyBlindVoteListService.java @@ -20,7 +20,6 @@ import bisq.core.app.BisqEnvironment; import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.TxBroadcastException; -import bisq.core.btc.exceptions.TxMalleabilityException; import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; @@ -338,13 +337,6 @@ public void onSuccess(Transaction transaction) { resultHandler.handleResult(); } - @Override - public void onTxMalleability(TxMalleabilityException exception) { - // TODO handle - // We need to be sure that in case of a failed tx the locked stake gets unlocked! - exceptionHandler.handleException(exception); - } - @Override public void onFailure(TxBroadcastException exception) { // TODO handle diff --git a/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupTxService.java b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupTxService.java index d842f4c028c..681efb756b5 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupTxService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/lockup/LockupTxService.java @@ -19,7 +19,6 @@ import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.TxBroadcastException; -import bisq.core.btc.exceptions.TxMalleabilityException; import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; @@ -80,11 +79,6 @@ public void onSuccess(Transaction transaction) { resultHandler.accept(transaction.getHashAsString()); } - @Override - public void onTxMalleability(TxMalleabilityException exception) { - exceptionHandler.handleException(exception); - } - @Override public void onFailure(TxBroadcastException exception) { exceptionHandler.handleException(exception); diff --git a/core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockTxService.java b/core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockTxService.java index 4a9c1bc0e6d..933081bced3 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockTxService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/unlock/UnlockTxService.java @@ -19,7 +19,6 @@ import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.TxBroadcastException; -import bisq.core.btc.exceptions.TxMalleabilityException; import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; @@ -80,11 +79,6 @@ public void onSuccess(Transaction transaction) { resultHandler.accept(transaction.getHashAsString()); } - @Override - public void onTxMalleability(TxMalleabilityException exception) { - exceptionHandler.handleException(exception); - } - @Override public void onFailure(TxBroadcastException exception) { exceptionHandler.handleException(exception); diff --git a/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java b/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java index 98ddd3a7396..b59b489d6f4 100644 --- a/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java +++ b/core/src/main/java/bisq/core/dao/governance/proposal/MyProposalListService.java @@ -19,7 +19,6 @@ import bisq.core.app.BisqEnvironment; import bisq.core.btc.exceptions.TxBroadcastException; -import bisq.core.btc.exceptions.TxMalleabilityException; import bisq.core.btc.wallet.TxBroadcaster; import bisq.core.btc.wallet.WalletsManager; import bisq.core.dao.governance.period.PeriodService; @@ -153,11 +152,6 @@ public void onSuccess(Transaction transaction) { resultHandler.handleResult(); } - @Override - public void onTxMalleability(TxMalleabilityException exception) { - errorMessageHandler.handleErrorMessage(exception.getMessage()); - } - @Override public void onFailure(TxBroadcastException exception) { errorMessageHandler.handleErrorMessage(exception.getMessage()); diff --git a/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java b/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java index 4dba0cff0db..b2b1ea00615 100644 --- a/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java +++ b/core/src/main/java/bisq/core/dao/governance/votereveal/VoteRevealService.java @@ -19,7 +19,6 @@ import bisq.core.btc.exceptions.TransactionVerificationException; import bisq.core.btc.exceptions.TxBroadcastException; -import bisq.core.btc.exceptions.TxMalleabilityException; import bisq.core.btc.exceptions.WalletException; import bisq.core.btc.wallet.BsqWalletService; import bisq.core.btc.wallet.BtcWalletService; @@ -250,14 +249,6 @@ public void onSuccess(Transaction transaction) { log.info("voteRevealTx successfully broadcasted."); } - @Override - public void onTxMalleability(TxMalleabilityException exception) { - log.error(exception.toString()); - // TODO handle - voteRevealExceptions.add(new VoteRevealException("Publishing of voteRevealTx failed.", - exception, voteRevealTx)); - } - @Override public void onFailure(TxBroadcastException exception) { log.error(exception.toString()); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java b/desktop/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java index 68af65f4a58..a10ec5fc6c7 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/wallet/send/BsqSendView.java @@ -34,7 +34,6 @@ import bisq.desktop.util.validation.BtcValidator; import bisq.core.btc.exceptions.TxBroadcastException; -import bisq.core.btc.exceptions.TxMalleabilityException; import bisq.core.btc.listeners.BsqBalanceListener; import bisq.core.btc.setup.WalletsSetup; import bisq.core.btc.wallet.BsqWalletService; @@ -349,12 +348,6 @@ public void onSuccess(Transaction transaction) { log.debug("Successfully sent tx with id " + txWithBtcFee.getHashAsString()); } - @Override - public void onTxMalleability(TxMalleabilityException exception) { - //TODO handle - new Popup<>().warning(exception.toString()); - } - @Override public void onFailure(TxBroadcastException exception) { //TODO handle From 698d01d4be33e57cfb50d10ed6c07a0c954f3bad Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 6 Nov 2018 22:24:25 -0500 Subject: [PATCH 24/27] Cleanup bond views --- .../main/java/bisq/core/dao/DaoFacade.java | 16 +- .../dao/governance/bond/BondRepository.java | 67 ++--- .../BondedReputationRepository.java | 29 +- .../MyBondedReputationRepository.java | 38 ++- .../bond/reputation/MyReputation.java | 3 + .../reputation/MyReputationListService.java | 16 -- .../desktop/main/dao/bonding/BondingView.java | 15 +- .../main/dao/bonding/bonds/BondListItem.java | 79 +----- .../main/dao/bonding/bonds/BondsView.java | 170 +++--------- .../MyBondedReputationListItem.java | 128 --------- .../reputation/MyReputationListItem.java | 68 +++++ ...utationView.fxml => MyReputationView.fxml} | 6 +- ...utationView.java => MyReputationView.java} | 246 ++++++----------- .../bonding/roles/BondedRolesListItem.java | 145 ---------- ...TypeWindow.java => RoleDetailsWindow.java} | 6 +- .../main/dao/bonding/roles/RolesListItem.java | 66 +++++ .../{BondedRolesView.fxml => RolesView.fxml} | 2 +- .../{BondedRolesView.java => RolesView.java} | 260 +++++------------- .../dao/governance/make/MakeProposalView.java | 8 +- .../governance/proposals/ProposalsView.java | 8 +- .../java/bisq/desktop/util/FormBuilder.java | 16 ++ .../main/java/bisq/desktop/util/GUIUtil.java | 5 + 22 files changed, 484 insertions(+), 913 deletions(-) delete mode 100644 desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java create mode 100644 desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationListItem.java rename desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/{MyBondedReputationView.fxml => MyReputationView.fxml} (86%) rename desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/{MyBondedReputationView.java => MyReputationView.java} (66%) delete mode 100644 desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java rename desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/{BondedRoleTypeWindow.java => RoleDetailsWindow.java} (94%) create mode 100644 desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesListItem.java rename desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/{BondedRolesView.fxml => RolesView.fxml} (97%) rename desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/{BondedRolesView.java => RolesView.java} (51%) diff --git a/core/src/main/java/bisq/core/dao/DaoFacade.java b/core/src/main/java/bisq/core/dao/DaoFacade.java index 428d4799653..5ea20900cfc 100644 --- a/core/src/main/java/bisq/core/dao/DaoFacade.java +++ b/core/src/main/java/bisq/core/dao/DaoFacade.java @@ -27,7 +27,6 @@ import bisq.core.dao.governance.bond.Bond; import bisq.core.dao.governance.bond.lockup.LockupReason; import bisq.core.dao.governance.bond.lockup.LockupTxService; -import bisq.core.dao.governance.bond.reputation.BondedReputation; import bisq.core.dao.governance.bond.reputation.BondedReputationRepository; import bisq.core.dao.governance.bond.reputation.MyBondedReputation; import bisq.core.dao.governance.bond.reputation.MyBondedReputationRepository; @@ -291,7 +290,7 @@ public ProposalWithTransaction getRemoveAssetProposalWithTransaction(String name return removeAssetProposalFactory.createProposalWithTransaction(name, link, asset); } - public List getBondedRoles() { + public ObservableList getBondedRoles() { return bondedRolesRepository.getBonds(); } @@ -518,19 +517,14 @@ public Optional getLockTime(String txId) { return daoStateService.getLockTime(txId); } - public List getActiveBondedRoles() { - return bondedRolesRepository.getActiveBonds(); - } public List getAllBonds() { - List bondedReputations = bondedReputationRepository.getBonds(); - List bondedRoles = bondedRolesRepository.getBonds(); - List bonds = new ArrayList<>(bondedReputations); - bonds.addAll(bondedRoles); + List bonds = new ArrayList<>(bondedReputationRepository.getBonds()); + bonds.addAll(bondedRolesRepository.getBonds()); return bonds; } - public List getMyBondedReputations() { + public ObservableList getMyBondedReputations() { return myBondedReputationRepository.getMyBondedReputations(); } @@ -665,6 +659,6 @@ public boolean isMyRole(Role role) { } public Optional getBondByLockupTxId(String lockupTxId) { - return getAllBonds().stream().filter(e -> e.getLockupTxId().equals(lockupTxId)).findAny(); + return getAllBonds().stream().filter(e -> lockupTxId.equals(e.getLockupTxId())).findAny(); } } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/BondRepository.java b/core/src/main/java/bisq/core/dao/governance/bond/BondRepository.java index 1e9f51f290b..12d4e65f8ea 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/BondRepository.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/BondRepository.java @@ -34,22 +34,26 @@ import javax.inject.Inject; -import java.util.ArrayList; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; + import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; import java.util.stream.Stream; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; /** * Collect bonds and bond asset data from other sources and provides access to the collection. + * Gets updated after a new block is parsed or at bsqWallet transaction change to detect also state changes by + * unconfirmed txs. */ @Slf4j -public abstract class BondRepository implements DaoStateListener, DaoSetupService { +public abstract class BondRepository implements DaoSetupService { /////////////////////////////////////////////////////////////////////////////////////////// // Static @@ -129,6 +133,8 @@ public static boolean isConfiscated(Bond bond, DaoStateService daoStateService) // This map is just for convenience. The data which are used to fill the map are stored in the DaoState (role, txs). protected final Map bondByUidMap = new HashMap<>(); + @Getter + protected final ObservableList bonds = FXCollections.observableArrayList(); /////////////////////////////////////////////////////////////////////////////////////////// @@ -139,8 +145,6 @@ public static boolean isConfiscated(Bond bond, DaoStateService daoStateService) public BondRepository(DaoStateService daoStateService, BsqWalletService bsqWalletService) { this.daoStateService = daoStateService; this.bsqWalletService = bsqWalletService; - - daoStateService.addBsqStateListener(this); } /////////////////////////////////////////////////////////////////////////////////////////// @@ -149,30 +153,26 @@ public BondRepository(DaoStateService daoStateService, BsqWalletService bsqWalle @Override public void addListeners() { + daoStateService.addBsqStateListener(new DaoStateListener() { + @Override + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onParseTxsComplete(Block block) { + update(); + } + + @Override + public void onParseBlockChainComplete() { + } + }); + bsqWalletService.getWalletTransactions().addListener((ListChangeListener) c -> update()); } @Override public void start() { - updateMap(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // DaoStateListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onNewBlockHeight(int blockHeight) { - } - - @Override - public void onParseTxsComplete(Block block) { - // TODO optimize to not re-write the whole map at each block - updateMap(); - } - - @Override - public void onParseBlockChainComplete() { + update(); } @@ -180,20 +180,9 @@ public void onParseBlockChainComplete() { // API /////////////////////////////////////////////////////////////////////////////////////////// - public List getBonds() { - return new ArrayList<>(bondByUidMap.values()); - } - - public List getActiveBonds() { - return bondByUidMap.values().stream() - .filter(T::isActive) - .collect(Collectors.toList()); - } - public boolean isBondedAssetAlreadyInBond(R bondedAsset) { boolean contains = bondByUidMap.containsKey(bondedAsset.getUid()); return contains && bondByUidMap.get(bondedAsset.getUid()).getLockupTxId() != null; - } @@ -207,7 +196,7 @@ public boolean isBondedAssetAlreadyInBond(R bondedAsset) { abstract protected Stream getBondedAssetStream(); - protected void updateMap() { + protected void update() { getBondedAssetStream().forEach(bondedAsset -> { String uid = bondedAsset.getUid(); bondByUidMap.putIfAbsent(uid, createBond(bondedAsset)); @@ -220,6 +209,8 @@ protected void updateMap() { updateBondStateFromUnconfirmedLockupTxs(); updateBondStateFromUnconfirmedUnlockTxs(); + + bonds.setAll(bondByUidMap.values()); } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationRepository.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationRepository.java index c5537c45ad7..08fc43739a1 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationRepository.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/BondedReputationRepository.java @@ -21,12 +21,15 @@ import bisq.core.dao.governance.bond.Bond; import bisq.core.dao.governance.bond.BondConsensus; import bisq.core.dao.governance.bond.BondRepository; +import bisq.core.dao.governance.bond.role.BondedRole; import bisq.core.dao.governance.bond.role.BondedRolesRepository; import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.model.blockchain.TxOutput; import javax.inject.Inject; +import javafx.collections.ListChangeListener; + import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -38,6 +41,8 @@ /** * Collect bonded reputations from the daoState blockchain data excluding bonded roles * and provides access to the collection. + * Gets updated after a new block is parsed or at bsqWallet transaction change to detect also state changes by + * unconfirmed txs. */ @Slf4j public class BondedReputationRepository extends BondRepository { @@ -55,6 +60,25 @@ public BondedReputationRepository(DaoStateService daoStateService, BsqWalletServ this.bondedRolesRepository = bondedRolesRepository; } + /////////////////////////////////////////////////////////////////////////////////////////// + // DaoSetupService + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public void addListeners() { + super.addListeners(); + + // As event listeners do not have a deterministic ordering of callback we need to ensure + // that we get updated our data after the bondedRolesRepository was updated. + // The update gets triggered by daoState or wallet changes. It could be that we get triggered first the + // listeners and update our data with stale data from bondedRolesRepository. After that the bondedRolesRepository + // gets triggered the listeners and we would miss the current state if we would not listen here as well on the + // bond list. + bondedRolesRepository.getBonds().addListener((ListChangeListener) c -> { + update(); + }); + } + /////////////////////////////////////////////////////////////////////////////////////////// // Protected @@ -71,9 +95,10 @@ protected Stream getBondedAssetStream() { } @Override - protected void updateMap() { + protected void update() { bondByUidMap.clear(); getBondedReputationStream().forEach(bondedReputation -> bondByUidMap.put(bondedReputation.getBondedAsset().getUid(), bondedReputation)); + bonds.setAll(bondByUidMap.values()); } private Stream getBondedReputationStream() { @@ -97,7 +122,7 @@ private Stream getBondedReputationStream() { } private Stream getLockupTxOutputsForBondedReputation() { - // We exclude bonded roles, so we store those ina lookup set. + // We exclude bonded roles, so we store those in a lookup set. Set bondedRolesLockupTxIdSet = bondedRolesRepository.getBonds().stream().map(Bond::getLockupTxId).collect(Collectors.toSet()); return daoStateService.getLockupTxOutputs().stream() .filter(e -> !bondedRolesLockupTxIdSet.contains(e.getTxId())); diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationRepository.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationRepository.java index 871cac26096..cd7b6519cd9 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationRepository.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyBondedReputationRepository.java @@ -22,28 +22,41 @@ import bisq.core.dao.governance.bond.BondConsensus; import bisq.core.dao.governance.bond.BondRepository; import bisq.core.dao.governance.bond.BondState; +import bisq.core.dao.state.DaoStateListener; import bisq.core.dao.state.DaoStateService; +import bisq.core.dao.state.model.blockchain.Block; + +import org.bitcoinj.core.Transaction; import javax.inject.Inject; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; + import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; /** * Collect MyBondedReputations from the myReputationListService and provides access to the collection. + * Gets updated after a new block is parsed or at bsqWallet transaction change to detect also state changes by + * unconfirmed txs. */ @Slf4j +//TODO maybe extend BondRepository as well? public class MyBondedReputationRepository implements DaoSetupService { private final DaoStateService daoStateService; private final BsqWalletService bsqWalletService; private final MyReputationListService myReputationListService; + @Getter + private final ObservableList myBondedReputations = FXCollections.observableArrayList(); /////////////////////////////////////////////////////////////////////////////////////////// @@ -66,6 +79,21 @@ public MyBondedReputationRepository(DaoStateService daoStateService, @Override public void addListeners() { + daoStateService.addBsqStateListener(new DaoStateListener() { + @Override + public void onNewBlockHeight(int blockHeight) { + } + + @Override + public void onParseTxsComplete(Block block) { + update(); + } + + @Override + public void onParseBlockChainComplete() { + } + }); + bsqWalletService.getWalletTransactions().addListener((ListChangeListener) c -> update()); } @Override @@ -74,10 +102,10 @@ public void start() { /////////////////////////////////////////////////////////////////////////////////////////// - // API + // Private /////////////////////////////////////////////////////////////////////////////////////////// - public List getMyBondedReputations() { + private void update() { // It can be that the same salt/hash is in several lockupTxs, so we use the bondByLockupTxIdMap to eliminate // duplicates by the collection algorithm. Map bondByLockupTxIdMap = new HashMap<>(); @@ -85,7 +113,7 @@ public List getMyBondedReputations() { .flatMap(this::getMyBondedReputation) .forEach(e -> bondByLockupTxIdMap.putIfAbsent(e.getLockupTxId(), e)); - return bondByLockupTxIdMap.values().stream() + myBondedReputations.setAll(bondByLockupTxIdMap.values().stream() .peek(myBondedReputation -> { if (BondRepository.isConfiscated(myBondedReputation, daoStateService)) { myBondedReputation.setBondState(BondState.CONFISCATED); @@ -101,7 +129,7 @@ public List getMyBondedReputations() { } } }) - .collect(Collectors.toList()); + .collect(Collectors.toList())); } private Stream getMyBondedReputation(MyReputation myReputation) { diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java index ac40f6cebee..f0a7eee04be 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputation.java @@ -37,6 +37,8 @@ import javax.annotation.concurrent.Immutable; +import static com.google.common.base.Preconditions.checkArgument; + /** * MyReputation is persisted locally and carries the private salt data. In contrast to Reputation which is the public * data everyone can derive from the blockchain data (hash in opReturn). @@ -52,6 +54,7 @@ public final class MyReputation implements PersistablePayload, NetworkPayload, B public MyReputation(byte[] salt) { this(UUID.randomUUID().toString(), salt); + checkArgument(salt.length <= 20, "salt must not be longer then 20 bytes"); } diff --git a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java index 8d5d39f63d4..198aeb5e787 100644 --- a/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java +++ b/core/src/main/java/bisq/core/dao/governance/bond/reputation/MyReputationListService.java @@ -26,9 +26,7 @@ import javax.inject.Inject; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; -import lombok.Getter; import lombok.extern.slf4j.Slf4j; /** @@ -37,17 +35,9 @@ @Slf4j public class MyReputationListService implements PersistedDataHost, DaoSetupService { - @SuppressWarnings("unused") - interface MyReputationListChangeListener { - void onListChanged(List list); - } - private final Storage storage; private final MyReputationList myReputationList = new MyReputationList(); - @Getter - private final List listeners = new CopyOnWriteArrayList<>(); - /////////////////////////////////////////////////////////////////////////////////////////// // Constructor @@ -70,7 +60,6 @@ public void readPersisted() { if (persisted != null) { myReputationList.clear(); myReputationList.addAll(persisted.getList()); - listeners.forEach(l -> l.onListChanged(myReputationList.getList())); } } } @@ -103,11 +92,6 @@ public List getMyReputationList() { return myReputationList.getList(); } - @SuppressWarnings("unused") - public void addListener(MyReputationListChangeListener listener) { - listeners.add(listener); - } - /////////////////////////////////////////////////////////////////////////////////////////// // Private diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index d93225ee445..d6c74c11d74 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -29,8 +29,8 @@ import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.bonding.bonds.BondsView; import bisq.desktop.main.dao.bonding.dashboard.BondingDashboardView; -import bisq.desktop.main.dao.bonding.reputation.MyBondedReputationView; -import bisq.desktop.main.dao.bonding.roles.BondedRolesView; +import bisq.desktop.main.dao.bonding.reputation.MyReputationView; +import bisq.desktop.main.dao.bonding.roles.RolesView; import bisq.core.locale.Res; @@ -84,9 +84,9 @@ public void initialize() { dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), BondingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); bondedRoles = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.bondedRoles"), - BondedRolesView.class, AwesomeIcon.SHIELD, baseNavPath); + RolesView.class, AwesomeIcon.SHIELD, baseNavPath); reputation = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.reputation"), - MyBondedReputationView.class, AwesomeIcon.LOCK, baseNavPath); + MyReputationView.class, AwesomeIcon.LOCK, baseNavPath); bonds = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.bonds"), BondsView.class, AwesomeIcon.UNLOCK, baseNavPath); @@ -105,7 +105,7 @@ protected void activate() { if (viewPath.size() == 3 && viewPath.indexOf(BondingView.class) == 2 || viewPath.size() == 2 && viewPath.indexOf(DaoView.class) == 1) { if (selectedViewClass == null) - selectedViewClass = BondedRolesView.class; + selectedViewClass = RolesView.class; loadView(selectedViewClass); @@ -115,6 +115,7 @@ protected void activate() { } } + @SuppressWarnings("Duplicates") @Override protected void deactivate() { navigation.removeListener(listener); @@ -130,8 +131,8 @@ private void loadView(Class viewClass) { content.getChildren().setAll(view.getRoot()); if (view instanceof BondingDashboardView) dashboard.setSelected(true); - else if (view instanceof BondedRolesView) bondedRoles.setSelected(true); - else if (view instanceof MyBondedReputationView) reputation.setSelected(true); + else if (view instanceof RolesView) bondedRoles.setSelected(true); + else if (view instanceof MyReputationView) reputation.setSelected(true); else if (view instanceof BondsView) bonds.setSelected(true); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java index 99d9e1e5c68..235f19322a0 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondListItem.java @@ -17,14 +17,9 @@ package bisq.desktop.main.dao.bonding.bonds; -import bisq.desktop.main.dao.bonding.BondingViewUtils; - -import bisq.core.dao.DaoFacade; import bisq.core.dao.governance.bond.Bond; +import bisq.core.dao.governance.bond.BondState; import bisq.core.dao.governance.bond.role.BondedRole; -import bisq.core.dao.governance.bond.role.BondedRolesRepository; -import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.model.blockchain.Block; import bisq.core.locale.Res; import bisq.core.util.BsqFormatter; @@ -32,47 +27,27 @@ import org.bitcoinj.core.Coin; -import javafx.scene.control.Button; -import javafx.scene.control.Label; - import java.util.Date; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.Getter; +import lombok.Value; import lombok.extern.slf4j.Slf4j; -@EqualsAndHashCode -@Data +@Value @Slf4j -class BondListItem implements DaoStateListener { +class BondListItem { private final Bond bond; - private final DaoFacade daoFacade; - private final BondedRolesRepository bondedRolesRepository; - private final BondingViewUtils bondingViewUtils; - private final BsqFormatter bsqFormatter; private final String bondType; - private final String txId; + private final String lockupTxId; private final String amount; - private final String lockupDate; + private final String lockupDateString; private final String lockTime; - private final Label stateLabel; private final String bondDetails; + private final BondState bondState; + private final String bondStateString; + private final Date lockupDate; - @Getter - private Button button; - - BondListItem(Bond bond, - DaoFacade daoFacade, - BondedRolesRepository bondedRolesRepository, - BondingViewUtils bondingViewUtils, - BsqFormatter bsqFormatter) { + BondListItem(Bond bond, BsqFormatter bsqFormatter) { this.bond = bond; - this.daoFacade = daoFacade; - this.bondedRolesRepository = bondedRolesRepository; - this.bondingViewUtils = bondingViewUtils; - this.bsqFormatter = bsqFormatter; - amount = bsqFormatter.formatCoin(Coin.valueOf(bond.getAmount())); lockTime = Integer.toString(bond.getLockTime()); @@ -83,34 +58,10 @@ class BondListItem implements DaoStateListener { bondType = Res.get("dao.bond.bondedReputation"); bondDetails = Utilities.bytesAsHexString(bond.getBondedAsset().getHash()); } - lockupDate = bsqFormatter.formatDateTime(new Date(bond.getLockupDate())); - txId = bond.getLockupTxId(); - - stateLabel = new Label(); - - daoFacade.addBsqStateListener(this); - update(); - } - - private void update() { - stateLabel.setText(Res.get("dao.bond.bondState." + bond.getBondState().name())); - } - - public void cleanup() { - daoFacade.removeBsqStateListener(this); - } - - // DaoStateListener - @Override - public void onNewBlockHeight(int blockHeight) { - } - - @Override - public void onParseTxsComplete(Block block) { - update(); - } - - @Override - public void onParseBlockChainComplete() { + lockupTxId = bond.getLockupTxId(); + lockupDate = new Date(bond.getLockupDate()); + lockupDateString = bsqFormatter.formatDateTime(lockupDate); + bondState = bond.getBondState(); + bondStateString = Res.get("dao.bond.bondState." + bond.getBondState().name()); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java index c0095175258..7df722f15c2 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java @@ -21,38 +21,29 @@ import bisq.desktop.common.view.FxmlView; import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; -import bisq.desktop.main.dao.bonding.BondingViewUtils; +import bisq.desktop.util.FormBuilder; import bisq.desktop.util.GUIUtil; -import bisq.desktop.util.validation.BsqValidator; -import bisq.core.btc.listeners.BsqBalanceListener; -import bisq.core.btc.wallet.BsqWalletService; -import bisq.core.dao.DaoFacade; +import bisq.core.dao.governance.bond.Bond; +import bisq.core.dao.governance.bond.reputation.BondedReputation; +import bisq.core.dao.governance.bond.reputation.BondedReputationRepository; +import bisq.core.dao.governance.bond.role.BondedRole; import bisq.core.dao.governance.bond.role.BondedRolesRepository; -import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.model.blockchain.Block; import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; -import org.bitcoinj.core.Coin; -import org.bitcoinj.core.Transaction; - import javax.inject.Inject; import de.jensd.fx.fontawesome.AwesomeIcon; -import javafx.scene.control.Label; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.Tooltip; import javafx.scene.layout.GridPane; -import javafx.geometry.Insets; - import javafx.beans.property.ReadOnlyObjectWrapper; -import javafx.beans.value.ChangeListener; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; @@ -61,22 +52,18 @@ import javafx.util.Callback; +import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; -import static bisq.desktop.util.FormBuilder.addTitledGroupBg; - @FxmlView -public class BondsView extends ActivatableView implements BsqBalanceListener, DaoStateListener { +public class BondsView extends ActivatableView { private TableView tableView; - private final BsqWalletService bsqWalletService; private final BsqFormatter bsqFormatter; - private final BsqValidator bsqValidator; - private final BondingViewUtils bondingViewUtils; private final BondedRolesRepository bondedRolesRepository; - private final DaoFacade daoFacade; + private final BondedReputationRepository bondedReputationRepository; private final Preferences preferences; private int gridRow = 0; @@ -84,8 +71,8 @@ public class BondsView extends ActivatableView implements BsqBal private final ObservableList observableList = FXCollections.observableArrayList(); private final SortedList sortedList = new SortedList<>(observableList); - private ListChangeListener walletBsqTransactionsListener; - private ChangeListener walletChainHeightListener; + private ListChangeListener bondedRolesListener; + private ListChangeListener bondedReputationListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -93,104 +80,39 @@ public class BondsView extends ActivatableView implements BsqBal /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private BondsView(BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BsqValidator bsqValidator, - BondingViewUtils bondingViewUtils, + private BondsView(BsqFormatter bsqFormatter, BondedRolesRepository bondedRolesRepository, - DaoFacade daoFacade, + BondedReputationRepository bondedReputationRepository, Preferences preferences) { - this.bsqWalletService = bsqWalletService; this.bsqFormatter = bsqFormatter; - this.bsqValidator = bsqValidator; - this.bondingViewUtils = bondingViewUtils; this.bondedRolesRepository = bondedRolesRepository; - this.daoFacade = daoFacade; + this.bondedReputationRepository = bondedReputationRepository; this.preferences = preferences; } @Override public void initialize() { - addTitledGroupBg(root, gridRow, 2, Res.get("dao.bonding.bonds.table.header")); - - tableView = new TableView<>(); - GridPane.setRowIndex(tableView, ++gridRow); - GridPane.setMargin(tableView, new Insets(30, -10, 5, -10)); - root.getChildren().add(tableView); - tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.bonding.bonds.table.header")); + tableView.setItems(sortedList); addColumns(); - walletBsqTransactionsListener = change -> updateList(); - walletChainHeightListener = (observable, oldValue, newValue) -> updateList(); + bondedReputationListener = c -> updateList(); + bondedRolesListener = c -> updateList(); } @Override protected void activate() { - bsqWalletService.addBsqBalanceListener(this); - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getUnverifiedBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockupBondsBalance(), - bsqWalletService.getUnlockingBondsBalance()); - - bsqWalletService.getWalletTransactions().addListener(walletBsqTransactionsListener); - bsqWalletService.addBsqBalanceListener(this); - bsqWalletService.getChainHeightProperty().addListener(walletChainHeightListener); - sortedList.comparatorProperty().bind(tableView.comparatorProperty()); - tableView.setItems(sortedList); - - daoFacade.addBsqStateListener(this); - + bondedReputationRepository.getBonds().addListener(bondedReputationListener); + bondedRolesRepository.getBonds().addListener(bondedRolesListener); updateList(); } @Override protected void deactivate() { - bsqWalletService.removeBsqBalanceListener(this); - - bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); - bsqWalletService.removeBsqBalanceListener(this); - bsqWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); - daoFacade.removeBsqStateListener(this); - sortedList.comparatorProperty().unbind(); - - observableList.forEach(BondListItem::cleanup); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // BsqBalanceListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onUpdateBalances(Coin confirmedBalance, - Coin availableNonBsqBalance, - Coin pendingBalance, - Coin lockedForVotingBalance, - Coin lockupBondsBalance, - Coin unlockingBondsBalance) { - bsqValidator.setAvailableBalance(confirmedBalance); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // DaoStateListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onNewBlockHeight(int blockHeight) { - } - - @Override - public void onParseTxsComplete(Block block) { - updateList(); - } - - @Override - public void onParseBlockChainComplete() { + bondedReputationRepository.getBonds().removeListener(bondedReputationListener); + bondedRolesRepository.getBonds().removeListener(bondedRolesListener); } @@ -198,24 +120,16 @@ public void onParseBlockChainComplete() { // Private /////////////////////////////////////////////////////////////////////////////////////////// - private void openTxInBlockExplorer(BondListItem item) { - if (item.getTxId() != null) - GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); - } - private void updateList() { - List items = daoFacade.getAllBonds().stream() + List combined = new ArrayList<>(bondedReputationRepository.getBonds()); + combined.addAll(bondedRolesRepository.getBonds()); + observableList.setAll(combined.stream() .map(bond -> { - return new BondListItem(bond, - daoFacade, - bondedRolesRepository, - bondingViewUtils, - bsqFormatter); + return new BondListItem(bond, bsqFormatter); }) - .sorted(Comparator.comparing(BondListItem::getLockupDate).reversed()) - .collect(Collectors.toList()); - observableList.setAll(items); - GUIUtil.setFitToRowsForTableView(tableView, 37, 28, 2, 10); + .sorted(Comparator.comparing(BondListItem::getLockupDateString).reversed()) + .collect(Collectors.toList())); + GUIUtil.setFitToRowsForTableView(tableView, 37, 28, 2, 30); } @@ -275,22 +189,14 @@ public void updateItem(final BondListItem item, boolean empty) { public TableCell call(TableColumn column) { return new TableCell<>() { - Label label; - @Override public void updateItem(final BondListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - if (label == null) { - label = item.getStateLabel(); - setGraphic(label); - } - } else { - setGraphic(null); - if (label != null) - label = null; - } + setText(item.getBondStateString()); + } else + setText(""); } }; } @@ -341,10 +247,8 @@ public void updateItem(final BondListItem item, boolean empty) { column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockupDate")); column.setMinWidth(140); - column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { - @Override public TableCell call(TableColumn column) { return new TableCell<>() { @@ -352,7 +256,7 @@ public TableCell call(TableColumn() { - @Override public TableCell call(TableColumn column) { @@ -377,12 +280,11 @@ public TableCell call(TableColumn openTxInBlockExplorer(item)); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId))); + String lockupTxId = item.getLockupTxId(); + hyperlinkWithIcon = new HyperlinkWithIcon(lockupTxId, AwesomeIcon.EXTERNAL_LINK); + hyperlinkWithIcon.setOnAction(event -> GUIUtil.openTxInBsqBlockExplorer(lockupTxId, preferences)); + hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", lockupTxId))); setGraphic(hyperlinkWithIcon); } else { setGraphic(null); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java deleted file mode 100644 index 3df6578cfe6..00000000000 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationListItem.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.bonding.reputation; - -import bisq.desktop.components.AutoTooltipButton; -import bisq.desktop.main.dao.bonding.BondingViewUtils; - -import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.BondState; -import bisq.core.dao.governance.bond.reputation.MyBondedReputation; -import bisq.core.dao.governance.bond.reputation.MyReputation; -import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.model.blockchain.Block; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import bisq.common.util.Utilities; - -import org.bitcoinj.core.Coin; - -import javafx.scene.control.Label; - -import java.util.Date; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@EqualsAndHashCode -@Data -@Slf4j -class MyBondedReputationListItem implements DaoStateListener { - private final MyBondedReputation myBondedReputation; - private final DaoFacade daoFacade; - private final BsqFormatter bsqFormatter; - private final String hash, salt; - private final String txId; - private final String amount; - private final String lockupDate; - private final String lockTime; - - @Getter - private final AutoTooltipButton button; - @Getter - private final Label stateLabel; - - MyBondedReputationListItem(MyBondedReputation myBondedReputation, - DaoFacade daoFacade, - BondingViewUtils bondingViewUtils, - BsqFormatter bsqFormatter) { - this.myBondedReputation = myBondedReputation; - this.daoFacade = daoFacade; - this.bsqFormatter = bsqFormatter; - - MyReputation myReputation = myBondedReputation.getBondedAsset(); - hash = Utilities.bytesAsHexString(myReputation.getHash()); - salt = Utilities.bytesAsHexString(myReputation.getSalt()); - txId = myBondedReputation.getLockupTxId(); - amount = bsqFormatter.formatCoin(Coin.valueOf(myBondedReputation.getAmount())); - lockupDate = bsqFormatter.formatDateTime(new Date(myBondedReputation.getLockupDate())); - lockTime = Integer.toString(myBondedReputation.getLockTime()); - - daoFacade.addBsqStateListener(this); - - button = new AutoTooltipButton(); - stateLabel = new Label(); - - button.setOnAction(e -> { - if (myBondedReputation.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { - bondingViewUtils.unLock(myBondedReputation.getLockupTxId(), - txId -> { - }); - } - }); - - update(); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // DaoStateListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onNewBlockHeight(int blockHeight) { - } - - @Override - public void onParseTxsComplete(Block block) { - update(); - } - - @Override - public void onParseBlockChainComplete() { - } - - void cleanup() { - daoFacade.removeBsqStateListener(this); - button.setOnAction(null); - } - - private void update() { - stateLabel.setText(Res.get("dao.bond.bondState." + myBondedReputation.getBondState().name())); - - boolean showButton = myBondedReputation.getBondState() == BondState.LOCKUP_TX_CONFIRMED; - if (showButton) - button.updateText(Res.get("dao.bond.table.button.unlock")); - - button.setVisible(showButton); - button.setManaged(showButton); - } -} diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationListItem.java new file mode 100644 index 00000000000..631f34202bd --- /dev/null +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationListItem.java @@ -0,0 +1,68 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding.reputation; + +import bisq.core.dao.governance.bond.BondState; +import bisq.core.dao.governance.bond.reputation.MyBondedReputation; +import bisq.core.dao.governance.bond.reputation.MyReputation; +import bisq.core.locale.Res; +import bisq.core.util.BsqFormatter; + +import bisq.common.util.Utilities; + +import org.bitcoinj.core.Coin; + +import java.util.Date; + +import lombok.Value; + +@Value +class MyReputationListItem { + private final MyBondedReputation myBondedReputation; + private final String hash, salt; + private final String txId; + private final String amount; + private final String lockupDateString; + private final String lockTime; + + private final String buttonText; + private final boolean showButton; + private final BondState bondState; + private final String bondStateString; + private final String lockupTxId; + private final Date lockupDate; + + MyReputationListItem(MyBondedReputation myBondedReputation, + BsqFormatter bsqFormatter) { + this.myBondedReputation = myBondedReputation; + + MyReputation myReputation = myBondedReputation.getBondedAsset(); + hash = Utilities.bytesAsHexString(myReputation.getHash()); + salt = Utilities.bytesAsHexString(myReputation.getSalt()); + txId = myBondedReputation.getLockupTxId(); + amount = bsqFormatter.formatCoin(Coin.valueOf(myBondedReputation.getAmount())); + lockupDate = new Date(myBondedReputation.getLockupDate()); + lockupDateString = bsqFormatter.formatDateTime(lockupDate); + lockTime = Integer.toString(myBondedReputation.getLockTime()); + lockupTxId = myBondedReputation.getLockupTxId(); + bondState = myBondedReputation.getBondState(); + bondStateString = Res.get("dao.bond.bondState." + myBondedReputation.getBondState().name()); + showButton = myBondedReputation.getBondState() == BondState.LOCKUP_TX_CONFIRMED; + buttonText = Res.get("dao.bond.table.button.unlock"); + } +} diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.fxml b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.fxml similarity index 86% rename from desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.fxml rename to desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.fxml index 4e175d3fae7..f0a618ed72a 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.fxml +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.fxml @@ -21,15 +21,13 @@ - - - - + diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java similarity index 66% rename from desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java rename to desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java index 1bc4318b6ea..0707ec8f151 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyBondedReputationView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java @@ -19,10 +19,10 @@ import bisq.desktop.common.view.ActivatableView; import bisq.desktop.common.view.FxmlView; +import bisq.desktop.components.AutoTooltipButton; import bisq.desktop.components.AutoTooltipTableColumn; import bisq.desktop.components.HyperlinkWithIcon; import bisq.desktop.components.InputTextField; -import bisq.desktop.components.TitledGroupBg; import bisq.desktop.main.dao.bonding.BondingViewUtils; import bisq.desktop.util.FormBuilder; import bisq.desktop.util.GUIUtil; @@ -33,8 +33,8 @@ import bisq.core.btc.wallet.BsqWalletService; import bisq.core.dao.DaoFacade; import bisq.core.dao.governance.bond.BondConsensus; -import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.model.blockchain.Block; +import bisq.core.dao.governance.bond.BondState; +import bisq.core.dao.governance.bond.reputation.MyBondedReputation; import bisq.core.locale.Res; import bisq.core.user.Preferences; import bisq.core.util.BsqFormatter; @@ -45,7 +45,6 @@ import bisq.common.util.Utilities; import org.bitcoinj.core.Coin; -import org.bitcoinj.core.Transaction; import javax.inject.Inject; @@ -54,15 +53,11 @@ import de.jensd.fx.fontawesome.AwesomeIcon; import javafx.scene.control.Button; -import javafx.scene.control.Label; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.Tooltip; import javafx.scene.layout.GridPane; -import javafx.scene.layout.VBox; - -import javafx.geometry.Insets; import javafx.beans.property.ReadOnlyObjectWrapper; import javafx.beans.value.ChangeListener; @@ -75,7 +70,6 @@ import javafx.util.Callback; import java.util.Comparator; -import java.util.List; import java.util.UUID; import java.util.stream.Collectors; @@ -84,26 +78,29 @@ import static bisq.desktop.util.FormBuilder.addTitledGroupBg; @FxmlView -public class MyBondedReputationView extends ActivatableView implements DaoStateListener, BsqBalanceListener { - private final BsqWalletService bsqWalletService; +public class MyReputationView extends ActivatableView implements BsqBalanceListener { + private InputTextField amountInputTextField, timeInputTextField, saltInputTextField; + private Button lockupButton; + private TableView tableView; + private final BsqFormatter bsqFormatter; + private final BsqWalletService bsqWalletService; private final BondingViewUtils bondingViewUtils; private final HexStringValidator hexStringValidator; private final BsqValidator bsqValidator; private final DaoFacade daoFacade; private final Preferences preferences; + private final IntegerValidator timeInputTextFieldValidator; + private final ObservableList observableList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(observableList); + private int gridRow = 0; - private InputTextField amountInputTextField, timeInputTextField, saltInputTextField; - private Button lockupButton; - private TableView tableView; + private ChangeListener amountFocusOutListener, timeFocusOutListener, saltFocusOutListener; private ChangeListener amountInputTextFieldListener, timeInputTextFieldListener, saltInputTextFieldListener; - private final ObservableList observableList = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(observableList); - private ListChangeListener walletBsqTransactionsListener; - private ChangeListener walletChainHeightListener; + private ListChangeListener myBondedReputationsChangeListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -111,15 +108,15 @@ public class MyBondedReputationView extends ActivatableView impl /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private MyBondedReputationView(BsqWalletService bsqWalletService, - BsqFormatter bsqFormatter, - BondingViewUtils bondingViewUtils, - HexStringValidator hexStringValidator, - BsqValidator bsqValidator, - DaoFacade daoFacade, - Preferences preferences) { - this.bsqWalletService = bsqWalletService; + private MyReputationView(BsqFormatter bsqFormatter, + BsqWalletService bsqWalletService, + BondingViewUtils bondingViewUtils, + HexStringValidator hexStringValidator, + BsqValidator bsqValidator, + DaoFacade daoFacade, + Preferences preferences) { this.bsqFormatter = bsqFormatter; + this.bsqWalletService = bsqWalletService; this.bondingViewUtils = bondingViewUtils; this.hexStringValidator = hexStringValidator; this.bsqValidator = bsqValidator; @@ -133,26 +130,23 @@ private MyBondedReputationView(BsqWalletService bsqWalletService, @Override public void initialize() { - int columnSpan = 3; - TitledGroupBg titledGroupBg = addTitledGroupBg(root, gridRow, 3, Res.get("dao.bonding.reputation.header")); - GridPane.setColumnSpan(titledGroupBg, columnSpan); + addTitledGroupBg(root, gridRow, 3, Res.get("dao.bonding.reputation.header")); amountInputTextField = addInputTextField(root, gridRow, Res.get("dao.bonding.lock.amount"), Layout.FIRST_ROW_DISTANCE); amountInputTextField.setValidator(bsqValidator); - GridPane.setColumnSpan(amountInputTextField, columnSpan); timeInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time")); - GridPane.setColumnSpan(timeInputTextField, columnSpan); timeInputTextField.setValidator(timeInputTextFieldValidator); saltInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.salt")); - GridPane.setColumnSpan(saltInputTextField, columnSpan); saltInputTextField.setValidator(hexStringValidator); lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); - createTableView(columnSpan); + tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.bonding.reputation.list.header"), 20); + createColumns(); + tableView.setItems(sortedList); createListeners(); } @@ -168,9 +162,10 @@ protected void activate() { saltInputTextField.textProperty().addListener(saltInputTextFieldListener); saltInputTextField.focusedProperty().addListener(saltFocusOutListener); - bsqWalletService.getWalletTransactions().addListener(walletBsqTransactionsListener); + sortedList.comparatorProperty().bind(tableView.comparatorProperty()); + + daoFacade.getMyBondedReputations().addListener(myBondedReputationsChangeListener); bsqWalletService.addBsqBalanceListener(this); - bsqWalletService.getChainHeightProperty().addListener(walletChainHeightListener); lockupButton.setOnAction((event) -> { Coin lockupAmount = bsqFormatter.parseToCoin(amountInputTextField.getText()); @@ -186,23 +181,18 @@ protected void activate() { setNewRandomSalt(); }); - daoFacade.addBsqStateListener(this); amountInputTextField.resetValidation(); timeInputTextField.resetValidation(); - setNewRandomSalt(); - sortedList.comparatorProperty().bind(tableView.comparatorProperty()); - tableView.setItems(sortedList); + //TODO maybe show generate salt button instead + setNewRandomSalt(); - onUpdateBalances(); updateList(); } @Override protected void deactivate() { - observableList.forEach(MyBondedReputationListItem::cleanup); - amountInputTextField.textProperty().removeListener(amountInputTextFieldListener); amountInputTextField.focusedProperty().removeListener(amountFocusOutListener); @@ -212,36 +202,14 @@ protected void deactivate() { saltInputTextField.textProperty().removeListener(saltInputTextFieldListener); saltInputTextField.focusedProperty().removeListener(saltFocusOutListener); - bsqWalletService.getWalletTransactions().removeListener(walletBsqTransactionsListener); - bsqWalletService.addBsqBalanceListener(this); - bsqWalletService.getChainHeightProperty().removeListener(walletChainHeightListener); - - lockupButton.setOnAction(null); + daoFacade.getMyBondedReputations().removeListener(myBondedReputationsChangeListener); + bsqWalletService.removeBsqBalanceListener(this); sortedList.comparatorProperty().unbind(); - daoFacade.removeBsqStateListener(this); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // DaoStateListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onNewBlockHeight(int blockHeight) { - } - - @Override - public void onParseTxsComplete(Block block) { - updateList(); - } - - @Override - public void onParseBlockChainComplete() { + lockupButton.setOnAction(null); } - /////////////////////////////////////////////////////////////////////////////////////////// // BsqBalanceListener /////////////////////////////////////////////////////////////////////////////////////////// @@ -254,7 +222,6 @@ public void onUpdateBalances(Coin confirmedBalance, Coin lockupBondsBalance, Coin unlockingBondsBalance) { bsqValidator.setAvailableBalance(confirmedBalance); - updateButtonState(); } @@ -266,19 +233,16 @@ private void createListeners() { amountFocusOutListener = (observable, oldValue, newValue) -> { if (!newValue) { updateButtonState(); - onUpdateBalances(); } }; timeFocusOutListener = (observable, oldValue, newValue) -> { if (!newValue) { updateButtonState(); - onUpdateBalances(); } }; saltFocusOutListener = (observable, oldValue, newValue) -> { if (!newValue) { updateButtonState(); - onUpdateBalances(); } }; @@ -286,26 +250,15 @@ private void createListeners() { timeInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); saltInputTextFieldListener = (observable, oldValue, newValue) -> updateButtonState(); - walletBsqTransactionsListener = change -> updateList(); - walletChainHeightListener = (observable, oldValue, newValue) -> updateList(); + myBondedReputationsChangeListener = c -> updateList(); } - private void createTableView(int columnSpan) { - TitledGroupBg titledGroupBg2 = addTitledGroupBg(root, ++gridRow, 2, Res.get("dao.bonding.reputation.list.header"), 20); - GridPane.setColumnSpan(titledGroupBg2, columnSpan); - - tableView = new TableView<>(); - tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); - createColumns(); - - VBox vBox = new VBox(); - vBox.setSpacing(10); - GridPane.setRowIndex(vBox, ++gridRow); - GridPane.setColumnSpan(vBox, columnSpan); - GridPane.setMargin(vBox, new Insets(50, -10, 5, -10)); - vBox.getChildren().addAll(tableView); - root.getChildren().add(vBox); + private void updateList() { + observableList.setAll(daoFacade.getMyBondedReputations().stream() + .map(myBondedReputation -> new MyReputationListItem(myBondedReputation, bsqFormatter)) + .sorted(Comparator.comparing(MyReputationListItem::getLockupDateString).reversed()) + .collect(Collectors.toList())); + GUIUtil.setFitToRowsForTableView(tableView, 41, 28, 2, 30); } private void setNewRandomSalt() { @@ -315,15 +268,6 @@ private void setNewRandomSalt() { saltInputTextField.resetValidation(); } - private void onUpdateBalances() { - onUpdateBalances(bsqWalletService.getAvailableBalance(), - bsqWalletService.getAvailableNonBsqBalance(), - bsqWalletService.getUnverifiedBalance(), - bsqWalletService.getLockedForVotingBalance(), - bsqWalletService.getLockupBondsBalance(), - bsqWalletService.getUnlockingBondsBalance()); - } - private void updateButtonState() { boolean isValid = bsqValidator.validate(amountInputTextField.getText()).isValid && timeInputTextFieldValidator.validate(timeInputTextField.getText()).isValid && @@ -331,29 +275,13 @@ private void updateButtonState() { lockupButton.setDisable(!isValid); } - private void openTxInBlockExplorer(MyBondedReputationListItem item) { - if (item.getTxId() != null) - GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + item.getTxId()); - } - - private void updateList() { - List items = daoFacade.getMyBondedReputations().stream() - .map(myBondedReputation -> { - return new MyBondedReputationListItem(myBondedReputation, daoFacade, bondingViewUtils, bsqFormatter); - }) - .sorted(Comparator.comparing(MyBondedReputationListItem::getLockupDate).reversed()) - .collect(Collectors.toList()); - observableList.setAll(items); - GUIUtil.setFitToRowsForTableView(tableView, 41, 28, 2, 10); - } - /////////////////////////////////////////////////////////////////////////////////////////// // Table columns /////////////////////////////////////////////////////////////////////////////////////////// private void createColumns() { - TableColumn column; + TableColumn column; column = new AutoTooltipTableColumn<>(Res.get("shared.amountWithCur", "BSQ")); column.setMinWidth(120); @@ -361,11 +289,11 @@ private void createColumns() { column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { @Override - public void updateItem(final MyBondedReputationListItem item, boolean empty) { + public void updateItem(final MyReputationListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { setText(item.getAmount()); @@ -383,11 +311,11 @@ public void updateItem(final MyBondedReputationListItem item, boolean empty) { column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { @Override - public void updateItem(final MyBondedReputationListItem item, boolean empty) { + public void updateItem(final MyReputationListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { setText(item.getLockTime()); @@ -405,25 +333,16 @@ public void updateItem(final MyBondedReputationListItem item, boolean empty) { column.setCellFactory( new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { - Label label; - @Override - public void updateItem(final MyBondedReputationListItem item, boolean empty) { + public void updateItem(MyReputationListItem item, boolean empty) { super.updateItem(item, empty); - if (item != null && !empty) { - if (label == null) { - label = item.getStateLabel(); - setGraphic(label); - } - } else { - setGraphic(null); - if (label != null) - label = null; - } + setText(item.getBondStateString()); + } else + setText(""); } }; } @@ -436,15 +355,15 @@ public void updateItem(final MyBondedReputationListItem item, boolean empty) { column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { @Override - public void updateItem(final MyBondedReputationListItem item, boolean empty) { + public void updateItem(final MyReputationListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { - setText(item.getLockupDate()); + setText(item.getLockupDateString()); } else setText(""); } @@ -459,19 +378,19 @@ public void updateItem(final MyBondedReputationListItem item, boolean empty) { column.setCellFactory( new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { private HyperlinkWithIcon hyperlinkWithIcon; @Override - public void updateItem(final MyBondedReputationListItem item, boolean empty) { + public void updateItem(final MyReputationListItem item, boolean empty) { super.updateItem(item, empty); //noinspection Duplicates if (item != null && !empty) { String transactionId = item.getTxId(); hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(item)); + hyperlinkWithIcon.setOnAction(event -> GUIUtil.openTxInBsqBlockExplorer(item.getTxId(), preferences)); hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId))); setGraphic(hyperlinkWithIcon); } else { @@ -490,11 +409,11 @@ public void updateItem(final MyBondedReputationListItem item, boolean empty) { column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { @Override - public void updateItem(final MyBondedReputationListItem item, boolean empty) { + public void updateItem(final MyReputationListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { setText(item.getSalt()); @@ -511,11 +430,11 @@ public void updateItem(final MyBondedReputationListItem item, boolean empty) { column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { @Override - public void updateItem(final MyBondedReputationListItem item, boolean empty) { + public void updateItem(final MyReputationListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { setText(item.getHash()); @@ -533,23 +452,30 @@ public void updateItem(final MyBondedReputationListItem item, boolean empty) { column.setCellFactory( new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { - Button button; + AutoTooltipButton button; @Override - public void updateItem(final MyBondedReputationListItem item, boolean empty) { + public void updateItem(final MyReputationListItem item, boolean empty) { super.updateItem(item, empty); - if (item != null && !empty) { - if (button == null) { - button = item.getButton(); - setGraphic(button); - } + if (item != null && !empty && item.isShowButton()) { + button = new AutoTooltipButton(item.getButtonText()); + button.setOnAction(e -> { + if (item.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { + bondingViewUtils.unLock(item.getLockupTxId(), + txId -> { + }); + } + }); + setGraphic(button); } else { setGraphic(null); - if (button != null) + if (button != null) { + button.setOnAction(null); button = null; + } } } }; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java deleted file mode 100644 index 520e4bfd04e..00000000000 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesListItem.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.desktop.main.dao.bonding.roles; - -import bisq.desktop.components.AutoTooltipButton; -import bisq.desktop.main.dao.bonding.BondingViewUtils; - -import bisq.core.dao.DaoFacade; -import bisq.core.dao.governance.bond.BondState; -import bisq.core.dao.governance.bond.role.BondedRole; -import bisq.core.dao.state.DaoStateListener; -import bisq.core.dao.state.model.blockchain.Block; -import bisq.core.dao.state.model.governance.Role; -import bisq.core.locale.Res; -import bisq.core.util.BsqFormatter; - -import javafx.scene.control.Label; - -import java.util.Date; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@EqualsAndHashCode -class BondedRolesListItem implements DaoStateListener { - @Getter - private final BondedRole bondedRole; - private final DaoFacade daoFacade; - private final BondingViewUtils bondingViewUtils; - private final BsqFormatter bsqFormatter; - @Getter - private final AutoTooltipButton button; - @Getter - private final Label label; - @Getter - private final Role role; - - private final boolean isMyRole; - - BondedRolesListItem(BondedRole bondedRole, - DaoFacade daoFacade, - BondingViewUtils bondingViewUtils, - BsqFormatter bsqFormatter) { - this.bondedRole = bondedRole; - this.daoFacade = daoFacade; - this.bondingViewUtils = bondingViewUtils; - this.bsqFormatter = bsqFormatter; - - role = bondedRole.getBondedAsset(); - isMyRole = daoFacade.isMyRole(role); - - daoFacade.addBsqStateListener(this); - - button = new AutoTooltipButton(); - button.setMinWidth(70); - label = new Label(); - - button.setOnAction(e -> { - if (bondedRole.getBondState() == BondState.READY_FOR_LOCKUP) { - bondingViewUtils.lockupBondForBondedRole(role, - txId -> { - /*bondedRole.setLockupTxId(txId); - bondedRole.setBondState(BondState.LOCKUP_TX_PENDING); - update(); - button.setDisable(true);*/ - }); - } else if (bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { - bondingViewUtils.unLock(bondedRole.getLockupTxId(), - txId -> { - /*bondedRole.setUnlockTxId(txId); - bondedRole.setBondState(BondState.UNLOCK_TX_PENDING); - update(); - button.setDisable(true);*/ - }); - } - }); - - update(); - } - - public String getStartDate() { - return bondedRole.getLockupDate() > 0 ? - bsqFormatter.formatDateTime(new Date(bondedRole.getLockupDate())) : - "-"; - } - - public String getRevokeDate() { - return bondedRole.getUnlockDate() > 0 ? - bsqFormatter.formatDateTime(new Date(bondedRole.getUnlockDate())) : - "-"; - } - - public void cleanup() { - daoFacade.removeBsqStateListener(this); - button.setOnAction(null); - } - - - private void update() { - label.setText(Res.get("dao.bond.bondState." + bondedRole.getBondState().name())); - - boolean showLockup = bondedRole.getBondState() == BondState.READY_FOR_LOCKUP; - boolean showRevoke = bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED; - if (showLockup) - button.updateText(Res.get("dao.bond.table.button.lockup")); - else if (showRevoke) - button.updateText(Res.get("dao.bond.table.button.revoke")); - - - boolean showButton = isMyRole && (showLockup || showRevoke); - button.setVisible(showButton); - button.setManaged(showButton); - } - - // DaoStateListener - @Override - public void onNewBlockHeight(int blockHeight) { - } - - @Override - public void onParseTxsComplete(Block block) { - update(); - } - - @Override - public void onParseBlockChainComplete() { - } -} diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java similarity index 94% rename from desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java rename to desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java index c0bab71276b..b925e730ba0 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRoleTypeWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java @@ -30,19 +30,19 @@ import lombok.extern.slf4j.Slf4j; +//TODO not used atm but keep it as is should be used @Slf4j -class BondedRoleTypeWindow extends Overlay { +class RoleDetailsWindow extends Overlay { private final BondedRoleType bondedRoleType; private final BsqFormatter bsqFormatter; - public BondedRoleTypeWindow(BondedRoleType bondedRoleType, BsqFormatter bsqFormatter) { + public RoleDetailsWindow(BondedRoleType bondedRoleType, BsqFormatter bsqFormatter) { this.bondedRoleType = bondedRoleType; this.bsqFormatter = bsqFormatter; width = 968; type = Type.Confirmation; - } /////////////////////////////////////////////////////////////////////////////////////////// diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesListItem.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesListItem.java new file mode 100644 index 00000000000..40bb7f668bd --- /dev/null +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesListItem.java @@ -0,0 +1,66 @@ +/* + * This file is part of Bisq. + * + * Bisq is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Bisq is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public + * License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Bisq. If not, see . + */ + +package bisq.desktop.main.dao.bonding.roles; + +import bisq.core.dao.DaoFacade; +import bisq.core.dao.governance.bond.BondState; +import bisq.core.dao.governance.bond.role.BondedRole; +import bisq.core.dao.state.model.governance.Role; +import bisq.core.locale.Res; + +import java.util.Date; + +import lombok.Value; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Value +class RolesListItem { + private final BondedRole bondedRole; + private final Role role; + private final String buttonText; + private final boolean isButtonVisible; + private final BondState bondState; + private final String bondStateString; + private final String lockupTxId; + private final Date lockupDate; + + RolesListItem(BondedRole bondedRole, + DaoFacade daoFacade) { + this.bondedRole = bondedRole; + + role = bondedRole.getBondedAsset(); + boolean isMyRole = daoFacade.isMyRole(role); + bondState = bondedRole.getBondState(); + lockupTxId = bondedRole.getLockupTxId(); + lockupDate = new Date(bondedRole.getLockupDate()); + bondStateString = Res.get("dao.bond.bondState." + bondedRole.getBondState().name()); + + boolean showLockup = bondedRole.getBondState() == BondState.READY_FOR_LOCKUP; + boolean showRevoke = bondedRole.getBondState() == BondState.LOCKUP_TX_CONFIRMED; + if (showLockup) { + buttonText = Res.get("dao.bond.table.button.lockup"); + } else if (showRevoke) { + buttonText = Res.get("dao.bond.table.button.revoke"); + } else { + buttonText = ""; + } + + isButtonVisible = isMyRole && (showLockup || showRevoke); + } +} diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.fxml b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesView.fxml similarity index 97% rename from desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.fxml rename to desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesView.fxml index e5233b4dc40..456483f9e6a 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/BondedRolesView.fxml +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesView.fxml @@ -21,7 +21,7 @@ - implements DaoStateListener { - private TableView tableView; +public class RolesView extends ActivatableView { + private TableView tableView; - private final BsqFormatter bsqFormatter; private final BondingViewUtils bondingViewUtils; + private final BsqFormatter bsqFormatter; private final DaoFacade daoFacade; private final Preferences preferences; - private final ObservableList observableList = FXCollections.observableArrayList(); - private final SortedList sortedList = new SortedList<>(observableList); + private final ObservableList observableList = FXCollections.observableArrayList(); + private final SortedList sortedList = new SortedList<>(observableList); + + private ListChangeListener bondedRoleListChangeListener; /////////////////////////////////////////////////////////////////////////////////////////// @@ -78,10 +78,10 @@ public class BondedRolesView extends ActivatableView implements /////////////////////////////////////////////////////////////////////////////////////////// @Inject - private BondedRolesView(BsqFormatter bsqFormatter, - BondingViewUtils bondingViewUtils, - DaoFacade daoFacade, - Preferences preferences) { + private RolesView(BsqFormatter bsqFormatter, + BondingViewUtils bondingViewUtils, + DaoFacade daoFacade, + Preferences preferences) { this.bsqFormatter = bsqFormatter; this.bondingViewUtils = bondingViewUtils; this.daoFacade = daoFacade; @@ -91,50 +91,24 @@ private BondedRolesView(BsqFormatter bsqFormatter, @Override public void initialize() { int gridRow = 0; - addTitledGroupBg(root, gridRow, 2, Res.get("dao.bond.bondedRoles")); - - tableView = new TableView<>(); - GridPane.setRowIndex(tableView, ++gridRow); - GridPane.setMargin(tableView, new Insets(30, -10, 5, -10)); - root.getChildren().add(tableView); - tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); - tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + tableView = FormBuilder.addTableViewWithHeader(root, gridRow, Res.get("dao.bond.bondedRoles")); createColumns(); tableView.setItems(sortedList); + + bondedRoleListChangeListener = c -> updateList(); } @Override protected void activate() { - daoFacade.addBsqStateListener(this); sortedList.comparatorProperty().bind(tableView.comparatorProperty()); - + daoFacade.getBondedRoles().addListener(bondedRoleListChangeListener); updateList(); } @Override protected void deactivate() { - daoFacade.removeBsqStateListener(this); sortedList.comparatorProperty().unbind(); - - observableList.forEach(BondedRolesListItem::cleanup); - } - - - /////////////////////////////////////////////////////////////////////////////////////////// - // DaoStateListener - /////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public void onNewBlockHeight(int blockHeight) { - } - - @Override - public void onParseTxsComplete(Block block) { - updateList(); - } - - @Override - public void onParseBlockChainComplete() { + daoFacade.getBondedRoles().removeListener(bondedRoleListChangeListener); } @@ -142,17 +116,12 @@ public void onParseBlockChainComplete() { // Private /////////////////////////////////////////////////////////////////////////////////////////// - private void updateList() { - observableList.forEach(BondedRolesListItem::cleanup); observableList.setAll(daoFacade.getBondedRoles().stream() - .map(bond -> new BondedRolesListItem(bond, daoFacade, bondingViewUtils, bsqFormatter)) + .map(bond -> new RolesListItem(bond, daoFacade)) + .sorted(Comparator.comparing(RolesListItem::getLockupDate).reversed()) .collect(Collectors.toList())); - } - - private void openTxInBlockExplorer(String transactionId) { - if (transactionId != null) - GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + transactionId); + GUIUtil.setFitToRowsForTableView(tableView, 41, 28, 2, 30); } @@ -161,20 +130,19 @@ private void openTxInBlockExplorer(String transactionId) { /////////////////////////////////////////////////////////////////////////////////////////// private void createColumns() { - TableColumn column; + TableColumn column; column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.name")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(80); column.setCellFactory( new Callback<>() { - @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { @Override - public void updateItem(final BondedRolesListItem item, boolean empty) { + public void updateItem(final RolesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { setText(item.getRole().getName()); @@ -191,15 +159,14 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { column.setMinWidth(60); column.setCellFactory( new Callback<>() { - @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { private HyperlinkWithIcon hyperlinkWithIcon; @Override - public void updateItem(final BondedRolesListItem item, boolean empty) { + public void updateItem(final RolesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { String link = item.getRole().getLink(); @@ -223,15 +190,14 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { column.setMinWidth(80); column.setCellFactory( new Callback<>() { - @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { private Hyperlink hyperlink; @Override - public void updateItem(final BondedRolesListItem item, boolean empty) { + public void updateItem(final RolesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { @@ -239,7 +205,7 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { String type = bondedRoleType.getDisplayString(); hyperlink = new Hyperlink(type); hyperlink.setOnAction(event -> { - new BondedRoleTypeWindow(bondedRoleType, bsqFormatter).show(); + new RoleDetailsWindow(bondedRoleType, bsqFormatter).show(); }); hyperlink.setTooltip(new Tooltip(Res.get("tooltip.openPopupForDetails", type))); setGraphic(hyperlink); @@ -254,77 +220,27 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { }); tableView.getColumns().add(column); - /* column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.startDate")); - column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(120); - column.setCellFactory( - new Callback, TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final BondedRolesListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null && !empty) { - setText(item.getStartDate()); - } else - setText(""); - } - }; - } - }); - tableView.getColumns().add(column); - - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.revokeDate")); - column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(120); - column.setCellFactory( - new Callback, TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - @Override - public void updateItem(final BondedRolesListItem item, boolean empty) { - super.updateItem(item, empty); - if (item != null && !empty) { - setText(item.getRevokeDate()); - } else - setText(""); - } - }; - } - }); - tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockupTxId")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(80); column.setCellFactory( - new Callback, TableCell>() { - + new Callback<>() { @Override - public TableCell call(TableColumn column) { - return new TableCell() { + public TableCell call(TableColumn column) { + return new TableCell<>() { private HyperlinkWithIcon hyperlinkWithIcon; private Label label; @Override - public void updateItem(final BondedRolesListItem item, boolean empty) { + public void updateItem(final RolesListItem item, boolean empty) { super.updateItem(item, empty); if (item != null && !empty) { String transactionId = item.getBondedRole().getLockupTxId(); if (transactionId != null) { hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(transactionId)); + hyperlinkWithIcon.setOnAction(event -> GUIUtil.openTxInBsqBlockExplorer(transactionId, preferences)); hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId))); setGraphic(hyperlinkWithIcon); } else { @@ -344,73 +260,22 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.unlockTxId")); - column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); - column.setMinWidth(80); - column.setCellFactory( - new Callback, TableCell>() { - - @Override - public TableCell call(TableColumn column) { - return new TableCell() { - private HyperlinkWithIcon hyperlinkWithIcon; - private Label label; - - @Override - public void updateItem(final BondedRolesListItem item, boolean empty) { - super.updateItem(item, empty); - - if (item != null && !empty) { - String transactionId = item.getBondedRole().getUnlockTxId(); - if (transactionId != null) { - hyperlinkWithIcon = new HyperlinkWithIcon(transactionId, AwesomeIcon.EXTERNAL_LINK); - hyperlinkWithIcon.setOnAction(event -> openTxInBlockExplorer(transactionId)); - hyperlinkWithIcon.setTooltip(new Tooltip(Res.get("tooltip.openBlockchainForTx", transactionId))); - setGraphic(hyperlinkWithIcon); - } else { - label = new Label("-"); - setGraphic(label); - } - } else { - setGraphic(null); - if (hyperlinkWithIcon != null) - hyperlinkWithIcon.setOnAction(null); - if (label != null) - label = null; - } - } - }; - } - }); - tableView.getColumns().add(column);*/ - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondState")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(120); column.setCellFactory( new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { - Label label; - @Override - public void updateItem(final BondedRolesListItem item, boolean empty) { + public void updateItem(final RolesListItem item, boolean empty) { super.updateItem(item, empty); - if (item != null && !empty) { - if (label == null) { - label = item.getLabel(); - setGraphic(label); - } - } else { - setGraphic(null); - if (label != null) - label = null; - } + setText(item.getBondStateString()); + } else + setText(""); } }; } @@ -423,24 +288,37 @@ public void updateItem(final BondedRolesListItem item, boolean empty) { column.setCellFactory( new Callback<>() { @Override - public TableCell call(TableColumn column) { + public TableCell call(TableColumn column) { return new TableCell<>() { - Button button; + AutoTooltipButton button; @Override - public void updateItem(final BondedRolesListItem item, boolean empty) { + public void updateItem(final RolesListItem item, boolean empty) { super.updateItem(item, empty); - - if (item != null && !empty) { + if (item != null && !empty && item.isButtonVisible()) { if (button == null) { - button = item.getButton(); + button = new AutoTooltipButton(item.getButtonText()); + button.setMinWidth(70); + button.setOnAction(e -> { + if (item.getBondState() == BondState.READY_FOR_LOCKUP) { + bondingViewUtils.lockupBondForBondedRole(item.getRole(), + txId -> { + }); + } else if (item.getBondState() == BondState.LOCKUP_TX_CONFIRMED) { + bondingViewUtils.unLock(item.getLockupTxId(), + txId -> { + }); + } + }); setGraphic(button); } } else { setGraphic(null); - if (button != null) + if (button != null) { + button.setOnAction(null); button = null; + } } } }; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java index c2356c7532f..6b984142688 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/make/MakeProposalView.java @@ -216,9 +216,13 @@ private void publishMyProposal(ProposalType type) { Coin miningFee = transaction.getFee(); int txSize = transaction.bitcoinSerialize().length; Coin fee = daoFacade.getProposalFee(daoFacade.getChainHeight()); - GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, - Res.get("dao.proposal"), () -> doPublishMyProposal(proposal, transaction)); + if (!DevEnv.isDevMode()) { + GUIUtil.showBsqFeeInfoPopup(fee, miningFee, txSize, bsqFormatter, btcFormatter, + Res.get("dao.proposal"), () -> doPublishMyProposal(proposal, transaction)); + } else { + doPublishMyProposal(proposal, transaction); + } } catch (InsufficientMoneyException e) { BSFormatter formatter = e instanceof InsufficientBsqException ? bsqFormatter : btcFormatter; new Popup<>().warning(Res.get("dao.proposal.create.missingFunds", diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java index aa3269d218c..f407f23ecc8 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/proposals/ProposalsView.java @@ -495,8 +495,12 @@ private void onVote() { Coin miningFee = miningFeeAndTxSize.first; int txSize = miningFeeAndTxSize.second; Coin blindVoteFee = daoFacade.getBlindVoteFeeForCycle(); - GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, - Res.get("dao.blindVote"), () -> publishBlindVote(stake)); + if (!DevEnv.isDevMode()) { + GUIUtil.showBsqFeeInfoPopup(blindVoteFee, miningFee, txSize, bsqFormatter, btcFormatter, + Res.get("dao.blindVote"), () -> publishBlindVote(stake)); + } else { + publishBlindVote(stake); + } } catch (InsufficientMoneyException | WalletException | TransactionVerificationException exception) { new Popup<>().warning(exception.toString()).show(); } diff --git a/desktop/src/main/java/bisq/desktop/util/FormBuilder.java b/desktop/src/main/java/bisq/desktop/util/FormBuilder.java index a1c44a6f16a..25d09f4dda7 100644 --- a/desktop/src/main/java/bisq/desktop/util/FormBuilder.java +++ b/desktop/src/main/java/bisq/desktop/util/FormBuilder.java @@ -64,6 +64,7 @@ import javafx.scene.control.Label; import javafx.scene.control.ListView; import javafx.scene.control.RadioButton; +import javafx.scene.control.TableView; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.control.ToggleButton; @@ -1680,4 +1681,19 @@ public static Button getIconButton(GlyphIcons icon, String styleClass) { } } + public static TableView addTableViewWithHeader(GridPane gridPane, int rowIndex, String headerText) { + return addTableViewWithHeader(gridPane, rowIndex, headerText, 0); + } + + public static TableView addTableViewWithHeader(GridPane gridPane, int rowIndex, String headerText, int top) { + addTitledGroupBg(gridPane, rowIndex, 1, headerText, top); + + TableView tableView = new TableView<>(); + GridPane.setRowIndex(tableView, rowIndex); + GridPane.setMargin(tableView, new Insets(top + 30, -10, 5, -10)); + gridPane.getChildren().add(tableView); + tableView.setPlaceholder(new AutoTooltipLabel(Res.get("table.placeholder.noData"))); + tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); + return tableView; + } } diff --git a/desktop/src/main/java/bisq/desktop/util/GUIUtil.java b/desktop/src/main/java/bisq/desktop/util/GUIUtil.java index 912ca8df428..77a5e6d7960 100644 --- a/desktop/src/main/java/bisq/desktop/util/GUIUtil.java +++ b/desktop/src/main/java/bisq/desktop/util/GUIUtil.java @@ -904,4 +904,9 @@ protected void updateItem(T item, boolean empty) { } }; } + + public static void openTxInBsqBlockExplorer(String txId, Preferences preferences) { + if (txId != null) + GUIUtil.openWebPage(preferences.getBsqBlockChainExplorer().txUrl + txId); + } } From 1c8df357f44d66121e823b12bd29708421f7f462 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 6 Nov 2018 22:32:40 -0500 Subject: [PATCH 25/27] Add length validation for salt --- .../bisq/core/util/validation/HexStringValidator.java | 9 +++++++++ .../main/dao/bonding/reputation/MyReputationView.java | 5 ++++- .../bisq/desktop/util/validation/LengthValidator.java | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/bisq/core/util/validation/HexStringValidator.java b/core/src/main/java/bisq/core/util/validation/HexStringValidator.java index 09d601f9bbf..32067b76e9e 100644 --- a/core/src/main/java/bisq/core/util/validation/HexStringValidator.java +++ b/core/src/main/java/bisq/core/util/validation/HexStringValidator.java @@ -23,10 +23,16 @@ import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.Setter; @EqualsAndHashCode(callSuper = true) @Data public class HexStringValidator extends InputValidator { + @Setter + private int minLength = Integer.MIN_VALUE; + @Setter + private int maxLength = Integer.MAX_VALUE; + public HexStringValidator() { } @@ -35,6 +41,9 @@ public ValidationResult validate(String input) { if (!validationResult.isValid) return validationResult; + if (input.length() > maxLength || input.length() < minLength) + new ValidationResult(false, Res.get("validation.length", minLength, maxLength)); + try { Utilities.decodeFromHex(input); return validationResult; diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java index 0707ec8f151..3366fcb2844 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java @@ -263,8 +263,11 @@ private void updateList() { private void setNewRandomSalt() { byte[] randomBytes = UUID.randomUUID().toString().getBytes(Charsets.UTF_8); + // We want to limit it to 20 bytes byte[] hashOfRandomBytes = Hash.getSha256Ripemd160hash(randomBytes); - saltInputTextField.setText(Utilities.bytesAsHexString(hashOfRandomBytes)); + // bytesAsHexString results in 40 chars + String bytesAsHexString = Utilities.bytesAsHexString(hashOfRandomBytes); + saltInputTextField.setText(bytesAsHexString); saltInputTextField.resetValidation(); } diff --git a/desktop/src/main/java/bisq/desktop/util/validation/LengthValidator.java b/desktop/src/main/java/bisq/desktop/util/validation/LengthValidator.java index 5a83c76d5bd..5d24c74fc22 100644 --- a/desktop/src/main/java/bisq/desktop/util/validation/LengthValidator.java +++ b/desktop/src/main/java/bisq/desktop/util/validation/LengthValidator.java @@ -22,7 +22,7 @@ public ValidationResult validate(String input) { int length = (input == null) ? 0 : input.length(); if (length < this.minLength || length > this.maxLength) - result = new ValidationResult(false, String.format(Res.get("validation.length", this.minLength, this.maxLength))); + result = new ValidationResult(false, Res.get("validation.length", this.minLength, this.maxLength)); return result; } From 3a03deb83a4b6bac9bb098b9b387f068219c89a7 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Tue, 6 Nov 2018 22:46:27 -0500 Subject: [PATCH 26/27] Cleanup translation string for bond domain --- .../resources/i18n/displayStrings.properties | 140 ++++++++---------- .../i18n/displayStrings_de.properties | 58 ++++---- .../i18n/displayStrings_el.properties | 58 ++++---- .../i18n/displayStrings_es.properties | 58 ++++---- .../i18n/displayStrings_fa.properties | 58 ++++---- .../i18n/displayStrings_hu.properties | 58 ++++---- .../i18n/displayStrings_pt.properties | 58 ++++---- .../i18n/displayStrings_ro.properties | 58 ++++---- .../i18n/displayStrings_ru.properties | 58 ++++---- .../i18n/displayStrings_sr.properties | 58 ++++---- .../i18n/displayStrings_th.properties | 58 ++++---- .../i18n/displayStrings_vi.properties | 58 ++++---- .../i18n/displayStrings_zh.properties | 58 ++++---- .../desktop/main/dao/bonding/BondingView.java | 6 +- .../main/dao/bonding/BondingViewUtils.java | 8 +- .../main/dao/bonding/bonds/BondsView.java | 14 +- .../bonding/reputation/MyReputationView.java | 24 +-- .../dao/bonding/roles/RoleDetailsWindow.java | 14 +- .../main/dao/bonding/roles/RolesView.java | 10 +- .../main/dao/wallet/BsqBalanceUtil.java | 6 +- 20 files changed, 452 insertions(+), 466 deletions(-) diff --git a/core/src/main/resources/i18n/displayStrings.properties b/core/src/main/resources/i18n/displayStrings.properties index 603036be595..b2d85d4a673 100644 --- a/core/src/main/resources/i18n/displayStrings.properties +++ b/core/src/main/resources/i18n/displayStrings.properties @@ -1307,36 +1307,69 @@ dao.results.votes.table.header.stake=Stake dao.results.votes.table.header.merit=Earned dao.results.votes.table.header.vote=Vote -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Bonded reputation -dao.bonding.menuItem.bonds=Bonds -dao.bonding.reputation.header=Lockup a bond for reputation -dao.bonding.reputation.list.header=My reputation bonds -dao.bonding.lock.amount=Amount of BSQ to lockup -dao.bonding.lock.time=Unlock time in blocks -dao.bonding.lock.salt=Salt -dao.bonding.lock.type=Type of bond -dao.bonding.lock.bondedRoles=Bonded roles -dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) -dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.unlock.time=Lock time -dao.bonding.unlock.unlock=Unlock -dao.bonding.unlock.hash=Hash -dao.bonding.unlock.salt=Salt -dao.bonding.unlock.reputation=Reputation -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over) -dao.bonding.bonds.table.lockupTxId=Lockup tx ID -dao.bonding.bonds.table.header=All bonds - -dao.bonding.info=Lockup Tx ID: {0} / {1} -dao.bonding.reputation.salt.info=Salt: {0} +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Bonded reputation +dao.bond.menuItem.bonds=Bonds + +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over) + + +dao.bond.reputation.header=Lockup a bond for reputation +dao.bond.reputation.table.header=My reputation bonds +dao.bond.reputation.amount=Amount of BSQ to lockup +dao.bond.reputation.time=Unlock time in blocks +dao.bond.reputation.salt=Salt +dao.bond.reputation.hash=Hash +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? + +dao.bond.allBonds.header=All bonds + +dao.bond.bondedReputation=Bonded Reputation +dao.bond.bondedRoles=Bonded roles + +dao.bond.details.header=Role details +dao.bond.details.role=Role +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks + +dao.bond.table.column.name=Name +dao.bond.table.column.link=Link +dao.bond.table.column.bondType=Bond type +dao.bond.table.column.details=Details +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.bondState=Bond state +dao.bond.table.column.lockTime=Lock time +dao.bond.table.column.lockupDate=Lockup date + +dao.bond.table.button.lockup=Lockup +dao.bond.table.button.unlock=Unlock +dao.bond.table.button.revoke=Revoke + +# suppress inspection "UnusedProperty" +dao.bond.bondState.READY_FOR_LOCKUP=Not bonded yet +# suppress inspection "UnusedProperty" +dao.bond.bondState.LOCKUP_TX_PENDING=Lockup pending +# suppress inspection "UnusedProperty" +dao.bond.bondState.LOCKUP_TX_CONFIRMED=Bond locked up +# suppress inspection "UnusedProperty" +dao.bond.bondState.UNLOCK_TX_PENDING=Unlock pending +# suppress inspection "UnusedProperty" +dao.bond.bondState.UNLOCK_TX_CONFIRMED=Unlock tx confirmed +# suppress inspection "UnusedProperty" +dao.bond.bondState.UNLOCKING=Bond unlocking +# suppress inspection "UnusedProperty" +dao.bond.bondState.UNLOCKED=Bond unlocked +# suppress inspection "UnusedProperty" +dao.bond.bondState.CONFISCATED=Bond confiscated # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1378,53 +1411,6 @@ dao.bond.bondedRoleType.MEDIATOR=Mediator # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.ARBITRATOR=Arbitrator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=Role -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks - -dao.bond.bondedReputation=Bonded Reputation -dao.bond.bondedRoles=Bonded roles - -dao.bond.table.column.header.name=Name -dao.bond.table.column.header.link=Link -dao.bond.table.column.header.bondType=Bond type -dao.bond.table.column.header.details=Details -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state -dao.bond.table.column.header.lockTime=Lock time -dao.bond.table.column.header.lockupDate=Lockup date - -dao.bond.table.button.lockup=Lockup -dao.bond.table.button.revoke=Revoke -dao.bond.table.button.unlock=Unlock -dao.bond.table.notBonded=Not bonded yet -dao.bond.table.lockedUp=Bond locked up -dao.bond.table.unlocking=Bond unlocking -dao.bond.table.unlocked=Bond unlocked - -# suppress inspection "UnusedProperty" -dao.bond.bondState.READY_FOR_LOCKUP=Not bonded yet -# suppress inspection "UnusedProperty" -dao.bond.bondState.LOCKUP_TX_PENDING=Lockup pending -# suppress inspection "UnusedProperty" -dao.bond.bondState.LOCKUP_TX_CONFIRMED=Bond locked up -# suppress inspection "UnusedProperty" -dao.bond.bondState.UNLOCK_TX_PENDING=Unlock pending -# suppress inspection "UnusedProperty" -dao.bond.bondState.UNLOCK_TX_CONFIRMED=Unlock tx confirmed -# suppress inspection "UnusedProperty" -dao.bond.bondState.UNLOCKING=Bond unlocking -# suppress inspection "UnusedProperty" -dao.bond.bondState.UNLOCKED=Bond unlocked -# suppress inspection "UnusedProperty" -dao.bond.bondState.CONFISCATED=Bond confiscated # suppress inspection "UnusedProperty" dao.phase.UNDEFINED=Undefined diff --git a/core/src/main/resources/i18n/displayStrings_de.properties b/core/src/main/resources/i18n/displayStrings_de.properties index e764e977d71..d88e08a0353 100644 --- a/core/src/main/resources/i18n/displayStrings_de.properties +++ b/core/src/main/resources/i18n/displayStrings_de.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blindabstimmung Tx ID dao.results.votes.table.header.voteRevealTxId=Stimmoffenbarung Tx ID dao.results.votes.table.header.vote=Stimme -dao.bonding.menuItem.bondedRoles=Gekoppelte Rollen -dao.bonding.menuItem.reputation=BSQ sperren -dao.bonding.menuItem.bonds=BSQ entsperren -dao.bonding.reputation.header=BSQ sperren -dao.bonding.lock.amount=Betrag von BSQ zu sperren: -dao.bonding.lock.time=Entsperrung-Zeit in Blöcken: +dao.bond.menuItem.bondedRoles=Gekoppelte Rollen +dao.bond.menuItem.reputation=BSQ sperren +dao.bond.menuItem.bonds=BSQ entsperren +dao.bond.reputation.header=BSQ sperren +dao.bond.reputation.amount=Betrag von BSQ zu sperren: +dao.bond.reputation.time=Entsperrung-Zeit in Blöcken: dao.bonding.lock.type=Art der Kopplung: dao.bonding.lock.bondedRoles=Gekoppelte Rollen: dao.bonding.lock.setAmount=Betrag zum Sperren festlegen (Min­dest­be­trag ist {0}) dao.bonding.lock.setTime=Anzahl Blöcke, nachdem gesperrte Gelder nach dem Entsperrung-Transaktion wieder verfügbar werden ({0} - {1}) -dao.bonding.lock.lockupButton=Sperren -dao.bonding.lock.sendFunds.headline=Sperrung-Transaktion bestätigen -dao.bonding.lock.sendFunds.details=Gesperrter Betrag: {0}\nSperr Zeit: {1} Blöcke(Block)\n\nSind Sie sicher, dass Sie fortfahren möchten? +dao.bond.reputation.lockupButton=Sperren +dao.bond.reputation.lockup.headline=Sperrung-Transaktion bestätigen +dao.bond.reputation.lockup.details=Gesperrter Betrag: {0}\nSperr Zeit: {1} Blöcke(Block)\n\nSind Sie sicher, dass Sie fortfahren möchten? dao.bonding.unlock.time=Sperrzeit dao.bonding.unlock.unlock=Entsperren -dao.bonding.unlock.sendTx.headline=Entsperrung-Transaktion bestätigen -dao.bonding.unlock.sendTx.details=Entsperrter Betrag: {0}\nSperr Zeit: {1} Blöcke(Block)\n\nSind Sie sicher, dass Sie fortfahren möchten? -dao.bonding.dashboard.bondsHeadline=Gekoppelte BSQ -dao.bonding.dashboard.lockupAmount=Gesperrte Gelder -dao.bonding.dashboard.unlockingAmount=Entsperre Gelder (Warten Sie bis die Sperrzeit vorbei ist): +dao.bond.reputation.unlock.headline=Entsperrung-Transaktion bestätigen +dao.bond.reputation.unlock.details=Entsperrter Betrag: {0}\nSperr Zeit: {1} Blöcke(Block)\n\nSind Sie sicher, dass Sie fortfahren möchten? +dao.bond.dashboard.bondsHeadline=Gekoppelte BSQ +dao.bond.dashboard.lockupAmount=Gesperrte Gelder +dao.bond.dashboard.unlockingAmount=Entsperre Gelder (Warten Sie bis die Sperrzeit vorbei ist): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Gekoppelte Rolle @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domainnamen Inhaber # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed-Knoten Betreiber -dao.bond.bondedRoleType.details.header=Rollendetails -dao.bond.bondedRoleType.details.role=Rolle -dao.bond.bondedRoleType.details.requiredBond=Benötigt BSQ Kopplung -dao.bond.bondedRoleType.details.unlockTime=Entsperrung-Zeit in Blöcken -dao.bond.bondedRoleType.details.link=Link zur Rollenbeschreibung -dao.bond.bondedRoleType.details.isSingleton=Kann von mehreren Rollenhalter genommen werden -dao.bond.bondedRoleType.details.blocks={0} Blöcke +dao.bond.details.header=Rollendetails +dao.bond.details.role=Rolle +dao.bond.details.requiredBond=Benötigt BSQ Kopplung +dao.bond.details.unlockTime=Entsperrung-Zeit in Blöcken +dao.bond.details.link=Link zur Rollenbeschreibung +dao.bond.details.isSingleton=Kann von mehreren Rollenhalter genommen werden +dao.bond.details.blocks={0} Blöcke dao.bond.bondedRoles=Gekoppelte Rollen -dao.bond.table.column.header.name=Name -dao.bond.table.column.header.link=Konto -dao.bond.table.column.header.bondType=Rolle -dao.bond.table.column.header.startDate=Gestartet -dao.bond.table.column.header.lockupTxId=Sperrung Tx ID -dao.bond.table.column.header.revokeDate=Widerrufen -dao.bond.table.column.header.unlockTxId=Entsperrung Tx ID -dao.bond.table.column.header.bondState=Kopplungsstatus +dao.bond.table.column.name=Name +dao.bond.table.column.link=Konto +dao.bond.table.column.bondType=Rolle +dao.bond.table.column.startDate=Gestartet +dao.bond.table.column.lockupTxId=Sperrung Tx ID +dao.bond.table.column.revokeDate=Widerrufen +dao.bond.table.column.unlockTxId=Entsperrung Tx ID +dao.bond.table.column.bondState=Kopplungsstatus dao.bond.table.button.lockup=Sperren dao.bond.table.button.revoke=Widerrufen diff --git a/core/src/main/resources/i18n/displayStrings_el.properties b/core/src/main/resources/i18n/displayStrings_el.properties index afd3ec597f0..52f33eca1b4 100644 --- a/core/src/main/resources/i18n/displayStrings_el.properties +++ b/core/src/main/resources/i18n/displayStrings_el.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blind vote Tx ID dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Ψήφισε -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Lockup BSQ -dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.reputation.header=Lockup BSQ -dao.bonding.lock.amount=Amount of BSQ to lockup: -dao.bonding.lock.time=Unlock time in blocks: +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Lockup BSQ +dao.bond.menuItem.bonds=Unlock BSQ +dao.bond.reputation.header=Lockup BSQ +dao.bond.reputation.amount=Amount of BSQ to lockup: +dao.bond.reputation.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: dao.bonding.lock.bondedRoles=Bonded roles: dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=Ξεκλείδωσε -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds: -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds: +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domain name holder # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed node operator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=Ρόλος -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks +dao.bond.details.header=Role details +dao.bond.details.role=Ρόλος +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks dao.bond.bondedRoles=Bonded roles -dao.bond.table.column.header.name=Όνομα -dao.bond.table.column.header.link=Λογαριασμός -dao.bond.table.column.header.bondType=Ρόλος -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.name=Όνομα +dao.bond.table.column.link=Λογαριασμός +dao.bond.table.column.bondType=Ρόλος +dao.bond.table.column.startDate=Started +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.revokeDate=Revoked +dao.bond.table.column.unlockTxId=Unlock Tx ID +dao.bond.table.column.bondState=Bond state dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke diff --git a/core/src/main/resources/i18n/displayStrings_es.properties b/core/src/main/resources/i18n/displayStrings_es.properties index 6bcc7307f1e..cfb117c126f 100644 --- a/core/src/main/resources/i18n/displayStrings_es.properties +++ b/core/src/main/resources/i18n/displayStrings_es.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blind vote Tx ID dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=otar -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Lockup BSQ -dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.reputation.header=Lockup BSQ -dao.bonding.lock.amount=Amount of BSQ to lockup: -dao.bonding.lock.time=Unlock time in blocks: +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Lockup BSQ +dao.bond.menuItem.bonds=Unlock BSQ +dao.bond.reputation.header=Lockup BSQ +dao.bond.reputation.amount=Amount of BSQ to lockup: +dao.bond.reputation.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: dao.bonding.lock.bondedRoles=Bonded roles: dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=Desbloquear -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds: -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds: +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domain name holder # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed node operator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=Rol -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks +dao.bond.details.header=Role details +dao.bond.details.role=Rol +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks dao.bond.bondedRoles=Bonded roles -dao.bond.table.column.header.name=Nombre -dao.bond.table.column.header.link=Cuenta -dao.bond.table.column.header.bondType=Rol -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.name=Nombre +dao.bond.table.column.link=Cuenta +dao.bond.table.column.bondType=Rol +dao.bond.table.column.startDate=Started +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.revokeDate=Revoked +dao.bond.table.column.unlockTxId=Unlock Tx ID +dao.bond.table.column.bondState=Bond state dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke diff --git a/core/src/main/resources/i18n/displayStrings_fa.properties b/core/src/main/resources/i18n/displayStrings_fa.properties index 7449a1895b5..f5aed58798f 100644 --- a/core/src/main/resources/i18n/displayStrings_fa.properties +++ b/core/src/main/resources/i18n/displayStrings_fa.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blind vote Tx ID dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=رأی -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Lockup BSQ -dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.reputation.header=Lockup BSQ -dao.bonding.lock.amount=Amount of BSQ to lockup: -dao.bonding.lock.time=Unlock time in blocks: +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Lockup BSQ +dao.bond.menuItem.bonds=Unlock BSQ +dao.bond.reputation.header=Lockup BSQ +dao.bond.reputation.amount=Amount of BSQ to lockup: +dao.bond.reputation.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: dao.bonding.lock.bondedRoles=Bonded roles: dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=باز کردن -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds: -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds: +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domain name holder # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed node operator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=نقش -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks +dao.bond.details.header=Role details +dao.bond.details.role=نقش +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks dao.bond.bondedRoles=Bonded roles -dao.bond.table.column.header.name=نام -dao.bond.table.column.header.link=حساب -dao.bond.table.column.header.bondType=نقش -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.name=نام +dao.bond.table.column.link=حساب +dao.bond.table.column.bondType=نقش +dao.bond.table.column.startDate=Started +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.revokeDate=Revoked +dao.bond.table.column.unlockTxId=Unlock Tx ID +dao.bond.table.column.bondState=Bond state dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke diff --git a/core/src/main/resources/i18n/displayStrings_hu.properties b/core/src/main/resources/i18n/displayStrings_hu.properties index 54fd678fb20..5cad4dc375f 100644 --- a/core/src/main/resources/i18n/displayStrings_hu.properties +++ b/core/src/main/resources/i18n/displayStrings_hu.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blind vote Tx ID dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Szavazás -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Lockup BSQ -dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.reputation.header=Lockup BSQ -dao.bonding.lock.amount=Amount of BSQ to lockup: -dao.bonding.lock.time=Unlock time in blocks: +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Lockup BSQ +dao.bond.menuItem.bonds=Unlock BSQ +dao.bond.reputation.header=Lockup BSQ +dao.bond.reputation.amount=Amount of BSQ to lockup: +dao.bond.reputation.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: dao.bonding.lock.bondedRoles=Bonded roles: dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=Felnyit -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds: -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds: +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domain name holder # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed node operator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=Szerep -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks +dao.bond.details.header=Role details +dao.bond.details.role=Szerep +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks dao.bond.bondedRoles=Bonded roles -dao.bond.table.column.header.name=Név -dao.bond.table.column.header.link=Fiók -dao.bond.table.column.header.bondType=Szerep -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.name=Név +dao.bond.table.column.link=Fiók +dao.bond.table.column.bondType=Szerep +dao.bond.table.column.startDate=Started +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.revokeDate=Revoked +dao.bond.table.column.unlockTxId=Unlock Tx ID +dao.bond.table.column.bondState=Bond state dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke diff --git a/core/src/main/resources/i18n/displayStrings_pt.properties b/core/src/main/resources/i18n/displayStrings_pt.properties index d82f3316b21..fe3a89a7450 100644 --- a/core/src/main/resources/i18n/displayStrings_pt.properties +++ b/core/src/main/resources/i18n/displayStrings_pt.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blind vote Tx ID dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Votar -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Lockup BSQ -dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.reputation.header=Lockup BSQ -dao.bonding.lock.amount=Amount of BSQ to lockup: -dao.bonding.lock.time=Unlock time in blocks: +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Lockup BSQ +dao.bond.menuItem.bonds=Unlock BSQ +dao.bond.reputation.header=Lockup BSQ +dao.bond.reputation.amount=Amount of BSQ to lockup: +dao.bond.reputation.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: dao.bonding.lock.bondedRoles=Bonded roles: dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=Destravar -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds: -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds: +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domain name holder # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed node operator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=Função -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks +dao.bond.details.header=Role details +dao.bond.details.role=Função +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks dao.bond.bondedRoles=Bonded roles -dao.bond.table.column.header.name=Nome -dao.bond.table.column.header.link=Conta -dao.bond.table.column.header.bondType=Função -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.name=Nome +dao.bond.table.column.link=Conta +dao.bond.table.column.bondType=Função +dao.bond.table.column.startDate=Started +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.revokeDate=Revoked +dao.bond.table.column.unlockTxId=Unlock Tx ID +dao.bond.table.column.bondState=Bond state dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke diff --git a/core/src/main/resources/i18n/displayStrings_ro.properties b/core/src/main/resources/i18n/displayStrings_ro.properties index 45d61c69833..27bc9ea22cf 100644 --- a/core/src/main/resources/i18n/displayStrings_ro.properties +++ b/core/src/main/resources/i18n/displayStrings_ro.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blind vote Tx ID dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Votează -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Lockup BSQ -dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.reputation.header=Lockup BSQ -dao.bonding.lock.amount=Amount of BSQ to lockup: -dao.bonding.lock.time=Unlock time in blocks: +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Lockup BSQ +dao.bond.menuItem.bonds=Unlock BSQ +dao.bond.reputation.header=Lockup BSQ +dao.bond.reputation.amount=Amount of BSQ to lockup: +dao.bond.reputation.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: dao.bonding.lock.bondedRoles=Bonded roles: dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=Deblocare -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds: -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds: +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domain name holder # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed node operator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=Rol -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks +dao.bond.details.header=Role details +dao.bond.details.role=Rol +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks dao.bond.bondedRoles=Bonded roles -dao.bond.table.column.header.name=Nume -dao.bond.table.column.header.link=Cont -dao.bond.table.column.header.bondType=Rol -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.name=Nume +dao.bond.table.column.link=Cont +dao.bond.table.column.bondType=Rol +dao.bond.table.column.startDate=Started +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.revokeDate=Revoked +dao.bond.table.column.unlockTxId=Unlock Tx ID +dao.bond.table.column.bondState=Bond state dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke diff --git a/core/src/main/resources/i18n/displayStrings_ru.properties b/core/src/main/resources/i18n/displayStrings_ru.properties index 3260caafe5c..32c4a725179 100644 --- a/core/src/main/resources/i18n/displayStrings_ru.properties +++ b/core/src/main/resources/i18n/displayStrings_ru.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Транз. идент. слепо dao.results.votes.table.header.voteRevealTxId=Транз. идент. выявления голоса dao.results.votes.table.header.vote=Голосование -dao.bonding.menuItem.bondedRoles=Обеспеченные роли -dao.bonding.menuItem.reputation=Запереть BSQ -dao.bonding.menuItem.bonds=Разблокировать BSQ -dao.bonding.reputation.header=Запереть BSQ -dao.bonding.lock.amount=Запереть BSQ на сумму: -dao.bonding.lock.time=Срок разблокировки в блоках: +dao.bond.menuItem.bondedRoles=Обеспеченные роли +dao.bond.menuItem.reputation=Запереть BSQ +dao.bond.menuItem.bonds=Разблокировать BSQ +dao.bond.reputation.header=Запереть BSQ +dao.bond.reputation.amount=Запереть BSQ на сумму: +dao.bond.reputation.time=Срок разблокировки в блоках: dao.bonding.lock.type=Тир гарантийного депозита: dao.bonding.lock.bondedRoles=Обеспеченные роли: dao.bonding.lock.setAmount=Указать сумму BSQ для блокировки (мин. сумма {0}) dao.bonding.lock.setTime=Количество блоков, когда запертые средства становятся расходуемыми после транзакции разблокировки ({0} - {1}) -dao.bonding.lock.lockupButton=Запереть -dao.bonding.lock.sendFunds.headline=Подтвердить транзакцию блокировки -dao.bonding.lock.sendFunds.details=Запереть сумму: {0}\nВремя блокировки: {1} блок(ов) \n\nДействительно желаете продолжить? +dao.bond.reputation.lockupButton=Запереть +dao.bond.reputation.lockup.headline=Подтвердить транзакцию блокировки +dao.bond.reputation.lockup.details=Запереть сумму: {0}\nВремя блокировки: {1} блок(ов) \n\nДействительно желаете продолжить? dao.bonding.unlock.time=Время блокировки dao.bonding.unlock.unlock=Разблокировать -dao.bonding.unlock.sendTx.headline=Подтвердить транзакцию разблокировки -dao.bonding.unlock.sendTx.details=Отпереть сумму: {0}\nВремя блокировки: {1} блок(ов)\n\nДействительно желаете продолжить? -dao.bonding.dashboard.bondsHeadline=BSQ в гарантийных депозитах -dao.bonding.dashboard.lockupAmount=Запереть средства: -dao.bonding.dashboard.unlockingAmount=Разблокировка средств (дождитесь окончания времени блокировки): +dao.bond.reputation.unlock.headline=Подтвердить транзакцию разблокировки +dao.bond.reputation.unlock.details=Отпереть сумму: {0}\nВремя блокировки: {1} блок(ов)\n\nДействительно желаете продолжить? +dao.bond.dashboard.bondsHeadline=BSQ в гарантийных депозитах +dao.bond.dashboard.lockupAmount=Запереть средства: +dao.bond.dashboard.unlockingAmount=Разблокировка средств (дождитесь окончания времени блокировки): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Обеспеченная роль @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Владелец имени доме # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Оператор исходного узла -dao.bond.bondedRoleType.details.header=Подробности роли -dao.bond.bondedRoleType.details.role=Роль -dao.bond.bondedRoleType.details.requiredBond=Необходимый гарантийный депозит BSQ -dao.bond.bondedRoleType.details.unlockTime=Срок разблокировки в блоках -dao.bond.bondedRoleType.details.link=Ссылка на подробности роли -dao.bond.bondedRoleType.details.isSingleton=Может быть принято несколькими держателями роли -dao.bond.bondedRoleType.details.blocks={0} блоков +dao.bond.details.header=Подробности роли +dao.bond.details.role=Роль +dao.bond.details.requiredBond=Необходимый гарантийный депозит BSQ +dao.bond.details.unlockTime=Срок разблокировки в блоках +dao.bond.details.link=Ссылка на подробности роли +dao.bond.details.isSingleton=Может быть принято несколькими держателями роли +dao.bond.details.blocks={0} блоков dao.bond.bondedRoles=Обеспеченные роли -dao.bond.table.column.header.name=Имя -dao.bond.table.column.header.link=Счёт -dao.bond.table.column.header.bondType=Роль -dao.bond.table.column.header.startDate=Начато -dao.bond.table.column.header.lockupTxId=Транз. идент. блокировки -dao.bond.table.column.header.revokeDate=Аннулировано -dao.bond.table.column.header.unlockTxId=Транз. идент. разблокировки -dao.bond.table.column.header.bondState=Состояние гарантийного депозита +dao.bond.table.column.name=Имя +dao.bond.table.column.link=Счёт +dao.bond.table.column.bondType=Роль +dao.bond.table.column.startDate=Начато +dao.bond.table.column.lockupTxId=Транз. идент. блокировки +dao.bond.table.column.revokeDate=Аннулировано +dao.bond.table.column.unlockTxId=Транз. идент. разблокировки +dao.bond.table.column.bondState=Состояние гарантийного депозита dao.bond.table.button.lockup=Запереть dao.bond.table.button.revoke=Аннулировать diff --git a/core/src/main/resources/i18n/displayStrings_sr.properties b/core/src/main/resources/i18n/displayStrings_sr.properties index 235d12c4a41..8f2a7d366c9 100644 --- a/core/src/main/resources/i18n/displayStrings_sr.properties +++ b/core/src/main/resources/i18n/displayStrings_sr.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blind vote Tx ID dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Glasaj -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Lockup BSQ -dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.reputation.header=Lockup BSQ -dao.bonding.lock.amount=Amount of BSQ to lockup: -dao.bonding.lock.time=Unlock time in blocks: +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Lockup BSQ +dao.bond.menuItem.bonds=Unlock BSQ +dao.bond.reputation.header=Lockup BSQ +dao.bond.reputation.amount=Amount of BSQ to lockup: +dao.bond.reputation.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: dao.bonding.lock.bondedRoles=Bonded roles: dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=Otključaj -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds: -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds: +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domain name holder # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed node operator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=Uloga -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks +dao.bond.details.header=Role details +dao.bond.details.role=Uloga +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks dao.bond.bondedRoles=Bonded roles -dao.bond.table.column.header.name=Ime -dao.bond.table.column.header.link=Nalog -dao.bond.table.column.header.bondType=Uloga -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.name=Ime +dao.bond.table.column.link=Nalog +dao.bond.table.column.bondType=Uloga +dao.bond.table.column.startDate=Started +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.revokeDate=Revoked +dao.bond.table.column.unlockTxId=Unlock Tx ID +dao.bond.table.column.bondState=Bond state dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke diff --git a/core/src/main/resources/i18n/displayStrings_th.properties b/core/src/main/resources/i18n/displayStrings_th.properties index c4be425891a..fae44649ffd 100644 --- a/core/src/main/resources/i18n/displayStrings_th.properties +++ b/core/src/main/resources/i18n/displayStrings_th.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blind vote Tx ID dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=โหวต -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Lockup BSQ -dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.reputation.header=Lockup BSQ -dao.bonding.lock.amount=Amount of BSQ to lockup: -dao.bonding.lock.time=Unlock time in blocks: +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Lockup BSQ +dao.bond.menuItem.bonds=Unlock BSQ +dao.bond.reputation.header=Lockup BSQ +dao.bond.reputation.amount=Amount of BSQ to lockup: +dao.bond.reputation.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: dao.bonding.lock.bondedRoles=Bonded roles: dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=ปลดล็อค -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds: -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds: +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domain name holder # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed node operator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=บทบาท -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks +dao.bond.details.header=Role details +dao.bond.details.role=บทบาท +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks dao.bond.bondedRoles=Bonded roles -dao.bond.table.column.header.name=ชื่อ -dao.bond.table.column.header.link=บัญชี -dao.bond.table.column.header.bondType=บทบาท -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.name=ชื่อ +dao.bond.table.column.link=บัญชี +dao.bond.table.column.bondType=บทบาท +dao.bond.table.column.startDate=Started +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.revokeDate=Revoked +dao.bond.table.column.unlockTxId=Unlock Tx ID +dao.bond.table.column.bondState=Bond state dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke diff --git a/core/src/main/resources/i18n/displayStrings_vi.properties b/core/src/main/resources/i18n/displayStrings_vi.properties index 207dcc5cef1..a8bb6e85611 100644 --- a/core/src/main/resources/i18n/displayStrings_vi.properties +++ b/core/src/main/resources/i18n/displayStrings_vi.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blind vote Tx ID dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=Bỏ phiếu -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Lockup BSQ -dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.reputation.header=Lockup BSQ -dao.bonding.lock.amount=Amount of BSQ to lockup: -dao.bonding.lock.time=Unlock time in blocks: +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Lockup BSQ +dao.bond.menuItem.bonds=Unlock BSQ +dao.bond.reputation.header=Lockup BSQ +dao.bond.reputation.amount=Amount of BSQ to lockup: +dao.bond.reputation.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: dao.bonding.lock.bondedRoles=Bonded roles: dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=Mở khóa -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds: -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds: +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domain name holder # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed node operator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=Vai trò -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks +dao.bond.details.header=Role details +dao.bond.details.role=Vai trò +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks dao.bond.bondedRoles=Bonded roles -dao.bond.table.column.header.name=Tên -dao.bond.table.column.header.link=Tài khoản -dao.bond.table.column.header.bondType=Vai trò -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.name=Tên +dao.bond.table.column.link=Tài khoản +dao.bond.table.column.bondType=Vai trò +dao.bond.table.column.startDate=Started +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.revokeDate=Revoked +dao.bond.table.column.unlockTxId=Unlock Tx ID +dao.bond.table.column.bondState=Bond state dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke diff --git a/core/src/main/resources/i18n/displayStrings_zh.properties b/core/src/main/resources/i18n/displayStrings_zh.properties index a85664b837b..670e8c1c845 100644 --- a/core/src/main/resources/i18n/displayStrings_zh.properties +++ b/core/src/main/resources/i18n/displayStrings_zh.properties @@ -1121,26 +1121,26 @@ dao.results.votes.table.header.blindVoteTxId=Blind vote Tx ID dao.results.votes.table.header.voteRevealTxId=Vote reveal Tx ID dao.results.votes.table.header.vote=投票 -dao.bonding.menuItem.bondedRoles=Bonded roles -dao.bonding.menuItem.reputation=Lockup BSQ -dao.bonding.menuItem.bonds=Unlock BSQ -dao.bonding.reputation.header=Lockup BSQ -dao.bonding.lock.amount=Amount of BSQ to lockup: -dao.bonding.lock.time=Unlock time in blocks: +dao.bond.menuItem.bondedRoles=Bonded roles +dao.bond.menuItem.reputation=Lockup BSQ +dao.bond.menuItem.bonds=Unlock BSQ +dao.bond.reputation.header=Lockup BSQ +dao.bond.reputation.amount=Amount of BSQ to lockup: +dao.bond.reputation.time=Unlock time in blocks: dao.bonding.lock.type=Type of bond: dao.bonding.lock.bondedRoles=Bonded roles: dao.bonding.lock.setAmount=Set BSQ amount to lockup (min. amount is {0}) dao.bonding.lock.setTime=Number of blocks when locked funds become spendable after the unlock transaction ({0} - {1}) -dao.bonding.lock.lockupButton=Lockup -dao.bonding.lock.sendFunds.headline=Confirm lockup transaction -dao.bonding.lock.sendFunds.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.reputation.lockupButton=Lockup +dao.bond.reputation.lockup.headline=Confirm lockup transaction +dao.bond.reputation.lockup.details=Lockup amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? dao.bonding.unlock.time=Lock time dao.bonding.unlock.unlock=解锁 -dao.bonding.unlock.sendTx.headline=Confirm unlock transaction -dao.bonding.unlock.sendTx.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? -dao.bonding.dashboard.bondsHeadline=Bonded BSQ -dao.bonding.dashboard.lockupAmount=Lockup funds: -dao.bonding.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): +dao.bond.reputation.unlock.headline=Confirm unlock transaction +dao.bond.reputation.unlock.details=Unlock amount: {0}\nLockup time: {1} block(s)\n\nAre you sure you want to proceed? +dao.bond.dashboard.bondsHeadline=Bonded BSQ +dao.bond.dashboard.lockupAmount=Lockup funds: +dao.bond.dashboard.unlockingAmount=Unlocking funds (wait until lock time is over): # suppress inspection "UnusedProperty" dao.bond.lockupReason.BONDED_ROLE=Bonded role @@ -1153,23 +1153,23 @@ dao.bond.bondedRoleType.DOMAIN_NAME_HOLDER=Domain name holder # suppress inspection "UnusedProperty" dao.bond.bondedRoleType.SEED_NODE_OPERATOR=Seed node operator -dao.bond.bondedRoleType.details.header=Role details -dao.bond.bondedRoleType.details.role=角色 -dao.bond.bondedRoleType.details.requiredBond=Required BSQ bond -dao.bond.bondedRoleType.details.unlockTime=Unlock time in blocks -dao.bond.bondedRoleType.details.link=Link to role description -dao.bond.bondedRoleType.details.isSingleton=Can be taken by multiple role holders -dao.bond.bondedRoleType.details.blocks={0} blocks +dao.bond.details.header=Role details +dao.bond.details.role=角色 +dao.bond.details.requiredBond=Required BSQ bond +dao.bond.details.unlockTime=Unlock time in blocks +dao.bond.details.link=Link to role description +dao.bond.details.isSingleton=Can be taken by multiple role holders +dao.bond.details.blocks={0} blocks dao.bond.bondedRoles=Bonded roles -dao.bond.table.column.header.name=名称 -dao.bond.table.column.header.link=账户 -dao.bond.table.column.header.bondType=角色 -dao.bond.table.column.header.startDate=Started -dao.bond.table.column.header.lockupTxId=Lockup Tx ID -dao.bond.table.column.header.revokeDate=Revoked -dao.bond.table.column.header.unlockTxId=Unlock Tx ID -dao.bond.table.column.header.bondState=Bond state +dao.bond.table.column.name=名称 +dao.bond.table.column.link=账户 +dao.bond.table.column.bondType=角色 +dao.bond.table.column.startDate=Started +dao.bond.table.column.lockupTxId=Lockup Tx ID +dao.bond.table.column.revokeDate=Revoked +dao.bond.table.column.unlockTxId=Unlock Tx ID +dao.bond.table.column.bondState=Bond state dao.bond.table.button.lockup=Lockup dao.bond.table.button.revoke=Revoke diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index d6c74c11d74..ab11918f70c 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -83,11 +83,11 @@ public void initialize() { final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, bisq.desktop.main.dao.bonding.BondingView.class); dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), BondingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); - bondedRoles = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.bondedRoles"), + bondedRoles = new MenuItem(navigation, toggleGroup, Res.get("dao.bond.menuItem.bondedRoles"), RolesView.class, AwesomeIcon.SHIELD, baseNavPath); - reputation = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.reputation"), + reputation = new MenuItem(navigation, toggleGroup, Res.get("dao.bond.menuItem.reputation"), MyReputationView.class, AwesomeIcon.LOCK, baseNavPath); - bonds = new MenuItem(navigation, toggleGroup, Res.get("dao.bonding.menuItem.bonds"), + bonds = new MenuItem(navigation, toggleGroup, Res.get("dao.bond.menuItem.bonds"), BondsView.class, AwesomeIcon.UNLOCK, baseNavPath); leftVBox.getChildren().addAll(dashboard, bondedRoles, reputation, bonds); diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java index 5f1e927ffa4..d6a62dde6a4 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingViewUtils.java @@ -100,8 +100,8 @@ private void lockupBond(byte[] hash, Coin lockupAmount, int lockupTime, LockupRe Consumer resultHandler) { if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) { if (!DevEnv.isDevMode()) { - new Popup<>().headLine(Res.get("dao.bonding.lock.sendFunds.headline")) - .confirmation(Res.get("dao.bonding.lock.sendFunds.details", + new Popup<>().headLine(Res.get("dao.bond.reputation.lockup.headline")) + .confirmation(Res.get("dao.bond.reputation.lockup.details", bsqFormatter.formatCoinWithCode(lockupAmount), lockupTime )) @@ -143,8 +143,8 @@ public void unLock(String lockupTxId, Consumer resultHandler) { try { if (!DevEnv.isDevMode()) { - new Popup<>().headLine(Res.get("dao.bonding.unlock.sendTx.headline")) - .confirmation(Res.get("dao.bonding.unlock.sendTx.details", + new Popup<>().headLine(Res.get("dao.bond.reputation.unlock.headline")) + .confirmation(Res.get("dao.bond.reputation.unlock.details", bsqFormatter.formatCoinWithCode(unlockAmount), lockTime )) diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java index 7df722f15c2..99cb7529aab 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/bonds/BondsView.java @@ -92,7 +92,7 @@ private BondsView(BsqFormatter bsqFormatter, @Override public void initialize() { - tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.bonding.bonds.table.header")); + tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.bond.allBonds.header")); tableView.setItems(sortedList); addColumns(); @@ -160,7 +160,7 @@ public void updateItem(final BondListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockTime")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.lockTime")); column.setMinWidth(40); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @@ -180,7 +180,7 @@ public void updateItem(final BondListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondState")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.bondState")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(80); column.setCellFactory( @@ -203,7 +203,7 @@ public void updateItem(final BondListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondType")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.bondType")); column.setMinWidth(100); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @@ -224,7 +224,7 @@ public void updateItem(final BondListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.details")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.details")); column.setMinWidth(100); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @@ -245,7 +245,7 @@ public void updateItem(final BondListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockupDate")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.lockupDate")); column.setMinWidth(140); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @@ -265,7 +265,7 @@ public void updateItem(final BondListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.bonds.table.lockupTxId")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.lockupTxId")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(60); column.setCellFactory( diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java index 3366fcb2844..301034fc25a 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/reputation/MyReputationView.java @@ -130,21 +130,21 @@ private MyReputationView(BsqFormatter bsqFormatter, @Override public void initialize() { - addTitledGroupBg(root, gridRow, 3, Res.get("dao.bonding.reputation.header")); + addTitledGroupBg(root, gridRow, 3, Res.get("dao.bond.reputation.header")); - amountInputTextField = addInputTextField(root, gridRow, Res.get("dao.bonding.lock.amount"), + amountInputTextField = addInputTextField(root, gridRow, Res.get("dao.bond.reputation.amount"), Layout.FIRST_ROW_DISTANCE); amountInputTextField.setValidator(bsqValidator); - timeInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.time")); + timeInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bond.reputation.time")); timeInputTextField.setValidator(timeInputTextFieldValidator); - saltInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bonding.lock.salt")); + saltInputTextField = FormBuilder.addInputTextField(root, ++gridRow, Res.get("dao.bond.reputation.salt")); saltInputTextField.setValidator(hexStringValidator); - lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bonding.lock.lockupButton")); + lockupButton = addButtonAfterGroup(root, ++gridRow, Res.get("dao.bond.reputation.lockupButton")); - tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.bonding.reputation.list.header"), 20); + tableView = FormBuilder.addTableViewWithHeader(root, ++gridRow, Res.get("dao.bond.reputation.table.header"), 20); createColumns(); tableView.setItems(sortedList); @@ -308,7 +308,7 @@ public void updateItem(final MyReputationListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockTime")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.lockTime")); column.setMinWidth(60); column.setMaxWidth(column.getMinWidth()); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); @@ -330,7 +330,7 @@ public void updateItem(final MyReputationListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondState")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.bondState")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(120); column.setCellFactory( @@ -352,7 +352,7 @@ public void updateItem(MyReputationListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockupDate")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.lockupDate")); column.setMinWidth(140); column.setMaxWidth(column.getMinWidth()); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); @@ -375,7 +375,7 @@ public void updateItem(final MyReputationListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.bonds.table.lockupTxId")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.lockupTxId")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(80); column.setCellFactory( @@ -407,7 +407,7 @@ public void updateItem(final MyReputationListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.salt")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.reputation.salt")); column.setMinWidth(80); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { @@ -428,7 +428,7 @@ public void updateItem(final MyReputationListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bonding.unlock.hash")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.reputation.hash")); column.setMinWidth(80); column.setCellValueFactory((item) -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setCellFactory(new Callback<>() { diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java index b925e730ba0..b4c73989793 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RoleDetailsWindow.java @@ -51,7 +51,7 @@ public RoleDetailsWindow(BondedRoleType bondedRoleType, BsqFormatter bsqFormatte @Override public void show() { - headLine = Res.get("dao.bond.bondedRoleType.details.header"); + headLine = Res.get("dao.bond.details.header"); createGridPane(); addHeadLine(); @@ -74,19 +74,19 @@ protected void createGridPane() { } private void addContent() { - FormBuilder.addTopLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.bondedRoleType.details.role"), + FormBuilder.addTopLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.details.role"), bondedRoleType.getDisplayString()); - FormBuilder.addTopLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.bondedRoleType.details.requiredBond"), + FormBuilder.addTopLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.details.requiredBond"), bsqFormatter.formatCoinWithCode(Coin.valueOf(bondedRoleType.getRequiredBond()))); - FormBuilder.addTopLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.bondedRoleType.details.unlockTime"), - Res.get("dao.bond.bondedRoleType.details.blocks", bondedRoleType.getUnlockTimeInBlocks())); + FormBuilder.addTopLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.details.unlockTime"), + Res.get("dao.bond.details.blocks", bondedRoleType.getUnlockTimeInBlocks())); - FormBuilder.addLabelHyperlinkWithIcon(gridPane, ++rowIndex, Res.getWithCol("dao.bond.bondedRoleType.details.link"), + FormBuilder.addLabelHyperlinkWithIcon(gridPane, ++rowIndex, Res.getWithCol("dao.bond.details.link"), bondedRoleType.getLink(), bondedRoleType.getLink()); - FormBuilder.addTopLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.bondedRoleType.details.isSingleton"), + FormBuilder.addTopLabelTextField(gridPane, ++rowIndex, Res.getWithCol("dao.bond.details.isSingleton"), bsqFormatter.booleanToYesNo(bondedRoleType.isAllowMultipleHolders())); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesView.java index 2b81eb92ef7..34cf99c124a 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/roles/RolesView.java @@ -132,7 +132,7 @@ private void updateList() { private void createColumns() { TableColumn column; - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.name")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.name")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(80); column.setCellFactory( @@ -154,7 +154,7 @@ public void updateItem(final RolesListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.link")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.link")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(60); column.setCellFactory( @@ -185,7 +185,7 @@ public void updateItem(final RolesListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondType")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.bondType")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(80); column.setCellFactory( @@ -220,7 +220,7 @@ public void updateItem(final RolesListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.lockupTxId")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.lockupTxId")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(80); column.setCellFactory( @@ -260,7 +260,7 @@ public void updateItem(final RolesListItem item, boolean empty) { }); tableView.getColumns().add(column); - column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.header.bondState")); + column = new AutoTooltipTableColumn<>(Res.get("dao.bond.table.column.bondState")); column.setCellValueFactory(item -> new ReadOnlyObjectWrapper<>(item.getValue())); column.setMinWidth(120); column.setCellFactory( diff --git a/desktop/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java b/desktop/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java index 1e9372dff6b..cdb0942b0af 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/wallet/BsqBalanceUtil.java @@ -94,13 +94,13 @@ public int addGroup(GridPane gridPane, int gridRow) { public int addBondBalanceGroup(GridPane gridPane, int gridRow) { addTitledGroupBg(gridPane, ++gridRow, 2, - Res.get("dao.bonding.dashboard.bondsHeadline"), Layout.GROUP_DISTANCE); + Res.get("dao.bond.dashboard.bondsHeadline"), Layout.GROUP_DISTANCE); lockupAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(gridPane, gridRow, - Res.get("dao.bonding.dashboard.lockupAmount"), + Res.get("dao.bond.dashboard.lockupAmount"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; unlockingAmountTextField = FormBuilder.addTopLabelReadOnlyTextField(gridPane, ++gridRow, - Res.get("dao.bonding.dashboard.unlockingAmount")).second; + Res.get("dao.bond.dashboard.unlockingAmount")).second; return gridRow; } From 2b1405ecab742c1b8b1228305b5da99aa8f24462 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Wed, 7 Nov 2018 00:11:14 -0500 Subject: [PATCH 27/27] Change style for menu buttons in dao views --- .../bisq/desktop/components/MenuItem.java | 126 +++++++++++------- .../desktop/main/dao/bonding/BondingView.java | 21 ++- .../main/dao/governance/GovernanceView.java | 23 ++-- .../main/dao/wallet/BsqWalletView.java | 102 ++------------ 4 files changed, 114 insertions(+), 158 deletions(-) diff --git a/desktop/src/main/java/bisq/desktop/components/MenuItem.java b/desktop/src/main/java/bisq/desktop/components/MenuItem.java index 1cb87270aee..668d0924f02 100644 --- a/desktop/src/main/java/bisq/desktop/components/MenuItem.java +++ b/desktop/src/main/java/bisq/desktop/components/MenuItem.java @@ -19,87 +19,125 @@ import bisq.desktop.Navigation; import bisq.desktop.common.view.View; -import bisq.desktop.util.Colors; -import de.jensd.fx.fontawesome.AwesomeDude; -import de.jensd.fx.fontawesome.AwesomeIcon; +import com.jfoenix.controls.JFXButton; -import javafx.scene.control.Label; +import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; -import javafx.scene.paint.Paint; -import javafx.geometry.Insets; import javafx.geometry.Pos; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ChangeListener; import java.util.ArrayList; import java.util.List; -import org.jetbrains.annotations.NotNull; +import lombok.extern.slf4j.Slf4j; -public class MenuItem extends AutoTooltipToggleButton { +import org.jetbrains.annotations.NotNull; - private final ChangeListener selectedPropertyChangeListener; - private final ChangeListener disablePropertyChangeListener; +@Slf4j +public class MenuItem extends JFXButton implements Toggle { private final Navigation navigation; + private final ObjectProperty toggleGroupProperty = new SimpleObjectProperty<>(); private final Class viewClass; private final List> baseNavPath; + private final BooleanProperty selectedProperty = new SimpleBooleanProperty(); + private final ChangeListener listener; public MenuItem(Navigation navigation, ToggleGroup toggleGroup, String title, Class viewClass, - AwesomeIcon awesomeIcon, List> baseNavPath) { this.navigation = navigation; this.viewClass = viewClass; this.baseNavPath = baseNavPath; - setToggleGroup(toggleGroup); setLabelText(title); - setId("account-settings-item-background-active"); setPrefHeight(40); setPrefWidth(240); setAlignment(Pos.CENTER_LEFT); - Label icon = new Label(); - AwesomeDude.setIcon(icon, awesomeIcon); - icon.setTextFill(Paint.valueOf("#333")); - icon.setPadding(new Insets(0, 5, 0, 0)); - icon.setAlignment(Pos.CENTER); - icon.setMinWidth(25); - icon.setMaxWidth(25); - setGraphic(icon); - - selectedPropertyChangeListener = (ov, oldValue, newValue) -> { - if (newValue) { - setId("account-settings-item-background-selected"); - icon.setTextFill(Colors.BLUE); - } else { - setId("account-settings-item-background-active"); - icon.setTextFill(Paint.valueOf("#333")); - } - }; + toggleGroupProperty.set(toggleGroup); + toggleGroup.getToggles().add(this); - disablePropertyChangeListener = (ov, oldValue, newValue) -> { - if (newValue) { - setId("account-settings-item-background-disabled"); - icon.setTextFill(Paint.valueOf("#ccc")); + setUserData(getUid()); + + listener = (observable, oldValue, newValue) -> { + Object userData = newValue.getUserData(); + String uid = getUid(); + if (newValue.isSelected() && userData != null && userData.equals(uid)) { + getStyleClass().add("action-button"); } else { - setId("account-settings-item-background-active"); - icon.setTextFill(Paint.valueOf("#333")); + getStyleClass().remove("action-button"); } }; + + } + + /////////////////////////////////////////////////////////////////////////////////////////// + // Toggle implementation + /////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public ToggleGroup getToggleGroup() { + return toggleGroupProperty.get(); } + @Override + public void setToggleGroup(ToggleGroup toggleGroup) { + toggleGroupProperty.set(toggleGroup); + } + + @Override + public ObjectProperty toggleGroupProperty() { + return toggleGroupProperty; + } + + @Override + public boolean isSelected() { + return selectedProperty.get(); + } + + @Override + public BooleanProperty selectedProperty() { + return selectedProperty; + } + + @Override + public void setSelected(boolean selected) { + selectedProperty.set(selected); + } + + + /////////////////////////////////////////////////////////////////////////////////////////// + // API + /////////////////////////////////////////////////////////////////////////////////////////// + public void activate() { setOnAction((event) -> navigation.navigateTo(getNavPathClasses())); - selectedProperty().addListener(selectedPropertyChangeListener); - disableProperty().addListener(disablePropertyChangeListener); + toggleGroupProperty.get().selectedToggleProperty().addListener(listener); + } + + public void deactivate() { + setOnAction(null); + toggleGroupProperty.get().selectedToggleProperty().removeListener(listener); + } + + public void setLabelText(String value) { + setText(value); } + /////////////////////////////////////////////////////////////////////////////////////////// + // Private + /////////////////////////////////////////////////////////////////////////////////////////// + @NotNull private Class[] getNavPathClasses() { List> list = new ArrayList<>(baseNavPath); @@ -110,13 +148,7 @@ private Class[] getNavPathClasses() { return array; } - public void deactivate() { - setOnAction(null); - selectedProperty().removeListener(selectedPropertyChangeListener); - disableProperty().removeListener(disablePropertyChangeListener); - } - - public void setLabelText(String value) { - setText(value); + private String getUid() { + return viewClass.getName(); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java index ab11918f70c..ea6543bc6e8 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/bonding/BondingView.java @@ -36,8 +36,6 @@ import javax.inject.Inject; -import de.jensd.fx.fontawesome.AwesomeIcon; - import javafx.fxml.FXML; import javafx.scene.control.ToggleGroup; @@ -62,6 +60,7 @@ public class BondingView extends ActivatableViewAndModel { private AnchorPane content; private Class selectedViewClass; + private ToggleGroup toggleGroup; @Inject private BondingView(CachingViewLoader viewLoader, Navigation navigation) { @@ -79,16 +78,16 @@ public void initialize() { loadView(selectedViewClass); }; - ToggleGroup toggleGroup = new ToggleGroup(); + toggleGroup = new ToggleGroup(); final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, bisq.desktop.main.dao.bonding.BondingView.class); dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), - BondingDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); + BondingDashboardView.class, baseNavPath); bondedRoles = new MenuItem(navigation, toggleGroup, Res.get("dao.bond.menuItem.bondedRoles"), - RolesView.class, AwesomeIcon.SHIELD, baseNavPath); + RolesView.class, baseNavPath); reputation = new MenuItem(navigation, toggleGroup, Res.get("dao.bond.menuItem.reputation"), - MyReputationView.class, AwesomeIcon.LOCK, baseNavPath); + MyReputationView.class, baseNavPath); bonds = new MenuItem(navigation, toggleGroup, Res.get("dao.bond.menuItem.bonds"), - BondsView.class, AwesomeIcon.UNLOCK, baseNavPath); + BondsView.class, baseNavPath); leftVBox.getChildren().addAll(dashboard, bondedRoles, reputation, bonds); } @@ -130,9 +129,9 @@ private void loadView(Class viewClass) { View view = viewLoader.load(viewClass); content.getChildren().setAll(view.getRoot()); - if (view instanceof BondingDashboardView) dashboard.setSelected(true); - else if (view instanceof RolesView) bondedRoles.setSelected(true); - else if (view instanceof MyReputationView) reputation.setSelected(true); - else if (view instanceof BondsView) bonds.setSelected(true); + if (view instanceof BondingDashboardView) toggleGroup.selectToggle(dashboard); + else if (view instanceof RolesView) toggleGroup.selectToggle(bondedRoles); + else if (view instanceof MyReputationView) toggleGroup.selectToggle(reputation); + else if (view instanceof BondsView) toggleGroup.selectToggle(bonds); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/governance/GovernanceView.java b/desktop/src/main/java/bisq/desktop/main/dao/governance/GovernanceView.java index e70a4e83862..dd275f1ddc4 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/governance/GovernanceView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/governance/GovernanceView.java @@ -38,8 +38,6 @@ import javax.inject.Inject; -import de.jensd.fx.fontawesome.AwesomeIcon; - import javafx.fxml.FXML; import javafx.scene.control.ToggleGroup; @@ -68,6 +66,7 @@ public class GovernanceView extends ActivatableViewAndModel { private Class selectedViewClass; private ChangeListener phaseChangeListener; + private ToggleGroup toggleGroup; @Inject private GovernanceView(CachingViewLoader viewLoader, Navigation navigation, DaoFacade daoFacade) { @@ -93,16 +92,16 @@ public void initialize() { open.setLabelText(Res.get("dao.proposal.menuItem.browse")); }; - ToggleGroup toggleGroup = new ToggleGroup(); - final List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, GovernanceView.class); + toggleGroup = new ToggleGroup(); + List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, GovernanceView.class); dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), - GovernanceDashboardView.class, AwesomeIcon.DASHBOARD, baseNavPath); + GovernanceDashboardView.class, baseNavPath); make = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.make"), - MakeProposalView.class, AwesomeIcon.EDIT, baseNavPath); + MakeProposalView.class, baseNavPath); open = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.browse"), - ProposalsView.class, AwesomeIcon.LIST_UL, baseNavPath); + ProposalsView.class, baseNavPath); result = new MenuItem(navigation, toggleGroup, Res.get("dao.proposal.menuItem.result"), - VoteResultView.class, AwesomeIcon.LIST_ALT, baseNavPath); + VoteResultView.class, baseNavPath); leftVBox.getChildren().addAll(dashboard, make, open, result); } @@ -147,10 +146,10 @@ private void loadView(Class viewClass) { View view = viewLoader.load(viewClass); content.getChildren().setAll(view.getRoot()); - if (view instanceof GovernanceDashboardView) dashboard.setSelected(true); - else if (view instanceof MakeProposalView) make.setSelected(true); - else if (view instanceof ProposalsView) open.setSelected(true); - else if (view instanceof VoteResultView) result.setSelected(true); + if (view instanceof GovernanceDashboardView) toggleGroup.selectToggle(dashboard); + else if (view instanceof MakeProposalView) toggleGroup.selectToggle(make); + else if (view instanceof ProposalsView) toggleGroup.selectToggle(open); + else if (view instanceof VoteResultView) toggleGroup.selectToggle(result); } } diff --git a/desktop/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.java b/desktop/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.java index 58d259018bc..b7b037dffe4 100644 --- a/desktop/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.java +++ b/desktop/src/main/java/bisq/desktop/main/dao/wallet/BsqWalletView.java @@ -24,35 +24,27 @@ import bisq.desktop.common.view.View; import bisq.desktop.common.view.ViewLoader; import bisq.desktop.common.view.ViewPath; -import bisq.desktop.components.AutoTooltipToggleButton; +import bisq.desktop.components.MenuItem; import bisq.desktop.main.MainView; import bisq.desktop.main.dao.DaoView; import bisq.desktop.main.dao.wallet.dashboard.BsqDashboardView; import bisq.desktop.main.dao.wallet.receive.BsqReceiveView; import bisq.desktop.main.dao.wallet.send.BsqSendView; import bisq.desktop.main.dao.wallet.tx.BsqTxView; -import bisq.desktop.util.Colors; import bisq.core.app.BisqEnvironment; import bisq.core.locale.Res; import javax.inject.Inject; -import de.jensd.fx.fontawesome.AwesomeDude; -import de.jensd.fx.fontawesome.AwesomeIcon; - import javafx.fxml.FXML; -import javafx.scene.control.Label; import javafx.scene.control.ToggleGroup; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; -import javafx.scene.paint.Paint; - -import javafx.geometry.Insets; -import javafx.geometry.Pos; -import javafx.beans.value.ChangeListener; +import java.util.Arrays; +import java.util.List; @FxmlView public class BsqWalletView extends ActivatableViewAndModel { @@ -69,6 +61,7 @@ public class BsqWalletView extends ActivatableViewAndModel { private AnchorPane content; private Class selectedViewClass; + private ToggleGroup toggleGroup; @Inject private BsqWalletView(CachingViewLoader viewLoader, Navigation navigation) { @@ -86,11 +79,12 @@ public void initialize() { loadView(selectedViewClass); }; - ToggleGroup toggleGroup = new ToggleGroup(); - dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), BsqDashboardView.class, AwesomeIcon.DASHBOARD); - send = new MenuItem(navigation, toggleGroup, Res.get("dao.wallet.menuItem.send"), BsqSendView.class, AwesomeIcon.SIGNOUT); - receive = new MenuItem(navigation, toggleGroup, Res.get("dao.wallet.menuItem.receive"), BsqReceiveView.class, AwesomeIcon.SIGNIN); - transactions = new MenuItem(navigation, toggleGroup, Res.get("dao.wallet.menuItem.transactions"), BsqTxView.class, AwesomeIcon.TABLE); + toggleGroup = new ToggleGroup(); + List> baseNavPath = Arrays.asList(MainView.class, DaoView.class, BsqWalletView.class); + dashboard = new MenuItem(navigation, toggleGroup, Res.get("shared.dashboard"), BsqDashboardView.class, baseNavPath); + send = new MenuItem(navigation, toggleGroup, Res.get("dao.wallet.menuItem.send"), BsqSendView.class, baseNavPath); + receive = new MenuItem(navigation, toggleGroup, Res.get("dao.wallet.menuItem.receive"), BsqReceiveView.class, baseNavPath); + transactions = new MenuItem(navigation, toggleGroup, Res.get("dao.wallet.menuItem.transactions"), BsqTxView.class, baseNavPath); leftVBox.getChildren().addAll(dashboard, send, receive, transactions); // TODO just until DAO is enabled @@ -141,81 +135,13 @@ private void loadView(Class viewClass) { View view = viewLoader.load(viewClass); content.getChildren().setAll(view.getRoot()); - if (view instanceof BsqDashboardView) dashboard.setSelected(true); - else if (view instanceof BsqSendView) send.setSelected(true); - else if (view instanceof BsqReceiveView) receive.setSelected(true); - else if (view instanceof BsqTxView) transactions.setSelected(true); + if (view instanceof BsqDashboardView) toggleGroup.selectToggle(dashboard); + else if (view instanceof BsqSendView) toggleGroup.selectToggle(send); + else if (view instanceof BsqReceiveView) toggleGroup.selectToggle(receive); + else if (view instanceof BsqTxView) toggleGroup.selectToggle(transactions); } public Class getSelectedViewClass() { return selectedViewClass; } } - - -class MenuItem extends AutoTooltipToggleButton { - - private final ChangeListener selectedPropertyChangeListener; - private final ChangeListener disablePropertyChangeListener; - private final Navigation navigation; - private final Class viewClass; - - MenuItem(Navigation navigation, ToggleGroup toggleGroup, String title, Class viewClass, AwesomeIcon awesomeIcon) { - this.navigation = navigation; - this.viewClass = viewClass; - - setToggleGroup(toggleGroup); - setText(title); - setId("account-settings-item-background-active"); - setPrefHeight(40); - setPrefWidth(240); - setAlignment(Pos.CENTER_LEFT); - - Label icon = new Label(); - AwesomeDude.setIcon(icon, awesomeIcon); - if (viewClass == BsqReceiveView.class) { - icon.setRotate(180); - icon.setPadding(new Insets(0, 0, 0, 5)); - } else { - icon.setPadding(new Insets(0, 5, 0, 0)); - } - icon.setTextFill(Paint.valueOf("#333")); - icon.setAlignment(Pos.CENTER); - icon.setMinWidth(25); - icon.setMaxWidth(25); - setGraphic(icon); - - selectedPropertyChangeListener = (ov, oldValue, newValue) -> { - if (newValue) { - setId("account-settings-item-background-selected"); - icon.setTextFill(Colors.BLUE); - } else { - setId("account-settings-item-background-active"); - icon.setTextFill(Paint.valueOf("#333")); - } - }; - - disablePropertyChangeListener = (ov, oldValue, newValue) -> { - if (newValue) { - setId("account-settings-item-background-disabled"); - icon.setTextFill(Paint.valueOf("#ccc")); - } else { - setId("account-settings-item-background-active"); - icon.setTextFill(Paint.valueOf("#333")); - } - }; - } - - public void activate() { - setOnAction((event) -> navigation.navigateTo(MainView.class, DaoView.class, BsqWalletView.class, viewClass)); - selectedProperty().addListener(selectedPropertyChangeListener); - disableProperty().addListener(disablePropertyChangeListener); - } - - public void deactivate() { - setOnAction(null); - selectedProperty().removeListener(selectedPropertyChangeListener); - disableProperty().removeListener(disablePropertyChangeListener); - } -} -