diff --git a/core/src/main/java/bisq/core/dao/DaoModule.java b/core/src/main/java/bisq/core/dao/DaoModule.java
index 293a609630a..48d1c3727be 100644
--- a/core/src/main/java/bisq/core/dao/DaoModule.java
+++ b/core/src/main/java/bisq/core/dao/DaoModule.java
@@ -53,7 +53,7 @@
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.JsonBlockChainExporter;
+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;
@@ -99,7 +99,7 @@ protected void configure() {
bind(BsqState.class).in(Singleton.class);
bind(BsqStateService.class).in(Singleton.class);
bind(SnapshotManager.class).in(Singleton.class);
- bind(JsonBlockChainExporter.class).in(Singleton.class);
+ bind(ExportJsonFilesService.class).in(Singleton.class);
// Period
bind(CycleService.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 f09246988d6..5c4740bb2c9 100644
--- a/core/src/main/java/bisq/core/dao/DaoSetup.java
+++ b/core/src/main/java/bisq/core/dao/DaoSetup.java
@@ -25,6 +25,7 @@
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.state.BsqStateService;
import bisq.core.dao.state.period.CycleService;
@@ -35,7 +36,6 @@
/**
* 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 BsqStateService bsqStateService;
@@ -47,6 +47,7 @@ public class DaoSetup {
private final VoteRevealService voteRevealService;
private final VoteResultService voteResultService;
private final BsqNode bsqNode;
+ private final ExportJsonFilesService exportJsonFilesService;
@Inject
public DaoSetup(BsqNodeProvider bsqNodeProvider,
@@ -57,7 +58,8 @@ public DaoSetup(BsqNodeProvider bsqNodeProvider,
BlindVoteListService blindVoteListService,
MyBlindVoteListService myBlindVoteListService,
VoteRevealService voteRevealService,
- VoteResultService voteResultService) {
+ VoteResultService voteResultService,
+ ExportJsonFilesService exportJsonFilesService) {
this.bsqStateService = bsqStateService;
this.cycleService = cycleService;
this.proposalService = proposalService;
@@ -66,6 +68,7 @@ public DaoSetup(BsqNodeProvider bsqNodeProvider,
this.myBlindVoteListService = myBlindVoteListService;
this.voteRevealService = voteRevealService;
this.voteResultService = voteResultService;
+ this.exportJsonFilesService = exportJsonFilesService;
bsqNode = bsqNodeProvider.getBsqNode();
}
@@ -81,6 +84,7 @@ public void onAllServicesInitialized(ErrorMessageHandler errorMessageHandler) {
myBlindVoteListService.addListeners();
voteRevealService.addListeners();
voteResultService.addListeners();
+ exportJsonFilesService.addListeners();
bsqStateService.start();
cycleService.start();
@@ -90,6 +94,7 @@ public void onAllServicesInitialized(ErrorMessageHandler errorMessageHandler) {
myBlindVoteListService.start();
voteRevealService.start();
voteResultService.start();
+ exportJsonFilesService.start();
bsqNode.setErrorMessageHandler(errorMessageHandler);
bsqNode.start();
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 05b9ac7db8b..5843368accd 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
@@ -19,7 +19,7 @@
import bisq.core.dao.node.BsqNode;
import bisq.core.dao.node.full.network.FullNodeNetworkService;
-import bisq.core.dao.node.json.JsonBlockChainExporter;
+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.BsqStateService;
@@ -49,7 +49,7 @@ public class FullNode extends BsqNode {
private final RpcService rpcService;
private final FullNodeNetworkService fullNodeNetworkService;
- private final JsonBlockChainExporter jsonBlockChainExporter;
+ private final ExportJsonFilesService exportJsonFilesService;
private boolean addBlockHandlerAdded;
@@ -64,12 +64,12 @@ public FullNode(BlockParser blockParser,
SnapshotManager snapshotManager,
P2PService p2PService,
RpcService rpcService,
- JsonBlockChainExporter jsonBlockChainExporter,
+ ExportJsonFilesService exportJsonFilesService,
FullNodeNetworkService fullNodeNetworkService) {
super(blockParser, bsqStateService, snapshotManager, p2PService);
this.rpcService = rpcService;
- this.jsonBlockChainExporter = jsonBlockChainExporter;
+ this.exportJsonFilesService = exportJsonFilesService;
this.fullNodeNetworkService = fullNodeNetworkService;
}
@@ -88,7 +88,7 @@ public void start() {
}
public void shutDown() {
- jsonBlockChainExporter.shutDown();
+ exportJsonFilesService.shutDown();
fullNodeNetworkService.shutDown();
}
@@ -147,7 +147,7 @@ private void addBlockHandler() {
}
private void onNewBlock(Block block) {
- jsonBlockChainExporter.maybeExport();
+ exportJsonFilesService.exportToJson();
if (p2pNetworkReady && parseBlockchainComplete)
fullNodeNetworkService.publishNewBlock(block);
diff --git a/core/src/main/java/bisq/core/dao/node/json/ExportJsonFilesService.java b/core/src/main/java/bisq/core/dao/node/json/ExportJsonFilesService.java
new file mode 100644
index 00000000000..bd64c30e9c6
--- /dev/null
+++ b/core/src/main/java/bisq/core/dao/node/json/ExportJsonFilesService.java
@@ -0,0 +1,235 @@
+/*
+ * 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.node.json;
+
+import bisq.core.dao.DaoOptionKeys;
+import bisq.core.dao.DaoSetupService;
+import bisq.core.dao.state.BsqState;
+import bisq.core.dao.state.BsqStateService;
+import bisq.core.dao.state.blockchain.PubKeyScript;
+import bisq.core.dao.state.blockchain.TxOutput;
+import bisq.core.dao.state.blockchain.TxType;
+
+import bisq.common.storage.FileUtil;
+import bisq.common.storage.JsonFileManager;
+import bisq.common.storage.Storage;
+import bisq.common.util.Utilities;
+
+import org.bitcoinj.core.Utils;
+
+import com.google.inject.Inject;
+
+import javax.inject.Named;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+import java.nio.file.Paths;
+
+import java.io.File;
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.jetbrains.annotations.NotNull;
+
+@Slf4j
+public class ExportJsonFilesService implements DaoSetupService {
+ private final BsqStateService bsqStateService;
+ private final File storageDir;
+ private final boolean dumpBlockchainData;
+
+ private final ListeningExecutorService executor = Utilities.getListeningExecutorService("JsonExporter",
+ 1, 1, 1200);
+ private JsonFileManager txFileManager, txOutputFileManager, bsqStateFileManager;
+
+ @Inject
+ public ExportJsonFilesService(BsqStateService bsqStateService,
+ @Named(Storage.STORAGE_DIR) File storageDir,
+ @Named(DaoOptionKeys.DUMP_BLOCKCHAIN_DATA) boolean dumpBlockchainData) {
+ this.bsqStateService = bsqStateService;
+ this.storageDir = storageDir;
+ this.dumpBlockchainData = dumpBlockchainData;
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////////////
+ // DaoSetupService
+ ///////////////////////////////////////////////////////////////////////////////////////////
+
+ @Override
+ public void addListeners() {
+ }
+
+ @Override
+ public void start() {
+ if (dumpBlockchainData) {
+ File jsonDir = new File(Paths.get(storageDir.getAbsolutePath(), "json").toString());
+ File txDir = new File(Paths.get(storageDir.getAbsolutePath(), "json", "tx").toString());
+ File txOutputDir = new File(Paths.get(storageDir.getAbsolutePath(), "json", "txo").toString());
+ File bsqStateDir = new File(Paths.get(storageDir.getAbsolutePath(), "json", "all").toString());
+ try {
+ if (txDir.exists())
+ FileUtil.deleteDirectory(txDir);
+ if (txOutputDir.exists())
+ FileUtil.deleteDirectory(txOutputDir);
+ if (bsqStateDir.exists())
+ FileUtil.deleteDirectory(bsqStateDir);
+ if (jsonDir.exists())
+ FileUtil.deleteDirectory(jsonDir);
+ } catch (IOException e) {
+ log.error(e.toString());
+ e.printStackTrace();
+ }
+
+ if (!jsonDir.mkdir())
+ log.warn("make jsonDir failed.\njsonDir=" + jsonDir.getAbsolutePath());
+
+ if (!txDir.mkdir())
+ log.warn("make txDir failed.\ntxDir=" + txDir.getAbsolutePath());
+
+ if (!txOutputDir.mkdir())
+ log.warn("make txOutputDir failed.\ntxOutputDir=" + txOutputDir.getAbsolutePath());
+
+ if (!bsqStateDir.mkdir())
+ log.warn("make bsqStateDir failed.\nbsqStateDir=" + bsqStateDir.getAbsolutePath());
+
+ txFileManager = new JsonFileManager(txDir);
+ txOutputFileManager = new JsonFileManager(txOutputDir);
+ bsqStateFileManager = new JsonFileManager(bsqStateDir);
+ }
+ }
+
+ public void shutDown() {
+ if (dumpBlockchainData) {
+ txFileManager.shutDown();
+ txOutputFileManager.shutDown();
+ bsqStateFileManager.shutDown();
+ }
+ }
+
+ public void exportToJson() {
+ if (dumpBlockchainData) {
+ // We store the data we need once we write the data to disk (in the thread) locally.
+ // Access to bsqStateService is single threaded, we must not access bsqStateService from the thread.
+ List allJsonTxOutputs = new ArrayList<>();
+ List jsonTxs = new ArrayList<>();
+ BsqState bsqStateClone = bsqStateService.getClone();
+
+ bsqStateService.getTxStream().forEach(tx -> {
+ List jsonTxOutputs = new ArrayList<>();
+ String txId = tx.getId();
+ long time = tx.getTime();
+ int blockHeight = tx.getBlockHeight();
+ long burntFee = bsqStateService.getBurntFee(tx.getId());
+ TxType txType = tx.getTxType();
+ JsonTxType jsonTxType = txType != null ? JsonTxType.valueOf(txType.name()) : null;
+ String jsonTxTypeDisplayString = jsonTxType != null ? jsonTxType.getDisplayString() : "";
+ tx.getTxOutputs().forEach(txOutput -> {
+ boolean isBsqTxOutputType = bsqStateService.isBsqTxOutputType(txOutput);
+ long bsqAmount = isBsqTxOutputType ? txOutput.getValue() : 0;
+ long btcAmount = !isBsqTxOutputType ? txOutput.getValue() : 0;
+ PubKeyScript pubKeyScript = txOutput.getPubKeyScript();
+ JsonScriptPubKey scriptPubKey = pubKeyScript != null ? new JsonScriptPubKey(pubKeyScript) : null;
+ JsonSpentInfo spentInfo = bsqStateService.getSpentInfo(txOutput).map(JsonSpentInfo::new).orElse(null);
+ JsonTxOutputType txOutputType = JsonTxOutputType.valueOf(txOutput.getTxOutputType().name());
+ int lockTime = txOutput.getLockTime();
+ String opReturn = txOutput.getOpReturnData() != null ? Utils.HEX.encode(txOutput.getOpReturnData()) : null;
+ JsonTxOutput jsonTxOutput = new JsonTxOutput(txId,
+ txOutput.getIndex(),
+ bsqAmount,
+ btcAmount,
+ blockHeight,
+ isBsqTxOutputType,
+ burntFee,
+ txOutput.getAddress(),
+ scriptPubKey,
+ spentInfo,
+ time,
+ jsonTxType,
+ jsonTxTypeDisplayString,
+ txOutputType,
+ txOutputType.getDisplayString(),
+ opReturn,
+ lockTime
+ );
+ jsonTxOutputs.add(jsonTxOutput);
+ allJsonTxOutputs.add(jsonTxOutput);
+ });
+
+ List inputs = tx.getTxInputs().stream()
+ .map(txInput -> {
+ Optional optionalTxOutput = bsqStateService.getConnectedTxOutput(txInput);
+ if (optionalTxOutput.isPresent()) {
+ TxOutput connectedTxOutput = optionalTxOutput.get();
+ boolean isBsqTxOutputType = bsqStateService.isBsqTxOutputType(connectedTxOutput);
+ return new JsonTxInput(txInput.getConnectedTxOutputIndex(),
+ txInput.getConnectedTxOutputTxId(),
+ connectedTxOutput.getValue(),
+ isBsqTxOutputType,
+ connectedTxOutput.getAddress(),
+ time);
+ } else {
+ return null;
+ }
+ })
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+
+ JsonTx jsonTx = new JsonTx(txId,
+ blockHeight,
+ tx.getBlockHash(),
+ time,
+ inputs,
+ jsonTxOutputs,
+ jsonTxType,
+ jsonTxTypeDisplayString,
+ burntFee,
+ tx.getUnlockBlockHeight());
+
+ jsonTxs.add(jsonTx);
+ });
+
+ ListenableFuture future = executor.submit(() -> {
+ bsqStateFileManager.writeToDisc(Utilities.objectToJson(bsqStateClone), "BsqStateService");
+ allJsonTxOutputs.forEach(jsonTxOutput -> txOutputFileManager.writeToDisc(Utilities.objectToJson(jsonTxOutput), jsonTxOutput.getId()));
+ jsonTxs.forEach(jsonTx -> txFileManager.writeToDisc(Utilities.objectToJson(jsonTx), jsonTx.getId()));
+ return null;
+ });
+
+ Futures.addCallback(future, new FutureCallback<>() {
+ public void onSuccess(Void ignore) {
+ log.trace("onSuccess");
+ }
+
+ public void onFailure(@NotNull Throwable throwable) {
+ log.error(throwable.toString());
+ throwable.printStackTrace();
+ }
+ });
+ }
+ }
+}
diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonBlockChainExporter.java b/core/src/main/java/bisq/core/dao/node/json/JsonBlockChainExporter.java
deleted file mode 100644
index 25745e3556b..00000000000
--- a/core/src/main/java/bisq/core/dao/node/json/JsonBlockChainExporter.java
+++ /dev/null
@@ -1,206 +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.node.json;
-
-import bisq.core.dao.DaoOptionKeys;
-import bisq.core.dao.state.BsqState;
-import bisq.core.dao.state.BsqStateService;
-import bisq.core.dao.state.blockchain.PubKeyScript;
-import bisq.core.dao.state.blockchain.SpentInfo;
-import bisq.core.dao.state.blockchain.Tx;
-import bisq.core.dao.state.blockchain.TxOutput;
-import bisq.core.dao.state.blockchain.TxType;
-
-import bisq.common.storage.FileUtil;
-import bisq.common.storage.JsonFileManager;
-import bisq.common.storage.Storage;
-import bisq.common.util.Utilities;
-
-import org.bitcoinj.core.Utils;
-
-import com.google.inject.Inject;
-
-import javax.inject.Named;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-
-import java.nio.file.Paths;
-
-import java.io.File;
-import java.io.IOException;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-import lombok.extern.slf4j.Slf4j;
-
-import org.jetbrains.annotations.NotNull;
-
-@Slf4j
-public class JsonBlockChainExporter {
- private final BsqStateService bsqStateService;
- private final boolean dumpBlockchainData;
-
- private final ListeningExecutorService executor = Utilities.getListeningExecutorService("JsonExporter", 1, 1, 1200);
- private JsonFileManager txFileManager, txOutputFileManager, jsonFileManager;
-
- @Inject
- public JsonBlockChainExporter(BsqStateService bsqStateService,
- @Named(Storage.STORAGE_DIR) File storageDir,
- @Named(DaoOptionKeys.DUMP_BLOCKCHAIN_DATA) boolean dumpBlockchainData) {
- this.bsqStateService = bsqStateService;
- this.dumpBlockchainData = dumpBlockchainData;
-
- init(storageDir, dumpBlockchainData);
- }
-
- private void init(@Named(Storage.STORAGE_DIR) File storageDir, @Named(DaoOptionKeys.DUMP_BLOCKCHAIN_DATA) boolean dumpBlockchainData) {
- if (dumpBlockchainData) {
- File txDir = new File(Paths.get(storageDir.getAbsolutePath(), "tx").toString());
- File txOutputDir = new File(Paths.get(storageDir.getAbsolutePath(), "txo").toString());
- File blockchainDir = new File(Paths.get(storageDir.getAbsolutePath(), "all").toString());
- try {
- if (txDir.exists())
- FileUtil.deleteDirectory(txDir);
- if (txOutputDir.exists())
- FileUtil.deleteDirectory(txOutputDir);
- if (blockchainDir.exists())
- FileUtil.deleteDirectory(blockchainDir);
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- if (!txDir.mkdir())
- log.warn("make txDir failed.\ntxDir=" + txDir.getAbsolutePath());
-
- if (!txOutputDir.mkdir())
- log.warn("make txOutputDir failed.\ntxOutputDir=" + txOutputDir.getAbsolutePath());
-
- if (!blockchainDir.mkdir())
- log.warn("make blockchainDir failed.\nblockchainDir=" + blockchainDir.getAbsolutePath());
-
- txFileManager = new JsonFileManager(txDir);
- txOutputFileManager = new JsonFileManager(txOutputDir);
- jsonFileManager = new JsonFileManager(blockchainDir);
- }
- }
-
- public void shutDown() {
- if (dumpBlockchainData) {
- txFileManager.shutDown();
- txOutputFileManager.shutDown();
- jsonFileManager.shutDown();
- }
- }
-
- public void maybeExport() {
- if (dumpBlockchainData) {
- ListenableFuture future = executor.submit(() -> {
- final BsqState bsqStateClone = bsqStateService.getClone();
- Map txMap = bsqStateService.getBlocksFromState(bsqStateClone).stream()
- .filter(Objects::nonNull)
- .flatMap(block -> block.getTxs().stream())
- .collect(Collectors.toMap(Tx::getId, tx -> tx));
- for (Tx tx : txMap.values()) {
- String txId = tx.getId();
- final Optional optionalTxType = bsqStateService.getOptionalTxType(txId);
- optionalTxType.ifPresent(txType1 -> {
- JsonTxType txType = txType1 != TxType.UNDEFINED_TX_TYPE ?
- JsonTxType.valueOf(txType1.name()) : null;
- List outputs = new ArrayList<>();
- tx.getTxOutputs().forEach(txOutput -> {
- final Optional optionalSpentInfo = bsqStateService.getSpentInfo(txOutput);
- final boolean isBsqOutput = bsqStateService.isBsqTxOutputType(txOutput);
- final PubKeyScript pubKeyScript = txOutput.getPubKeyScript();
- final JsonTxOutput outputForJson = new JsonTxOutput(txId,
- txOutput.getIndex(),
- isBsqOutput ? txOutput.getValue() : 0,
- !isBsqOutput ? txOutput.getValue() : 0,
- txOutput.getBlockHeight(),
- isBsqOutput,
- bsqStateService.getBurntFee(tx.getId()),
- txOutput.getAddress(),
- pubKeyScript != null ? new JsonScriptPubKey(pubKeyScript) : null,
- optionalSpentInfo.map(JsonSpentInfo::new).orElse(null),
- tx.getTime(),
- txType,
- txType != null ? txType.getDisplayString() : "",
- txOutput.getOpReturnData() != null ? Utils.HEX.encode(txOutput.getOpReturnData()) : null
- );
- outputs.add(outputForJson);
- txOutputFileManager.writeToDisc(Utilities.objectToJson(outputForJson), outputForJson.getId());
- });
-
-
- List inputs = tx.getTxInputs().stream()
- .map(txInput -> {
- Optional optionalTxOutput = bsqStateService.getConnectedTxOutput(txInput);
- if (optionalTxOutput.isPresent()) {
- final TxOutput connectedTxOutput = optionalTxOutput.get();
- final boolean isBsqOutput = bsqStateService.isBsqTxOutputType(connectedTxOutput);
- return new JsonTxInput(txInput.getConnectedTxOutputIndex(),
- txInput.getConnectedTxOutputTxId(),
- connectedTxOutput.getValue(),
- isBsqOutput,
- connectedTxOutput.getAddress(),
- tx.getTime());
- } else {
- return null;
- }
- })
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
-
- final JsonTx jsonTx = new JsonTx(txId,
- tx.getBlockHeight(),
- tx.getBlockHash(),
- tx.getTime(),
- inputs,
- outputs,
- txType,
- txType != null ? txType.getDisplayString() : "",
- bsqStateService.getBurntFee(tx.getId()));
-
- txFileManager.writeToDisc(Utilities.objectToJson(jsonTx), txId);
- });
- }
-
- jsonFileManager.writeToDisc(Utilities.objectToJson(bsqStateClone), "BsqStateService");
- return null;
- });
-
- Futures.addCallback(future, new FutureCallback() {
- public void onSuccess(Void ignore) {
- log.trace("onSuccess");
- }
-
- public void onFailure(@NotNull Throwable throwable) {
- log.error(throwable.toString());
- throwable.printStackTrace();
- }
- });
- }
- }
-}
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 5ea7d38e4b2..e68e74859ef 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
@@ -23,9 +23,8 @@
import lombok.Value;
-//TODO sync up with data model
@Value
-public class JsonTx {
+class JsonTx {
private final String txVersion = Version.BSQ_TX_VERSION;
private final String id;
private final int blockHeight;
@@ -36,4 +35,6 @@ public class JsonTx {
private final JsonTxType txType;
private final String txTypeDisplayString;
private final long burntFee;
+ // If not set it is -1. LockTime of 0 is a valid value.
+ private final int unlockBlockHeight;
}
diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonTxInput.java b/core/src/main/java/bisq/core/dao/node/json/JsonTxInput.java
index 329e75a1e01..684d6031d89 100644
--- a/core/src/main/java/bisq/core/dao/node/json/JsonTxInput.java
+++ b/core/src/main/java/bisq/core/dao/node/json/JsonTxInput.java
@@ -21,14 +21,13 @@
import javax.annotation.concurrent.Immutable;
-//TODO sync up with data model
@Value
@Immutable
-public class JsonTxInput {
- private final int spendingTxOutputIndex;
- private final String spendingTxId;
+class JsonTxInput {
+ private final int spendingTxOutputIndex; // connectedTxOutputIndex
+ private final String spendingTxId; // connectedTxOutputTxId
private final long bsqAmount;
- private final boolean isVerified;
+ private final boolean isVerified; // isBsqTxOutputType
private final String address;
private final long time;
}
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 069066a645a..c19b7bd198d 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
@@ -21,7 +21,8 @@
import lombok.Value;
-//TODO sync up with data model
+import javax.annotation.Nullable;
+
@Value
public class JsonTxOutput {
private final String txVersion = Version.BSQ_TX_VERSION;
@@ -30,15 +31,21 @@ public class JsonTxOutput {
private final long bsqAmount;
private final long btcAmount;
private final int height;
- private final boolean isVerified;
+ private final boolean isVerified; // isBsqTxOutputType
private final long burntFee;
private final String address;
+ @Nullable
private final JsonScriptPubKey scriptPubKey;
+ @Nullable
private final JsonSpentInfo spentInfo;
private final long time;
private final JsonTxType txType;
private final String txTypeDisplayString;
+ private final JsonTxOutputType txOutputType; // new
+ private final String txOutputTypeDisplayString; // new
+ @Nullable
private final String opReturn;
+ private final int lockTime; // new
public String getId() {
return txId + ":" + outputIndex;
diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonTxOutputType.java b/core/src/main/java/bisq/core/dao/node/json/JsonTxOutputType.java
new file mode 100644
index 00000000000..018a95f9c4d
--- /dev/null
+++ b/core/src/main/java/bisq/core/dao/node/json/JsonTxOutputType.java
@@ -0,0 +1,47 @@
+/*
+ * 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.node.json;
+
+import lombok.Getter;
+
+// Need to be in sync with TxOutputType
+public enum JsonTxOutputType {
+ UNDEFINED("Undefined"),
+ GENESIS_OUTPUT("Genesis"),
+ BSQ_OUTPUT("BSQ"),
+ BTC_OUTPUT("BTC"),
+ PROPOSAL_OP_RETURN_OUTPUT("Proposal opReturn"),
+ COMP_REQ_OP_RETURN_OUTPUT("Compensation request opReturn"),
+ CONFISCATE_BOND_OP_RETURN_OUTPUT("Confiscate bond opReturn"),
+ ISSUANCE_CANDIDATE_OUTPUT("Issuance candidate"),
+ BLIND_VOTE_LOCK_STAKE_OUTPUT("Blind vote lock stake"),
+ BLIND_VOTE_OP_RETURN_OUTPUT("Blind vote opReturn"),
+ VOTE_REVEAL_UNLOCK_STAKE_OUTPUT("Vote reveal unlock stake"),
+ VOTE_REVEAL_OP_RETURN_OUTPUT("Vote reveal opReturn"),
+ LOCKUP("Lockup"),
+ LOCKUP_OP_RETURN_OUTPUT("Lockup opReturn"),
+ UNLOCK("Unlock"),
+ INVALID_OUTPUT("Invalid");
+
+ @Getter
+ private String displayString;
+
+ JsonTxOutputType(String displayString) {
+ this.displayString = displayString;
+ }
+}
diff --git a/core/src/main/java/bisq/core/dao/node/json/JsonTxType.java b/core/src/main/java/bisq/core/dao/node/json/JsonTxType.java
index e624247377b..3833341a11f 100644
--- a/core/src/main/java/bisq/core/dao/node/json/JsonTxType.java
+++ b/core/src/main/java/bisq/core/dao/node/json/JsonTxType.java
@@ -19,7 +19,7 @@
import lombok.Getter;
-//TODO sync up with data model
+// Need to be in sync with TxOutputType
public enum JsonTxType {
UNDEFINED_TX_TYPE("Undefined"),
UNVERIFIED("Unverified"),
@@ -27,13 +27,12 @@ public enum JsonTxType {
GENESIS("Genesis"),
TRANSFER_BSQ("Transfer BSQ"),
PAY_TRADE_FEE("Pay trade fee"),
- PROPOSAL("Ballot"),
+ PROPOSAL("Proposal"),
COMPENSATION_REQUEST("Compensation request"),
- VOTE("Vote"),
BLIND_VOTE("Blind vote"),
VOTE_REVEAL("Vote reveal"),
- LOCK_UP("Lockup"),
- UN_LOCK("Unlock");
+ LOCKUP("Lockup"),
+ UNLOCK("Unlock");
@Getter
private String displayString;
diff --git a/core/src/main/java/bisq/core/dao/state/BsqStateService.java b/core/src/main/java/bisq/core/dao/state/BsqStateService.java
index 97eabda13dd..926bf6a8b33 100644
--- a/core/src/main/java/bisq/core/dao/state/BsqStateService.java
+++ b/core/src/main/java/bisq/core/dao/state/BsqStateService.java
@@ -120,10 +120,6 @@ public BsqState getClone() {
return bsqState.getClone();
}
- public LinkedList getBlocksFromState(BsqState bsqState) {
- return new LinkedList<>(bsqState.getBlocks());
- }
-
///////////////////////////////////////////////////////////////////////////////////////////
// ChainHeight
diff --git a/core/src/main/java/bisq/core/dao/state/SnapshotManager.java b/core/src/main/java/bisq/core/dao/state/SnapshotManager.java
index d86e98db341..dcdd65a0bd2 100644
--- a/core/src/main/java/bisq/core/dao/state/SnapshotManager.java
+++ b/core/src/main/java/bisq/core/dao/state/SnapshotManager.java
@@ -29,6 +29,8 @@
import java.io.File;
+import java.util.LinkedList;
+
import lombok.extern.slf4j.Slf4j;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -101,7 +103,7 @@ public void applySnapshot() {
checkNotNull(storage, "storage must not be null");
BsqState persisted = storage.initAndGetPersisted(bsqState, 100);
if (persisted != null) {
- log.info("applySnapshot persisted.chainHeadHeight=" + bsqStateService.getBlocksFromState(persisted).getLast().getHeight());
+ log.info("applySnapshot persisted.chainHeadHeight=" + new LinkedList<>(persisted.getBlocks()).getLast().getHeight());
bsqStateService.applySnapshot(persisted);
} else {
log.info("Try to apply snapshot but no stored snapshot available");