Add check if dao is ready. Improve getBisqTxForAddr and fix nullpointer

Signed-off-by: HenrikJannsen <boilingfrog@gmx.com>
This commit is contained in:
HenrikJannsen 2024-07-21 19:55:23 +07:00
parent 20e7a38c7d
commit 0b40276a4c
No known key found for this signature in database
GPG Key ID: 02AA2BAE387C8307
4 changed files with 44 additions and 13 deletions

View File

@ -26,8 +26,10 @@ import bisq.core.dao.governance.bond.reputation.BondedReputationRepository;
import bisq.core.dao.governance.bond.role.BondedRolesRepository; import bisq.core.dao.governance.bond.role.BondedRolesRepository;
import bisq.core.dao.governance.period.CycleService; import bisq.core.dao.governance.period.CycleService;
import bisq.core.dao.governance.proposal.ProposalService; import bisq.core.dao.governance.proposal.ProposalService;
import bisq.core.dao.state.DaoStateListener;
import bisq.core.dao.state.DaoStateService; import bisq.core.dao.state.DaoStateService;
import bisq.core.dao.state.DaoStateSnapshotService; import bisq.core.dao.state.DaoStateSnapshotService;
import bisq.core.dao.state.model.blockchain.Block;
import bisq.core.offer.OfferBookService; import bisq.core.offer.OfferBookService;
import bisq.core.provider.price.PriceFeedService; import bisq.core.provider.price.PriceFeedService;
import bisq.core.trade.statistics.TradeStatisticsManager; import bisq.core.trade.statistics.TradeStatisticsManager;
@ -39,6 +41,8 @@ import bisq.common.config.Config;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import static com.google.common.base.Preconditions.checkArgument;
@Slf4j @Slf4j
public class RestApi extends ExecutableForAppWithP2p { public class RestApi extends ExecutableForAppWithP2p {
@Getter @Getter
@ -64,6 +68,8 @@ public class RestApi extends ExecutableForAppWithP2p {
@Getter @Getter
private OfferBookService offerBookService; private OfferBookService offerBookService;
private PriceFeedService priceFeedService; private PriceFeedService priceFeedService;
@Getter
private boolean parseBlockCompleteAfterBatchProcessing;
public RestApi() { public RestApi() {
super("Bisq Rest Api", "bisq_restapi", "bisq_restapi", Version.VERSION); super("Bisq Rest Api", "bisq_restapi", "bisq_restapi", Version.VERSION);
@ -97,6 +103,14 @@ public class RestApi extends ExecutableForAppWithP2p {
tradeStatisticsManager = injector.getInstance(TradeStatisticsManager.class); tradeStatisticsManager = injector.getInstance(TradeStatisticsManager.class);
offerBookService = injector.getInstance(OfferBookService.class); offerBookService = injector.getInstance(OfferBookService.class);
priceFeedService = injector.getInstance(PriceFeedService.class); priceFeedService = injector.getInstance(PriceFeedService.class);
daoStateService.addDaoStateListener(new DaoStateListener() {
@Override
public void onParseBlockCompleteAfterBatchProcessing(Block block) {
log.error("onParseBlockCompleteAfterBatchProcessing");
parseBlockCompleteAfterBatchProcessing = true;
}
});
} }
@Override @Override
@ -114,4 +128,8 @@ public class RestApi extends ExecutableForAppWithP2p {
priceFeedService.setCurrencyCodeOnInit(); priceFeedService.setCurrencyCodeOnInit();
priceFeedService.initialRequestPriceFeed(); priceFeedService.initialRequestPriceFeed();
} }
public void checkDaoReady() {
checkArgument(parseBlockCompleteAfterBatchProcessing, "DAO not ready yet");
}
} }

View File

@ -36,9 +36,10 @@ import jakarta.ws.rs.core.MediaType;
@Tag(name = "BLOCKS API") @Tag(name = "BLOCKS API")
public class ExplorerBlocksApi { public class ExplorerBlocksApi {
private final DaoStateService daoStateService; private final DaoStateService daoStateService;
private final RestApi restApi;
public ExplorerBlocksApi(@Context Application application) { public ExplorerBlocksApi(@Context Application application) {
RestApi restApi = ((RestApiMain) application).getRestApi(); restApi = ((RestApiMain) application).getRestApi();
daoStateService = restApi.getDaoStateService(); daoStateService = restApi.getDaoStateService();
} }
@ -51,6 +52,7 @@ public class ExplorerBlocksApi {
@GET @GET
@Path("get-bsq-block-by-height/{block-height}") @Path("get-bsq-block-by-height/{block-height}")
public JsonBlock getBsqBlockByHeight(@Parameter(description = "Block Height") @PathParam("block-height") int blockHeight) { public JsonBlock getBsqBlockByHeight(@Parameter(description = "Block Height") @PathParam("block-height") int blockHeight) {
restApi.checkDaoReady();
List<Block> blocks = daoStateService.getBlocks(); List<Block> blocks = daoStateService.getBlocks();
Optional<JsonBlock> jsonBlock = checkNotNull(blocks.stream()) Optional<JsonBlock> jsonBlock = checkNotNull(blocks.stream())
.filter(block -> block.getHeight() == blockHeight) .filter(block -> block.getHeight() == blockHeight)
@ -68,6 +70,7 @@ public class ExplorerBlocksApi {
@GET @GET
@Path("get-bsq-block-by-hash/{block-hash}") @Path("get-bsq-block-by-hash/{block-hash}")
public JsonBlock getBsqBlockByHash(@Parameter(description = "Block Hash") @PathParam("block-hash") String hash) { public JsonBlock getBsqBlockByHash(@Parameter(description = "Block Hash") @PathParam("block-hash") String hash) {
restApi.checkDaoReady();
List<Block> blocks = daoStateService.getBlocks(); List<Block> blocks = daoStateService.getBlocks();
Optional<JsonBlock> jsonBlock = checkNotNull(blocks.stream()) Optional<JsonBlock> jsonBlock = checkNotNull(blocks.stream())
.filter(block -> block.getHash().equalsIgnoreCase(hash)) .filter(block -> block.getHash().equalsIgnoreCase(hash))

View File

@ -41,9 +41,10 @@ public class ExplorerDaoApi {
private final DaoFacade daoFacade; private final DaoFacade daoFacade;
private final ProposalService proposalService; private final ProposalService proposalService;
private final CycleService cycleService; private final CycleService cycleService;
private final RestApi restApi;
public ExplorerDaoApi(@Context Application application) { public ExplorerDaoApi(@Context Application application) {
RestApi restApi = ((RestApiMain) application).getRestApi(); restApi = ((RestApiMain) application).getRestApi();
daoStateService = restApi.getDaoStateService(); daoStateService = restApi.getDaoStateService();
proposalService = restApi.getProposalService(); proposalService = restApi.getProposalService();
cycleService = restApi.getCycleService(); cycleService = restApi.getCycleService();
@ -54,6 +55,7 @@ public class ExplorerDaoApi {
@GET @GET
@Path("get-bsq-stats") @Path("get-bsq-stats")
public BsqStatsDto getBsqStats() { public BsqStatsDto getBsqStats() {
restApi.checkDaoReady();
long genesisSupply = daoFacade.getGenesisTotalSupply().getValue(); long genesisSupply = daoFacade.getGenesisTotalSupply().getValue();
long issuedByCompensations = daoStateService.getIssuanceSetForType(IssuanceType.COMPENSATION).stream().mapToLong(Issuance::getAmount).sum(); long issuedByCompensations = daoStateService.getIssuanceSetForType(IssuanceType.COMPENSATION).stream().mapToLong(Issuance::getAmount).sum();
long issuedByReimbursements = daoStateService.getIssuanceSetForType(IssuanceType.REIMBURSEMENT).stream().mapToLong(Issuance::getAmount).sum(); long issuedByReimbursements = daoStateService.getIssuanceSetForType(IssuanceType.REIMBURSEMENT).stream().mapToLong(Issuance::getAmount).sum();
@ -70,6 +72,7 @@ public class ExplorerDaoApi {
@GET @GET
@Path("query-dao-cycles") @Path("query-dao-cycles")
public List<JsonDaoCycle> queryDaoCycles() { public List<JsonDaoCycle> queryDaoCycles() {
restApi.checkDaoReady();
Set<Integer> cyclesAdded = new HashSet<>(); Set<Integer> cyclesAdded = new HashSet<>();
List<JsonDaoCycle> result = new ArrayList<>(); List<JsonDaoCycle> result = new ArrayList<>();
// Creating our data structure is a bit expensive so we ensure to only create the CycleListItems once. // Creating our data structure is a bit expensive so we ensure to only create the CycleListItems once.

View File

@ -22,12 +22,11 @@ import bisq.core.dao.state.model.blockchain.BaseTx;
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.blockchain.TxType;
import java.util.ArrayList; import java.util.Collection;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -54,9 +53,10 @@ import jakarta.ws.rs.core.MediaType;
@Tag(name = "TRANSACTIONS API") @Tag(name = "TRANSACTIONS API")
public class ExplorerTransactionsApi { public class ExplorerTransactionsApi {
private final DaoStateService daoStateService; private final DaoStateService daoStateService;
private final RestApi restApi;
public ExplorerTransactionsApi(@Context Application application) { public ExplorerTransactionsApi(@Context Application application) {
RestApi restApi = ((RestApiMain) application).getRestApi(); restApi = ((RestApiMain) application).getRestApi();
daoStateService = restApi.getDaoStateService(); daoStateService = restApi.getDaoStateService();
} }
@ -64,6 +64,7 @@ public class ExplorerTransactionsApi {
@Path("get-bsq-tx/{txid}") @Path("get-bsq-tx/{txid}")
public JsonTx getTx(@Parameter(description = "TxId") public JsonTx getTx(@Parameter(description = "TxId")
@PathParam("txid") String txId) { @PathParam("txid") String txId) {
restApi.checkDaoReady();
Optional<JsonTx> jsonTx = daoStateService.getUnorderedTxStream() Optional<JsonTx> jsonTx = daoStateService.getUnorderedTxStream()
.filter(t -> t.getId().equals(txId)) .filter(t -> t.getId().equals(txId))
.map(tx -> BlockDataToJsonConverter.getJsonTx(daoStateService, tx)) .map(tx -> BlockDataToJsonConverter.getJsonTx(daoStateService, tx))
@ -79,14 +80,19 @@ public class ExplorerTransactionsApi {
@GET @GET
@Path("get-bsq-tx-for-addr/{addr}") @Path("get-bsq-tx-for-addr/{addr}")
public List<JsonTx> getBisqTxForAddr(@PathParam("addr") String address) { public List<JsonTx> getBisqTxForAddr(@PathParam("addr") String address) {
Map<String, Set<String>> addressToTxIds = daoStateService.getTxIdSetByAddress(); restApi.checkDaoReady();
List<JsonTx> result = new ArrayList<>(); // In case we get a prefixed address marking BSQ addresses we remove the prefix
Set<String> strings = addressToTxIds.get(address); if (address.startsWith("B")) {
strings.forEach(txId -> { address = address.substring(1, address.length());
daoStateService.getTx(txId).stream() }
String finalAddress = address;
List<JsonTx> result = daoStateService.getTxIdSetByAddress().entrySet().stream()
.filter(e -> e.getKey().equals(finalAddress))
.map(Map.Entry::getValue)
.flatMap(Collection::stream)
.flatMap(txId -> daoStateService.getTx(txId).stream())
.map(tx -> BlockDataToJsonConverter.getJsonTx(daoStateService, tx)) .map(tx -> BlockDataToJsonConverter.getJsonTx(daoStateService, tx))
.forEach(result::add); .collect(Collectors.toList());
});
log.info("getBisqTxForAddr: returning {} items.", result.size()); log.info("getBisqTxForAddr: returning {} items.", result.size());
return result; return result;
} }
@ -96,6 +102,7 @@ public class ExplorerTransactionsApi {
public List<JsonTx> queryTxsPaginated(@PathParam("start") int start, public List<JsonTx> queryTxsPaginated(@PathParam("start") int start,
@PathParam("count") int count, @PathParam("count") int count,
@PathParam("filters") String filters) { @PathParam("filters") String filters) {
restApi.checkDaoReady();
log.info("filters: {}", filters); log.info("filters: {}", filters);
List<JsonTx> jsonTxs = daoStateService.getUnorderedTxStream() List<JsonTx> jsonTxs = daoStateService.getUnorderedTxStream()
.sorted(Comparator.comparing(BaseTx::getTime).reversed()) .sorted(Comparator.comparing(BaseTx::getTime).reversed())