mirror of
https://github.com/bisq-network/bisq.git
synced 2025-02-23 15:00:30 +01:00
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:
parent
823cec086c
commit
d5fc7cb97e
13 changed files with 121 additions and 85 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue