Use burnedBsq field in Tx for burnedFee and invalidatedBsq

In case of an invalid tx we burn all available BSQ input. We only know
that at parsing time. We renamed the burntFee field to burntBsq to make
it more generic and use it for the burnt fee in case if a normal tx and
as invalidatedBsq in case of an invalid tx.
This commit is contained in:
Manfred Karrer 2019-03-30 19:35:12 -05:00
parent 823cec086c
commit d5fc7cb97e
No known key found for this signature in database
GPG key ID: 401250966A6B2C46
13 changed files with 121 additions and 85 deletions

View file

@ -1420,7 +1420,7 @@ message Tx {
// Because of the way how PB implements inheritence we need to use the super class as type // Because of the way how PB implements inheritence we need to use the super class as type
repeated BaseTxOutput tx_outputs = 1; repeated BaseTxOutput tx_outputs = 1;
TxType txType = 2; TxType txType = 2;
int64 burnt_fee = 3; int64 burnt_bsq = 3;
} }
enum TxType { enum TxType {

View file

@ -544,8 +544,13 @@ public class DaoFacade implements DaoSetupService {
return daoStateService.getTotalAmountOfConfiscatedTxOutputs(); return daoStateService.getTotalAmountOfConfiscatedTxOutputs();
} }
public long getBurnedBsqOfAllInvalidTxs() { public long getTotalAmountOfInvalidatedBsq() {
return daoStateService.getBurnedBsqOfAllInvalidTxs(); return daoStateService.getTotalAmountOfInvalidatedBsq();
}
// Contains burned fee and invalidated bsq due invalid txs
public long getTotalAmountOfBurntBsq() {
return daoStateService.getTotalAmountOfBurntBsq();
} }
public List<Tx> getInvalidTxs() { public List<Tx> getInvalidTxs() {
@ -603,7 +608,7 @@ public class DaoFacade implements DaoSetupService {
return daoStateService.getIssuanceSet(issuanceType).size(); return daoStateService.getIssuanceSet(issuanceType).size();
} }
public Set<Tx> getFeeTxs() { public Set<Tx> getBurntFeeTxs() {
return daoStateService.getBurntFeeTxs(); return daoStateService.getBurntFeeTxs();
} }

View file

@ -145,13 +145,12 @@ public class DaoStateMonitoringService implements DaoSetupService, DaoStateListe
@Override @Override
public void onDaoStateChanged(Block block) { public void onDaoStateChanged(Block block) {
long genesisTotalSupply = daoStateService.getGenesisTotalSupply().value; long genesisTotalSupply = daoStateService.getGenesisTotalSupply().value;
long totalBurntFee = daoStateService.getTotalBurntFee();
long compensationIssuance = daoStateService.getTotalIssuedAmount(IssuanceType.COMPENSATION); long compensationIssuance = daoStateService.getTotalIssuedAmount(IssuanceType.COMPENSATION);
long reimbursementIssuance = daoStateService.getTotalIssuedAmount(IssuanceType.REIMBURSEMENT); long reimbursementIssuance = daoStateService.getTotalIssuedAmount(IssuanceType.REIMBURSEMENT);
long totalInvalidAmount = daoStateService.getBurnedBsqOfAllInvalidTxs(); long totalAmountOfBurntBsq = daoStateService.getTotalAmountOfBurntBsq();
// confiscated funds are still in the utxo set // confiscated funds are still in the utxo set
long sumUtxo = daoStateService.getUnspentTxOutputMap().values().stream().mapToLong(BaseTxOutput::getValue).sum(); long sumUtxo = daoStateService.getUnspentTxOutputMap().values().stream().mapToLong(BaseTxOutput::getValue).sum();
long sumBsq = genesisTotalSupply + compensationIssuance + reimbursementIssuance - totalBurntFee - totalInvalidAmount; long sumBsq = genesisTotalSupply + compensationIssuance + reimbursementIssuance - totalAmountOfBurntBsq;
if (sumBsq != sumUtxo) { if (sumBsq != sumUtxo) {
utxoMismatches.add(new UtxoMismatch(block.getHeight(), sumUtxo, sumBsq)); utxoMismatches.add(new UtxoMismatch(block.getHeight(), sumUtxo, sumBsq));

View file

@ -193,7 +193,8 @@ public class ExportJsonFilesService implements DaoSetupService {
getJsonTxOutputs(tx), getJsonTxOutputs(tx),
jsonTxType, jsonTxType,
jsonTxTypeDisplayString, jsonTxTypeDisplayString,
daoStateService.getBurntFee(tx.getId()), tx.getBurntFee(),
tx.getInvalidatedBsq(),
tx.getUnlockBlockHeight()); tx.getUnlockBlockHeight());
} }
@ -239,7 +240,8 @@ public class ExportJsonFilesService implements DaoSetupService {
btcAmount, btcAmount,
tx.getBlockHeight(), tx.getBlockHeight(),
isBsqTxOutputType, isBsqTxOutputType,
daoStateService.getBurntFee(tx.getId()), tx.getBurntFee(),
tx.getInvalidatedBsq(),
txOutput.getAddress(), txOutput.getAddress(),
scriptPubKey, scriptPubKey,
spentInfo, spentInfo,

View file

@ -36,9 +36,26 @@ class JsonTx {
private final JsonTxType txType; private final JsonTxType txType;
private final String txTypeDisplayString; private final String txTypeDisplayString;
private final long burntFee; private final long burntFee;
private final long invalidatedBsq;
// If not set it is -1. LockTime of 0 is a valid value. // If not set it is -1. LockTime of 0 is a valid value.
private final int unlockBlockHeight; private final int unlockBlockHeight;
JsonTx(String id, int blockHeight, String blockHash, long time, List<JsonTxInput> inputs,
List<JsonTxOutput> outputs, JsonTxType txType, String txTypeDisplayString, long burntFee,
long invalidatedBsq, int unlockBlockHeight) {
this.id = id;
this.blockHeight = blockHeight;
this.blockHash = blockHash;
this.time = time;
this.inputs = inputs;
this.outputs = outputs;
this.txType = txType;
this.txTypeDisplayString = txTypeDisplayString;
this.burntFee = burntFee;
this.invalidatedBsq = invalidatedBsq;
this.unlockBlockHeight = unlockBlockHeight;
}
// Enums must not be used directly for hashCode or equals as it delivers the Object.hashCode (internal address)! // 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. // The equals and hashCode methods cannot be overwritten in Enums.
@Override @Override
@ -50,6 +67,7 @@ class JsonTx {
return blockHeight == jsonTx.blockHeight && return blockHeight == jsonTx.blockHeight &&
time == jsonTx.time && time == jsonTx.time &&
burntFee == jsonTx.burntFee && burntFee == jsonTx.burntFee &&
invalidatedBsq == jsonTx.invalidatedBsq &&
unlockBlockHeight == jsonTx.unlockBlockHeight && unlockBlockHeight == jsonTx.unlockBlockHeight &&
Objects.equals(txVersion, jsonTx.txVersion) && Objects.equals(txVersion, jsonTx.txVersion) &&
Objects.equals(id, jsonTx.id) && Objects.equals(id, jsonTx.id) &&
@ -62,7 +80,7 @@ class JsonTx {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(super.hashCode(), txVersion, id, blockHeight, blockHash, time, inputs, outputs,
return Objects.hash(super.hashCode(), txVersion, id, blockHeight, blockHash, time, inputs, outputs, txType.name(), txTypeDisplayString, burntFee, unlockBlockHeight); txType.name(), txTypeDisplayString, burntFee, invalidatedBsq, unlockBlockHeight);
} }
} }

View file

@ -35,6 +35,7 @@ class JsonTxOutput {
private final int height; private final int height;
private final boolean isVerified; // isBsqTxOutputType private final boolean isVerified; // isBsqTxOutputType
private final long burntFee; private final long burntFee;
private final long invalidatedBsq;
private final String address; private final String address;
@Nullable @Nullable
private final JsonScriptPubKey scriptPubKey; private final JsonScriptPubKey scriptPubKey;
@ -50,6 +51,31 @@ class JsonTxOutput {
private final int lockTime; private final int lockTime;
private final boolean isUnspent; private final boolean isUnspent;
JsonTxOutput(String txId, int index, long bsqAmount, long btcAmount, int height, boolean isVerified, long burntFee,
long invalidatedBsq, String address, JsonScriptPubKey scriptPubKey, JsonSpentInfo spentInfo,
long time, JsonTxType txType, String txTypeDisplayString, JsonTxOutputType txOutputType,
String txOutputTypeDisplayString, String opReturn, int lockTime, boolean isUnspent) {
this.txId = txId;
this.index = index;
this.bsqAmount = bsqAmount;
this.btcAmount = btcAmount;
this.height = height;
this.isVerified = isVerified;
this.burntFee = burntFee;
this.invalidatedBsq = invalidatedBsq;
this.address = address;
this.scriptPubKey = scriptPubKey;
this.spentInfo = spentInfo;
this.time = time;
this.txType = txType;
this.txTypeDisplayString = txTypeDisplayString;
this.txOutputType = txOutputType;
this.txOutputTypeDisplayString = txOutputTypeDisplayString;
this.opReturn = opReturn;
this.lockTime = lockTime;
this.isUnspent = isUnspent;
}
String getId() { String getId() {
return txId + ":" + index; return txId + ":" + index;
} }
@ -68,6 +94,7 @@ class JsonTxOutput {
height == that.height && height == that.height &&
isVerified == that.isVerified && isVerified == that.isVerified &&
burntFee == that.burntFee && burntFee == that.burntFee &&
invalidatedBsq == that.invalidatedBsq &&
time == that.time && time == that.time &&
lockTime == that.lockTime && lockTime == that.lockTime &&
isUnspent == that.isUnspent && isUnspent == that.isUnspent &&
@ -86,6 +113,8 @@ class JsonTxOutput {
@Override @Override
public int hashCode() { 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); return Objects.hash(super.hashCode(), txVersion, txId, index, bsqAmount, btcAmount, height, isVerified,
burntFee, invalidatedBsq, address, scriptPubKey, spentInfo, time, txType.name(), txTypeDisplayString,
txOutputType, txOutputTypeDisplayString, opReturn, lockTime, isUnspent);
} }
} }

View file

@ -55,12 +55,7 @@ public class TempTx extends BaseTx {
// Mutable data // Mutable data
@Nullable @Nullable
private TxType txType; private TxType txType;
private long burntFee; private long burntBsq;
///////////////////////////////////////////////////////////////////////////////////////////
// PROTO BUFFER
///////////////////////////////////////////////////////////////////////////////////////////
private TempTx(String txVersion, private TempTx(String txVersion,
String id, String id,
@ -70,7 +65,7 @@ public class TempTx extends BaseTx {
ImmutableList<TxInput> txInputs, ImmutableList<TxInput> txInputs,
ImmutableList<TempTxOutput> tempTxOutputs, ImmutableList<TempTxOutput> tempTxOutputs,
@Nullable TxType txType, @Nullable TxType txType,
long burntFee) { long burntBsq) {
super(txVersion, super(txVersion,
id, id,
blockHeight, blockHeight,
@ -79,7 +74,7 @@ public class TempTx extends BaseTx {
txInputs); txInputs);
this.tempTxOutputs = tempTxOutputs; this.tempTxOutputs = tempTxOutputs;
this.txType = txType; this.txType = txType;
this.burntFee = burntFee; this.burntBsq = burntBsq;
} }
@Override @Override
@ -87,7 +82,7 @@ public class TempTx extends BaseTx {
return "TempTx{" + return "TempTx{" +
"\n txOutputs=" + tempTxOutputs + "\n txOutputs=" + tempTxOutputs +
",\n txType=" + txType + ",\n txType=" + txType +
",\n burntFee=" + burntFee + ",\n burntBsq=" + burntBsq +
"\n} " + super.toString(); "\n} " + super.toString();
} }
@ -103,13 +98,13 @@ public class TempTx extends BaseTx {
String name = txType != null ? txType.name() : ""; String name = txType != null ? txType.name() : "";
String name1 = tempTx.txType != null ? tempTx.txType.name() : ""; String name1 = tempTx.txType != null ? tempTx.txType.name() : "";
boolean isTxTypeEquals = name.equals(name1); boolean isTxTypeEquals = name.equals(name1);
return burntFee == tempTx.burntFee && return burntBsq == tempTx.burntBsq &&
Objects.equals(tempTxOutputs, tempTx.tempTxOutputs) && Objects.equals(tempTxOutputs, tempTx.tempTxOutputs) &&
isTxTypeEquals; isTxTypeEquals;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(super.hashCode(), tempTxOutputs, txType, burntFee); return Objects.hash(super.hashCode(), tempTxOutputs, txType, burntBsq);
} }
} }

View file

@ -142,7 +142,7 @@ public class TxParser {
long burntBsq = remainingInputValue + burntBondValue; long burntBsq = remainingInputValue + burntBondValue;
boolean hasBurntBsq = burntBsq > 0; boolean hasBurntBsq = burntBsq > 0;
if (hasBurntBsq) if (hasBurntBsq)
tempTx.setBurntFee(burntBsq); tempTx.setBurntBsq(burntBsq);
//**************************************************************************************** //****************************************************************************************
@ -161,9 +161,7 @@ public class TxParser {
if (isTxInvalid(tempTx, bsqOutputFound, hasBurntBond)) { if (isTxInvalid(tempTx, bsqOutputFound, hasBurntBond)) {
tempTx.setTxType(TxType.INVALID); tempTx.setTxType(TxType.INVALID);
// We consider all BSQ inputs as burned if the tx is invalid. // We consider all BSQ inputs as burned if the tx is invalid.
// It might be that the invalid tx had a BSQ fee. To avoid that we count the burned BSQ twice we set the tempTx.setBurntBsq(accumulatedInputValue);
// burnedFee to 0.
tempTx.setBurntFee(0);
txOutputParser.invalidateUTXOCandidates(); txOutputParser.invalidateUTXOCandidates();
log.warn("We have destroyed BSQ because of an invalid tx. Burned BSQ={}. tx={}", accumulatedInputValue / 100D, tempTx); log.warn("We have destroyed BSQ because of an invalid tx. Burned BSQ={}. tx={}", accumulatedInputValue / 100D, tempTx);
} else if (txType == TxType.IRREGULAR) { } else if (txType == TxType.IRREGULAR) {

View file

@ -21,7 +21,6 @@ import bisq.core.dao.DaoSetupService;
import bisq.core.dao.governance.bond.BondConsensus; import bisq.core.dao.governance.bond.BondConsensus;
import bisq.core.dao.governance.param.Param; import bisq.core.dao.governance.param.Param;
import bisq.core.dao.state.model.DaoState; import bisq.core.dao.state.model.DaoState;
import bisq.core.dao.state.model.blockchain.BaseTxOutput;
import bisq.core.dao.state.model.blockchain.Block; import bisq.core.dao.state.model.blockchain.Block;
import bisq.core.dao.state.model.blockchain.SpentInfo; import bisq.core.dao.state.model.blockchain.SpentInfo;
import bisq.core.dao.state.model.blockchain.Tx; import bisq.core.dao.state.model.blockchain.Tx;
@ -387,9 +386,7 @@ public class DaoStateService implements DaoSetupService {
} }
public long getTotalBurntFee() { public long getTotalBurntFee() {
return getTxStream() return getTxStream().mapToLong(Tx::getBurntFee).sum();
.mapToLong(Tx::getBurntFee)
.sum();
} }
public Set<Tx> getBurntFeeTxs() { public Set<Tx> getBurntFeeTxs() {
@ -816,25 +813,13 @@ public class DaoStateService implements DaoSetupService {
.sum(); .sum();
} }
public long getBurnedBsqOfAllInvalidTxs() { public long getTotalAmountOfInvalidatedBsq() {
return getTxStream() return getTxStream().mapToLong(Tx::getInvalidatedBsq).sum();
.filter(e -> e.getTxType() == TxType.INVALID)
.mapToLong(this::getBurnedBsqOfInvalidTx)
.sum();
} }
public long getBurnedBsqOfInvalidTx(Tx tx) { // Contains burnt fee and invalidated bsq due invalid txs
return tx.getTxInputs().stream() public long getTotalAmountOfBurntBsq() {
.map(TxInput::getConnectedTxOutputKey) return getTxStream().mapToLong(Tx::getBurntBsq).sum();
.flatMap(txOutputKey -> getTxOutput(txOutputKey).stream())
.filter(txOutput -> txOutput.getTxOutputType() == TxOutputType.GENESIS_OUTPUT ||
txOutput.getTxOutputType() == TxOutputType.BSQ_OUTPUT ||
txOutput.getTxOutputType() == TxOutputType.BLIND_VOTE_LOCK_STAKE_OUTPUT ||
txOutput.getTxOutputType() == TxOutputType.VOTE_REVEAL_UNLOCK_STAKE_OUTPUT ||
txOutput.getTxOutputType() == TxOutputType.LOCKUP_OUTPUT ||
txOutput.getTxOutputType() == TxOutputType.UNLOCK_OUTPUT)
.mapToLong(BaseTxOutput::getValue)
.sum();
} }
// Confiscate bond // Confiscate bond

View file

@ -57,13 +57,14 @@ public final class Tx extends BaseTx implements PersistablePayload, ImmutableDao
tempTx.getTxInputs(), tempTx.getTxInputs(),
txOutputs, txOutputs,
tempTx.getTxType(), tempTx.getTxType(),
tempTx.getBurntFee()); tempTx.getBurntBsq());
} }
private final ImmutableList<TxOutput> txOutputs; private final ImmutableList<TxOutput> txOutputs;
@Nullable @Nullable
private final TxType txType; private final TxType txType;
private final long burntFee; // Can be burned fee or in case of an invalid tx the burned BSQ from all BSQ inputs
private final long burntBsq;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -78,7 +79,7 @@ public final class Tx extends BaseTx implements PersistablePayload, ImmutableDao
ImmutableList<TxInput> txInputs, ImmutableList<TxInput> txInputs,
ImmutableList<TxOutput> txOutputs, ImmutableList<TxOutput> txOutputs,
@Nullable TxType txType, @Nullable TxType txType,
long burntFee) { long burntBsq) {
super(txVersion, super(txVersion,
id, id,
blockHeight, blockHeight,
@ -87,7 +88,7 @@ public final class Tx extends BaseTx implements PersistablePayload, ImmutableDao
txInputs); txInputs);
this.txOutputs = txOutputs; this.txOutputs = txOutputs;
this.txType = txType; this.txType = txType;
this.burntFee = burntFee; this.burntBsq = burntBsq;
} }
@ -97,7 +98,7 @@ public final class Tx extends BaseTx implements PersistablePayload, ImmutableDao
.addAllTxOutputs(txOutputs.stream() .addAllTxOutputs(txOutputs.stream()
.map(TxOutput::toProtoMessage) .map(TxOutput::toProtoMessage)
.collect(Collectors.toList())) .collect(Collectors.toList()))
.setBurntFee(burntFee); .setBurntBsq(burntBsq);
Optional.ofNullable(txType).ifPresent(txType -> builder.setTxType(txType.toProtoMessage())); Optional.ofNullable(txType).ifPresent(txType -> builder.setTxType(txType.toProtoMessage()));
return getBaseTxBuilder().setTx(builder).build(); return getBaseTxBuilder().setTx(builder).build();
} }
@ -122,7 +123,7 @@ public final class Tx extends BaseTx implements PersistablePayload, ImmutableDao
txInputs, txInputs,
outputs, outputs,
TxType.fromProto(protoTx.getTxType()), TxType.fromProto(protoTx.getTxType()),
protoTx.getBurntFee()); protoTx.getBurntBsq());
} }
@ -135,6 +136,18 @@ public final class Tx extends BaseTx implements PersistablePayload, ImmutableDao
} }
public long getBurntBsq() {
return burntBsq;
}
public long getBurntFee() {
return txType == TxType.INVALID ? 0 : burntBsq;
}
public long getInvalidatedBsq() {
return txType == TxType.INVALID ? burntBsq : 0;
}
public int getLockTime() { public int getLockTime() {
return getLockupOutput().getLockTime(); return getLockupOutput().getLockTime();
} }
@ -158,7 +171,7 @@ public final class Tx extends BaseTx implements PersistablePayload, ImmutableDao
return "Tx{" + return "Tx{" +
"\n txOutputs=" + txOutputs + "\n txOutputs=" + txOutputs +
",\n txType=" + txType + ",\n txType=" + txType +
",\n burntFee=" + burntFee + ",\n burntBsq=" + burntBsq +
"\n} " + super.toString(); "\n} " + super.toString();
} }
@ -175,13 +188,13 @@ public final class Tx extends BaseTx implements PersistablePayload, ImmutableDao
String name1 = tx.txType != null ? tx.txType.name() : ""; String name1 = tx.txType != null ? tx.txType.name() : "";
boolean isTxTypeEquals = name.equals(name1); boolean isTxTypeEquals = name.equals(name1);
return burntFee == tx.burntFee && return burntBsq == tx.burntBsq &&
Objects.equals(txOutputs, tx.txOutputs) && Objects.equals(txOutputs, tx.txOutputs) &&
isTxTypeEquals; isTxTypeEquals;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(super.hashCode(), txOutputs, txType, burntFee); return Objects.hash(super.hashCode(), txOutputs, txType, burntBsq);
} }
} }

View file

@ -291,16 +291,15 @@ public class BsqDashboardView extends ActivatableView<GridPane, Void> implements
Coin issuedAmountFromGenesis = daoFacade.getGenesisTotalSupply(); Coin issuedAmountFromGenesis = daoFacade.getGenesisTotalSupply();
Coin issuedAmountFromCompRequests = Coin.valueOf(daoFacade.getTotalIssuedAmount(IssuanceType.COMPENSATION)); Coin issuedAmountFromCompRequests = Coin.valueOf(daoFacade.getTotalIssuedAmount(IssuanceType.COMPENSATION));
Coin issuedAmountFromReimbursementRequests = Coin.valueOf(daoFacade.getTotalIssuedAmount(IssuanceType.REIMBURSEMENT)); Coin issuedAmountFromReimbursementRequests = Coin.valueOf(daoFacade.getTotalIssuedAmount(IssuanceType.REIMBURSEMENT));
Coin burntFee = Coin.valueOf(daoFacade.getTotalBurntFee());
Coin totalConfiscatedAmount = Coin.valueOf(daoFacade.getTotalAmountOfConfiscatedTxOutputs()); Coin totalConfiscatedAmount = Coin.valueOf(daoFacade.getTotalAmountOfConfiscatedTxOutputs());
Coin burnedBsqOfAllInvalidTxs = Coin.valueOf(daoFacade.getBurnedBsqOfAllInvalidTxs()); // Contains burnt fee and invalidated bsq due invalid txs
Coin totalAmountOfBurntBsq = Coin.valueOf(daoFacade.getTotalAmountOfBurntBsq());
availableAmount = issuedAmountFromGenesis availableAmount = issuedAmountFromGenesis
.add(issuedAmountFromCompRequests) .add(issuedAmountFromCompRequests)
.add(issuedAmountFromReimbursementRequests) .add(issuedAmountFromReimbursementRequests)
.subtract(burntFee) .subtract(totalAmountOfBurntBsq)
.subtract(totalConfiscatedAmount) .subtract(totalConfiscatedAmount);
.subtract(burnedBsqOfAllInvalidTxs);
availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount)); availableAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(availableAmount));
} }

View file

@ -27,7 +27,6 @@ import bisq.core.dao.state.DaoStateListener;
import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.model.blockchain.Block; import bisq.core.dao.state.model.blockchain.Block;
import bisq.core.dao.state.model.blockchain.Tx; import bisq.core.dao.state.model.blockchain.Tx;
import bisq.core.dao.state.model.blockchain.TxType;
import bisq.core.dao.state.model.governance.Issuance; import bisq.core.dao.state.model.governance.Issuance;
import bisq.core.dao.state.model.governance.IssuanceType; import bisq.core.dao.state.model.governance.IssuanceType;
import bisq.core.locale.GlobalSettings; import bisq.core.locale.GlobalSettings;
@ -90,8 +89,8 @@ public class SupplyView extends ActivatableView<GridPane, Void> implements DaoSt
private int gridRow = 0; private int gridRow = 0;
private TextField genesisIssueAmountTextField, compRequestIssueAmountTextField, reimbursementAmountTextField, private TextField genesisIssueAmountTextField, compRequestIssueAmountTextField, reimbursementAmountTextField,
burntAmountTextField, totalLockedUpAmountTextField, totalUnlockingAmountTextField, totalBurntFeeAmountTextField, totalLockedUpAmountTextField, totalUnlockingAmountTextField,
totalUnlockedAmountTextField, totalConfiscatedAmountTextField, burnedBsqOfAllInvalidTxsTextField; totalUnlockedAmountTextField, totalConfiscatedAmountTextField, totalAmountOfInvalidatedBsqTextField;
private XYChart.Series<Number, Number> seriesBSQIssued, seriesBSQBurnt; private XYChart.Series<Number, Number> seriesBSQIssued, seriesBSQBurnt;
private static final Map<String, TemporalAdjuster> ADJUSTERS = new HashMap<>(); private static final Map<String, TemporalAdjuster> ADJUSTERS = new HashMap<>();
@ -168,9 +167,9 @@ public class SupplyView extends ActivatableView<GridPane, Void> implements DaoSt
private void createSupplyReducedInformation() { private void createSupplyReducedInformation() {
addTitledGroupBg(root, ++gridRow, 2, Res.get("dao.factsAndFigures.supply.burnt"), Layout.GROUP_DISTANCE); addTitledGroupBg(root, ++gridRow, 2, Res.get("dao.factsAndFigures.supply.burnt"), Layout.GROUP_DISTANCE);
burntAmountTextField = addTopLabelReadOnlyTextField(root, gridRow, totalBurntFeeAmountTextField = addTopLabelReadOnlyTextField(root, gridRow,
Res.get("dao.factsAndFigures.supply.burntAmount"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; Res.get("dao.factsAndFigures.supply.burntAmount"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
burnedBsqOfAllInvalidTxsTextField = addTopLabelReadOnlyTextField(root, gridRow, 1, totalAmountOfInvalidatedBsqTextField = addTopLabelReadOnlyTextField(root, gridRow, 1,
Res.get("dao.factsAndFigures.supply.invalidTxs"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; Res.get("dao.factsAndFigures.supply.invalidTxs"), Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
seriesBSQBurnt = new XYChart.Series<>(); seriesBSQBurnt = new XYChart.Series<>();
@ -272,20 +271,20 @@ public class SupplyView extends ActivatableView<GridPane, Void> implements DaoSt
Coin issuedAmountFromReimbursementRequests = Coin.valueOf(daoFacade.getTotalIssuedAmount(IssuanceType.REIMBURSEMENT)); Coin issuedAmountFromReimbursementRequests = Coin.valueOf(daoFacade.getTotalIssuedAmount(IssuanceType.REIMBURSEMENT));
reimbursementAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromReimbursementRequests)); reimbursementAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(issuedAmountFromReimbursementRequests));
Coin burntFee = Coin.valueOf(daoFacade.getTotalBurntFee()); Coin totalBurntFee = Coin.valueOf(daoFacade.getTotalBurntFee());
Coin totalLockedUpAmount = Coin.valueOf(daoFacade.getTotalLockupAmount()); Coin totalLockedUpAmount = Coin.valueOf(daoFacade.getTotalLockupAmount());
Coin totalUnlockingAmount = Coin.valueOf(daoFacade.getTotalAmountOfUnLockingTxOutputs()); Coin totalUnlockingAmount = Coin.valueOf(daoFacade.getTotalAmountOfUnLockingTxOutputs());
Coin totalUnlockedAmount = Coin.valueOf(daoFacade.getTotalAmountOfUnLockedTxOutputs()); Coin totalUnlockedAmount = Coin.valueOf(daoFacade.getTotalAmountOfUnLockedTxOutputs());
Coin totalConfiscatedAmount = Coin.valueOf(daoFacade.getTotalAmountOfConfiscatedTxOutputs()); Coin totalConfiscatedAmount = Coin.valueOf(daoFacade.getTotalAmountOfConfiscatedTxOutputs());
Coin burnedBsqOfAllInvalidTxs = Coin.valueOf(daoFacade.getBurnedBsqOfAllInvalidTxs()); Coin totalAmountOfInvalidatedBsq = Coin.valueOf(daoFacade.getTotalAmountOfInvalidatedBsq());
burntAmountTextField.setText("-" + bsqFormatter.formatAmountWithGroupSeparatorAndCode(burntFee)); totalBurntFeeAmountTextField.setText("-" + bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalBurntFee));
totalLockedUpAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalLockedUpAmount)); totalLockedUpAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalLockedUpAmount));
totalUnlockingAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalUnlockingAmount)); totalUnlockingAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalUnlockingAmount));
totalUnlockedAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalUnlockedAmount)); totalUnlockedAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalUnlockedAmount));
totalConfiscatedAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalConfiscatedAmount)); totalConfiscatedAmountTextField.setText(bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalConfiscatedAmount));
String minusSign = burnedBsqOfAllInvalidTxs.isPositive() ? "-" : ""; String minusSign = totalAmountOfInvalidatedBsq.isPositive() ? "-" : "";
burnedBsqOfAllInvalidTxsTextField.setText(minusSign + bsqFormatter.formatAmountWithGroupSeparatorAndCode(burnedBsqOfAllInvalidTxs)); totalAmountOfInvalidatedBsqTextField.setText(minusSign + bsqFormatter.formatAmountWithGroupSeparatorAndCode(totalAmountOfInvalidatedBsq));
updateCharts(); updateCharts();
} }
@ -307,13 +306,7 @@ public class SupplyView extends ActivatableView<GridPane, Void> implements DaoSt
ZonedDateTime zonedDateTime = date.atStartOfDay(ZoneId.systemDefault()); ZonedDateTime zonedDateTime = date.atStartOfDay(ZoneId.systemDefault());
return new XYChart.Data<Number, Number>(zonedDateTime.toInstant().getEpochSecond(), burntBsqByMonth.get(date) return new XYChart.Data<Number, Number>(zonedDateTime.toInstant().getEpochSecond(), burntBsqByMonth.get(date)
.stream() .stream()
.mapToDouble(tx -> { .mapToDouble(Tx::getBurntBsq)
if (tx.getTxType() == TxType.INVALID) {
return daoStateService.getBurnedBsqOfInvalidTx(tx);
} else {
return tx.getBurntFee();
}
})
.sum() .sum()
); );
}) })

View file

@ -51,10 +51,10 @@ public class BSQTransactionsView extends ActivatableView<GridPane, Void> impleme
private final Preferences preferences; private final Preferences preferences;
private int gridRow = 0; private int gridRow = 0;
private TextField allTxTextField, burntTxTextField, private TextField allTxTextField, burntFeeTxsTextField,
utxoTextField, compensationIssuanceTxTextField, utxoTextField, compensationIssuanceTxTextField,
reimbursementIssuanceTxTextField, reimbursementIssuanceTxTextField,
invalidTxTextField; invalidTxsTextField;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, lifecycle // Constructor, lifecycle
@ -107,9 +107,9 @@ public class BSQTransactionsView extends ActivatableView<GridPane, Void> impleme
reimbursementIssuanceTxTextField = addTopLabelReadOnlyTextField(root, gridRow, columnIndex, reimbursementIssuanceTxTextField = addTopLabelReadOnlyTextField(root, gridRow, columnIndex,
Res.get("dao.factsAndFigures.transactions.reimbursementIssuanceTx"), Res.get("dao.factsAndFigures.transactions.reimbursementIssuanceTx"),
Layout.FIRST_ROW_AND_GROUP_DISTANCE).second; Layout.FIRST_ROW_AND_GROUP_DISTANCE).second;
burntTxTextField = addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex, burntFeeTxsTextField = addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex,
Res.get("dao.factsAndFigures.transactions.burntTx")).second; Res.get("dao.factsAndFigures.transactions.burntTx")).second;
invalidTxTextField = addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex, invalidTxsTextField = addTopLabelReadOnlyTextField(root, ++gridRow, columnIndex,
Res.get("dao.factsAndFigures.transactions.invalidTx")).second; Res.get("dao.factsAndFigures.transactions.invalidTx")).second;
} }
@ -145,8 +145,8 @@ public class BSQTransactionsView extends ActivatableView<GridPane, Void> impleme
utxoTextField.setText(String.valueOf(daoFacade.getUnspentTxOutputs().size())); utxoTextField.setText(String.valueOf(daoFacade.getUnspentTxOutputs().size()));
compensationIssuanceTxTextField.setText(String.valueOf(daoFacade.getNumIssuanceTransactions(IssuanceType.COMPENSATION))); compensationIssuanceTxTextField.setText(String.valueOf(daoFacade.getNumIssuanceTransactions(IssuanceType.COMPENSATION)));
reimbursementIssuanceTxTextField.setText(String.valueOf(daoFacade.getNumIssuanceTransactions(IssuanceType.REIMBURSEMENT))); reimbursementIssuanceTxTextField.setText(String.valueOf(daoFacade.getNumIssuanceTransactions(IssuanceType.REIMBURSEMENT)));
burntTxTextField.setText(String.valueOf(daoFacade.getFeeTxs().size())); burntFeeTxsTextField.setText(String.valueOf(daoFacade.getBurntFeeTxs().size()));
invalidTxTextField.setText(String.valueOf(daoFacade.getInvalidTxs().size())); invalidTxsTextField.setText(String.valueOf(daoFacade.getInvalidTxs().size()));
} }
} }