mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Add supply change series.
Remove BsqSupplyChange. Use existing methods for supply calculation (existing method was incorrect as far I understand).
This commit is contained in:
parent
e08f7b6c09
commit
70e2f7c53b
@ -30,7 +30,6 @@ 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.BsqSupplyChange;
|
||||
import bisq.core.dao.state.model.governance.Cycle;
|
||||
import bisq.core.dao.state.model.governance.DecryptedBallotsWithMerits;
|
||||
import bisq.core.dao.state.model.governance.EvaluatedProposal;
|
||||
@ -1050,18 +1049,6 @@ public class DaoStateService implements DaoSetupService {
|
||||
return getTxOutputsByTxOutputType(TxOutputType.PROOF_OF_BURN_OP_RETURN_OUTPUT);
|
||||
}
|
||||
|
||||
public Stream<BsqSupplyChange> getBsqSupplyChanges() {
|
||||
Stream<BsqSupplyChange> issued = getIssuanceItems()
|
||||
.stream()
|
||||
.map(issuance -> new BsqSupplyChange(getBlockTime(issuance.getChainHeight()), issuance.getAmount()));
|
||||
|
||||
Stream<BsqSupplyChange> burned = getUnorderedTxStream()
|
||||
.filter(tx -> tx.getTxType() == TxType.PROOF_OF_BURN || tx.getTxType() == TxType.PAY_TRADE_FEE)
|
||||
.map(tx -> new BsqSupplyChange(tx.getTime(), -tx.getBurntBsq()));
|
||||
|
||||
return Stream.concat(issued, burned);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Listeners
|
||||
|
@ -1,30 +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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package bisq.core.dao.state.model.governance;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class BsqSupplyChange {
|
||||
@Getter
|
||||
long time;
|
||||
|
||||
@Getter
|
||||
long value;
|
||||
}
|
@ -2624,7 +2624,10 @@ dao.factsAndFigures.supply.totalBurned=Total burned BSQ
|
||||
dao.factsAndFigures.supply.totalBurned.tooltip=Total burned BSQ is the sum of BSQ trade fees and all 'Proof of Burn' transactions.\n\
|
||||
'Proof of Burn' transactions started in Dec 2019.
|
||||
dao.factsAndFigures.supply.totalSupply=Total BSQ supply
|
||||
dao.factsAndFigures.supply.totalSupply.tooltip=Total BSQ supply is the sum of all issues BSQ on top of the Genesis issuance and the total burned BSQ.
|
||||
dao.factsAndFigures.supply.totalSupply.tooltip=Total BSQ supply is 'Change of BSQ supply' + genesis issuance
|
||||
dao.factsAndFigures.supply.supplyChange=Change of BSQ supply
|
||||
dao.factsAndFigures.supply.supplyChange.tooltip=Change of BSQ supply reflects the change of all issued BSQ (compensation requests + reimbursement requests)\n\
|
||||
minus all burned BSQ (BSQ trade fees, Burned BSQ from BTC trade fees, burned BSQ from arbitration cases).
|
||||
dao.factsAndFigures.supply.chart.tradeFee.toolTip={0}\n{1}
|
||||
dao.factsAndFigures.supply.burnt=BSQ burnt
|
||||
|
||||
|
@ -1877,6 +1877,16 @@ textfield */
|
||||
-fx-background-color: -bs-chart-dao-line13, -bs-chart-dao-line13;
|
||||
}
|
||||
|
||||
|
||||
#charts-dao .default-color13.chart-series-line {
|
||||
-fx-stroke: -bs-chart-dao-line14;
|
||||
}
|
||||
|
||||
#charts-dao .default-color13.chart-line-symbol {
|
||||
-fx-background-color: -bs-chart-dao-line14, -bs-chart-dao-line14;
|
||||
}
|
||||
|
||||
|
||||
#charts-legend-toggle0 {
|
||||
-jfx-toggle-color: -bs-chart-dao-line1
|
||||
}
|
||||
@ -1929,6 +1939,10 @@ textfield */
|
||||
-jfx-toggle-color: -bs-chart-dao-line13;
|
||||
}
|
||||
|
||||
#charts-legend-toggle13 {
|
||||
-jfx-toggle-color: -bs-chart-dao-line14;
|
||||
}
|
||||
|
||||
#charts-dao .chart-series-line {
|
||||
-fx-stroke-width: 2px;
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ public abstract class ChartView<T extends ChartViewModel<? extends ChartDataMode
|
||||
hBox.setSpacing(10);
|
||||
collection.forEach(series -> {
|
||||
AutoTooltipSlideToggleButton toggle = new AutoTooltipSlideToggleButton();
|
||||
toggle.setMinWidth(220);
|
||||
toggle.setMinWidth(300);
|
||||
toggle.setAlignment(Pos.TOP_LEFT);
|
||||
String seriesId = getSeriesId(series);
|
||||
legendToggleBySeriesName.put(seriesId, toggle);
|
||||
|
@ -81,7 +81,7 @@ public class TemporalAdjusterModel {
|
||||
}
|
||||
}
|
||||
|
||||
protected TemporalAdjuster temporalAdjuster = Interval.DAY.getAdjuster();
|
||||
protected TemporalAdjuster temporalAdjuster = Interval.MONTH.getAdjuster();
|
||||
|
||||
public void setTemporalAdjuster(TemporalAdjuster temporalAdjuster) {
|
||||
this.temporalAdjuster = temporalAdjuster;
|
||||
|
@ -21,7 +21,6 @@ import bisq.desktop.components.chart.ChartDataModel;
|
||||
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.model.blockchain.Tx;
|
||||
import bisq.core.dao.state.model.governance.BsqSupplyChange;
|
||||
import bisq.core.dao.state.model.governance.Issuance;
|
||||
import bisq.core.dao.state.model.governance.IssuanceType;
|
||||
|
||||
@ -33,18 +32,15 @@ import javax.inject.Singleton;
|
||||
import java.time.Instant;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -56,7 +52,7 @@ public class DaoChartDataModel extends ChartDataModel {
|
||||
|
||||
private final DaoStateService daoStateService;
|
||||
private final Function<Issuance, Long> blockTimeOfIssuanceFunction;
|
||||
private Map<Long, Long> totalSupplyByInterval, totalIssuedByInterval, compensationByInterval,
|
||||
private Map<Long, Long> totalSupplyByInterval, supplyChangeByInterval, totalIssuedByInterval, compensationByInterval,
|
||||
reimbursementByInterval, reimbursementByIntervalAfterTagging,
|
||||
totalBurnedByInterval, bsqTradeFeeByInterval, bsqTradeFeeByIntervalAfterTagging,
|
||||
proofOfBurnByInterval, proofOfBurnFromBtcFeesByInterval, proofOfBurnFromArbitrationByInterval,
|
||||
@ -86,6 +82,7 @@ public class DaoChartDataModel extends ChartDataModel {
|
||||
@Override
|
||||
protected void invalidateCache() {
|
||||
totalSupplyByInterval = null;
|
||||
supplyChangeByInterval = null;
|
||||
totalIssuedByInterval = null;
|
||||
compensationByInterval = null;
|
||||
reimbursementByInterval = null;
|
||||
@ -134,18 +131,6 @@ public class DaoChartDataModel extends ChartDataModel {
|
||||
// Data for chart
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Map<Long, Long> getTotalSupplyByInterval() {
|
||||
if (totalSupplyByInterval != null) {
|
||||
return totalSupplyByInterval;
|
||||
}
|
||||
|
||||
totalSupplyByInterval = getTotalSupplyByInterval(
|
||||
daoStateService.getBsqSupplyChanges(),
|
||||
getDateFilter()
|
||||
);
|
||||
return totalSupplyByInterval;
|
||||
}
|
||||
|
||||
Map<Long, Long> getArbitrationDiffByInterval() {
|
||||
if (arbitrationDiffByInterval != null) {
|
||||
return arbitrationDiffByInterval;
|
||||
@ -294,33 +279,32 @@ public class DaoChartDataModel extends ChartDataModel {
|
||||
return proofOfBurnFromArbitrationByInterval;
|
||||
}
|
||||
|
||||
Map<Long, Long> getTotalSupplyByInterval() {
|
||||
if (totalSupplyByInterval != null) {
|
||||
return totalSupplyByInterval;
|
||||
}
|
||||
|
||||
long genesisValue = daoStateService.getGenesisTotalSupply().value;
|
||||
totalSupplyByInterval = getSupplyChangeByInterval().entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, e -> genesisValue + e.getValue()));
|
||||
return totalSupplyByInterval;
|
||||
}
|
||||
|
||||
Map<Long, Long> getSupplyChangeByInterval() {
|
||||
if (supplyChangeByInterval != null) {
|
||||
return supplyChangeByInterval;
|
||||
}
|
||||
|
||||
Map<Long, Long> issued = getTotalIssuedByInterval();
|
||||
Map<Long, Long> burned = getTotalBurnedByInterval();
|
||||
supplyChangeByInterval = getMergedMap(issued, burned, (a, b) -> a - b);
|
||||
return supplyChangeByInterval;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Aggregated collection data by interval
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private Map<Long, Long> getTotalSupplyByInterval(Stream<BsqSupplyChange> bsqSupplyChanges,
|
||||
Predicate<Long> dateFilter) {
|
||||
AtomicLong supply = new AtomicLong(DaoEconomyHistoricalData.TOTAL_SUPPLY_BY_CYCLE_DATE.get(1555340856L));
|
||||
|
||||
return bsqSupplyChanges
|
||||
.collect(Collectors.groupingBy(tx -> toTimeInterval(Instant.ofEpochMilli(tx.getTime()))))
|
||||
.entrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingLong(Map.Entry::getKey))
|
||||
.map(e -> new BsqSupplyChange(
|
||||
e.getKey(),
|
||||
supply.addAndGet(e
|
||||
.getValue()
|
||||
.stream()
|
||||
.mapToLong(BsqSupplyChange::getValue)
|
||||
.sum()
|
||||
))
|
||||
)
|
||||
.filter(t -> dateFilter.test(t.getTime()))
|
||||
.collect(Collectors.toMap(BsqSupplyChange::getTime, BsqSupplyChange::getValue));
|
||||
}
|
||||
|
||||
private Map<Long, Long> getIssuedBsqByInterval(Set<Issuance> issuanceSet, Predicate<Long> dateFilter) {
|
||||
return issuanceSet.stream()
|
||||
.collect(Collectors.groupingBy(issuance ->
|
||||
@ -377,14 +361,13 @@ public class DaoChartDataModel extends ChartDataModel {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// We did not use the reimbursement requests initially (but the compensation requests) because the limits
|
||||
// have been too low. Over time it got mixed in compensation requests and reimbursement requests.
|
||||
// To reflect that we use static data derived from the Github data. For new data we do not need that anymore
|
||||
// have been too low. Over time, it got mixed in compensation requests and reimbursement requests.
|
||||
// To reflect that we use static data derived from the GitHub data. For new data we do not need that anymore
|
||||
// as we have clearly separated that now. In case we have duplicate data for a months we use the static data.
|
||||
private static class DaoEconomyHistoricalData {
|
||||
// Key is start date of the cycle in epoch seconds, value is reimbursement amount
|
||||
public final static Map<Long, Long> REIMBURSEMENTS_BY_CYCLE_DATE = new HashMap<>();
|
||||
public final static Map<Long, Long> COMPENSATIONS_BY_CYCLE_DATE = new HashMap<>();
|
||||
public final static Map<Long, Long> TOTAL_SUPPLY_BY_CYCLE_DATE = new HashMap<>();
|
||||
|
||||
static {
|
||||
REIMBURSEMENTS_BY_CYCLE_DATE.put(1571349571L, 60760L);
|
||||
@ -420,8 +403,6 @@ public class DaoChartDataModel extends ChartDataModel {
|
||||
COMPENSATIONS_BY_CYCLE_DATE.put(1599175867L, 6086442L);
|
||||
COMPENSATIONS_BY_CYCLE_DATE.put(1601861442L, 5615973L);
|
||||
COMPENSATIONS_BY_CYCLE_DATE.put(1604845863L, 7782667L);
|
||||
|
||||
TOTAL_SUPPLY_BY_CYCLE_DATE.put(1555340856L, 372540100L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
private final LongProperty proofOfBurnAmountProperty = new SimpleLongProperty();
|
||||
|
||||
private XYChart.Series<Number, Number> seriesBsqTradeFee, seriesProofOfBurn, seriesCompensation,
|
||||
seriesReimbursement, seriesTotalSupply, seriesTotalIssued, seriesTotalBurned,
|
||||
seriesReimbursement, seriesTotalSupply, seriesSupplyChange, seriesTotalIssued, seriesTotalBurned,
|
||||
seriesTotalTradeFees, seriesProofOfBurnFromBtcFees,
|
||||
seriesProofOfBurnFromArbitration, seriesArbitrationDiff,
|
||||
seriesReimbursementAfterTagging, seriesBsqTradeFeeAfterTagging;
|
||||
@ -111,7 +111,7 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
}
|
||||
|
||||
protected Collection<XYChart.Series<Number, Number>> getSeriesForLegend5() {
|
||||
return List.of(seriesTotalSupply);
|
||||
return List.of(seriesSupplyChange, seriesTotalSupply);
|
||||
}
|
||||
|
||||
|
||||
@ -182,6 +182,10 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
seriesBsqTradeFeeAfterTagging = new XYChart.Series<>();
|
||||
seriesBsqTradeFeeAfterTagging.setName(Res.get("dao.factsAndFigures.supply.bsqTradeFeeAfterTagging"));
|
||||
seriesIndexMap.put(getSeriesId(seriesBsqTradeFeeAfterTagging), 12);
|
||||
|
||||
seriesSupplyChange = new XYChart.Series<>();
|
||||
seriesSupplyChange.setName(Res.get("dao.factsAndFigures.supply.supplyChange"));
|
||||
seriesIndexMap.put(getSeriesId(seriesSupplyChange), 13);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -209,7 +213,11 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
tooltip.setShowDelay(Duration.millis(100));
|
||||
Tooltip.install(toggle, tooltip);
|
||||
} else if (series.equals(seriesTotalSupply)) {
|
||||
Tooltip tooltip = new Tooltip(Res.get("dao.factsAndFigures.supply.totalSupply.tooltip"));
|
||||
Tooltip tooltip = new Tooltip(Res.get("dao.factsAndFigures.supply.supplyChange.tooltip"));
|
||||
tooltip.setShowDelay(Duration.millis(100));
|
||||
Tooltip.install(toggle, tooltip);
|
||||
} else if (series.equals(seriesSupplyChange)) {
|
||||
Tooltip tooltip = new Tooltip(Res.get("dao.factsAndFigures.supply.supplyChange.tooltip"));
|
||||
tooltip.setShowDelay(Duration.millis(100));
|
||||
Tooltip.install(toggle, tooltip);
|
||||
}
|
||||
@ -258,6 +266,11 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
allFutures.add(future);
|
||||
applyTotalSupply(future);
|
||||
}
|
||||
if (activeSeries.contains(seriesSupplyChange)) {
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
allFutures.add(future);
|
||||
applySupplyChange(future);
|
||||
}
|
||||
if (activeSeries.contains(seriesTotalTradeFees)) {
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
allFutures.add(future);
|
||||
@ -338,6 +351,15 @@ public class DaoChartView extends ChartView<DaoChartViewModel> {
|
||||
}));
|
||||
}
|
||||
|
||||
private void applySupplyChange(CompletableFuture<Boolean> completeFuture) {
|
||||
model.getSupplyChangeChartData()
|
||||
.whenComplete((data, t) ->
|
||||
mapToUserThread(() -> {
|
||||
seriesSupplyChange.getData().setAll(data);
|
||||
completeFuture.complete(true);
|
||||
}));
|
||||
}
|
||||
|
||||
private void applyTotalTradeFees(CompletableFuture<Boolean> completeFuture) {
|
||||
model.getTotalTradeFeesChartData()
|
||||
.whenComplete((data, t) ->
|
||||
|
@ -58,6 +58,10 @@ public class DaoChartViewModel extends ChartViewModel<DaoChartDataModel> {
|
||||
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getTotalSupplyByInterval()));
|
||||
}
|
||||
|
||||
CompletableFuture<List<XYChart.Data<Number, Number>>> getSupplyChangeChartData() {
|
||||
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getSupplyChangeByInterval()));
|
||||
}
|
||||
|
||||
CompletableFuture<List<XYChart.Data<Number, Number>>> getTotalTradeFeesChartData() {
|
||||
return CompletableFuture.supplyAsync(() -> toChartData(dataModel.getTotalTradeFeesByInterval()));
|
||||
}
|
||||
|
@ -152,6 +152,7 @@
|
||||
-bs-chart-dao-line11: #ff3939;
|
||||
-bs-chart-dao-line12: #1a6b66;
|
||||
-bs-chart-dao-line13: #b6239c;
|
||||
-bs-chart-dao-line14: #0052ff;
|
||||
|
||||
/* Monero orange color code */
|
||||
-xmr-orange: #f26822;
|
||||
|
@ -119,6 +119,7 @@
|
||||
-bs-chart-dao-line11: #ff3939;
|
||||
-bs-chart-dao-line12: #1a6b66;
|
||||
-bs-chart-dao-line13: #b6239c;
|
||||
-bs-chart-dao-line14: #0052ff;
|
||||
|
||||
/* Monero orange color code */
|
||||
-xmr-orange: #f26822;
|
||||
|
Loading…
Reference in New Issue
Block a user