mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 01:41:11 +01:00
Add bsq bonds
This commit is contained in:
parent
ec00c9962f
commit
2628eea9db
@ -167,7 +167,7 @@ public class ProofOfBurnService implements DaoSetupService, DaoStateListener {
|
||||
myProofOfBurnListService.addMyProofOfBurn(myProofOfBurn);
|
||||
}
|
||||
|
||||
public byte[] getHashFromOpReturnData(Tx tx) {
|
||||
public static byte[] getHashFromOpReturnData(Tx tx) {
|
||||
return ProofOfBurnConsensus.getHashFromOpReturnData(tx.getLastTxOutput().getOpReturnData());
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import bisq.core.app.TorSetup;
|
||||
import bisq.core.app.misc.AppSetupWithP2PAndDAO;
|
||||
import bisq.core.app.misc.ExecutableForAppWithP2p;
|
||||
import bisq.core.app.misc.ModuleForAppWithP2p;
|
||||
import bisq.core.dao.governance.bond.reputation.BondedReputationRepository;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.DaoStateSnapshotService;
|
||||
import bisq.core.user.Cookie;
|
||||
@ -55,6 +56,8 @@ public class DaoNode extends ExecutableForAppWithP2p {
|
||||
private Timer checkConnectionLossTime;
|
||||
@Getter
|
||||
private DaoStateService daoStateService;
|
||||
@Getter
|
||||
private BondedReputationRepository bondedReputationRepository;
|
||||
|
||||
public DaoNode() {
|
||||
super("Bisq Dao Node", "bisq-dao-node", "bisq_dao_node", Version.VERSION);
|
||||
@ -117,6 +120,7 @@ public class DaoNode extends ExecutableForAppWithP2p {
|
||||
injector.getInstance(AppSetupWithP2PAndDAO.class).start();
|
||||
|
||||
daoStateService = injector.getInstance(DaoStateService.class);
|
||||
bondedReputationRepository = injector.getInstance(BondedReputationRepository.class);
|
||||
|
||||
injector.getInstance(P2PService.class).addP2PServiceListener(new P2PServiceListener() {
|
||||
@Override
|
||||
|
@ -28,6 +28,7 @@ import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
|
||||
import bisq.daonode.endpoints.BondedReputationApi;
|
||||
import bisq.daonode.endpoints.ProofOfBurnApi;
|
||||
import bisq.daonode.error.CustomExceptionMapper;
|
||||
import bisq.daonode.error.StatusException;
|
||||
@ -54,6 +55,7 @@ public class DaoNodeRestApiApplication extends ResourceConfig {
|
||||
.register(CustomExceptionMapper.class)
|
||||
.register(StatusException.StatusExceptionMapper.class)
|
||||
.register(ProofOfBurnApi.class)
|
||||
.register(BondedReputationApi.class)
|
||||
.register(SwaggerResolution.class);
|
||||
daoNodeRestApiApplication.startServer(config.daoNodeApiUrl, config.daoNodeApiPort);
|
||||
});
|
||||
@ -62,6 +64,7 @@ public class DaoNodeRestApiApplication extends ResourceConfig {
|
||||
|
||||
@Getter
|
||||
private final DaoNode daoNode;
|
||||
|
||||
private HttpServer httpServer;
|
||||
|
||||
public DaoNodeRestApiApplication() {
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.daonode.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
/**
|
||||
* Minimal data required for Bisq 2 bonded reputation use case.
|
||||
* Need to be in sync with the Bisq 2 BondedReputationDto class.
|
||||
*/
|
||||
@Getter
|
||||
@Slf4j
|
||||
@Schema(title = "BondedReputation")
|
||||
public class BondedReputationDto {
|
||||
private long amount;
|
||||
private long time;
|
||||
private String hash;
|
||||
private int blockHeight;
|
||||
private int lockTime;
|
||||
|
||||
public BondedReputationDto(long amount, long time, String hash, int blockHeight, int lockTime) {
|
||||
this.amount = amount;
|
||||
this.time = time;
|
||||
this.hash = hash;
|
||||
this.blockHeight = blockHeight;
|
||||
this.lockTime = lockTime;
|
||||
}
|
||||
}
|
@ -24,23 +24,21 @@ import lombok.Getter;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
/**
|
||||
* Minimal data required for Bisq 2 reputation use case.
|
||||
* Minimal data required for Bisq 2 proof of burn use case.
|
||||
* Need to be in sync with the Bisq 2 ProofOfBurnDto class.
|
||||
*/
|
||||
@Getter
|
||||
@Schema(title = "ProofOfBurn")
|
||||
public class ProofOfBurnDto {
|
||||
private final String txId;
|
||||
private final long burnedAmount;
|
||||
private final int blockHeight;
|
||||
private final long amount;
|
||||
private final long time;
|
||||
private final String hash;
|
||||
private final int blockHeight;
|
||||
|
||||
public ProofOfBurnDto(String txId, long burnedAmount, int blockHeight, long time, String hash) {
|
||||
this.txId = txId;
|
||||
this.burnedAmount = burnedAmount;
|
||||
this.blockHeight = blockHeight;
|
||||
public ProofOfBurnDto(long amount, long time, String hash, int blockHeight) {
|
||||
this.amount = amount;
|
||||
this.time = time;
|
||||
this.hash = hash;
|
||||
this.blockHeight = blockHeight;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.daonode.endpoints;
|
||||
|
||||
import bisq.core.dao.governance.bond.reputation.BondedReputationRepository;
|
||||
import bisq.core.dao.state.DaoStateService;
|
||||
import bisq.core.dao.state.model.blockchain.Tx;
|
||||
|
||||
import bisq.common.util.Hex;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
||||
|
||||
import bisq.daonode.DaoNode;
|
||||
import bisq.daonode.DaoNodeRestApiApplication;
|
||||
import bisq.daonode.dto.BondedReputationDto;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.ws.rs.GET;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.PathParam;
|
||||
import jakarta.ws.rs.Produces;
|
||||
import jakarta.ws.rs.core.Application;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* Endpoint for getting the bonded reputation data from a given block height.
|
||||
* Used for reputation system in Bisq 2.
|
||||
* <a href="http://localhost:8082/api/v1/bonded-reputation/get-bonded-reputation/0">Request with block height 0</a>
|
||||
*/
|
||||
@Slf4j
|
||||
@Path("/bonded-reputation")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Tag(name = "Bonded reputation API")
|
||||
public class BondedReputationApi {
|
||||
private static final String DESC_BLOCK_HEIGHT = "The block height from which we request the bonded reputation data";
|
||||
private final BondedReputationRepository bondedReputationRepository;
|
||||
private final DaoStateService daoStateService;
|
||||
|
||||
public BondedReputationApi(@Context Application application) {
|
||||
DaoNode daoNode = ((DaoNodeRestApiApplication) application).getDaoNode();
|
||||
daoStateService = daoNode.getDaoStateService();
|
||||
bondedReputationRepository = daoNode.getBondedReputationRepository();
|
||||
}
|
||||
|
||||
@Operation(description = "Request the bonded reputation data")
|
||||
@ApiResponse(responseCode = "200", description = "The bonded reputation data",
|
||||
content = {@Content(mediaType = MediaType.APPLICATION_JSON,
|
||||
schema = @Schema(allOf = BondedReputationDto.class))}
|
||||
)
|
||||
@GET
|
||||
@Path("get-bonded-reputation/{block-height}")
|
||||
public List<BondedReputationDto> getBondedReputation(@Parameter(description = DESC_BLOCK_HEIGHT)
|
||||
@PathParam("block-height")
|
||||
int fromBlockHeight) {
|
||||
return bondedReputationRepository.getActiveBonds().stream()
|
||||
.map(bondedReputation -> {
|
||||
Optional<Tx> optionalTx = daoStateService.getTx(bondedReputation.getLockupTxId());
|
||||
if (optionalTx.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Tx tx = optionalTx.get();
|
||||
int blockHeight = tx.getBlockHeight();
|
||||
if (blockHeight >= fromBlockHeight) {
|
||||
return new BondedReputationDto(bondedReputation.getAmount(),
|
||||
tx.getTime(),
|
||||
Hex.encode(bondedReputation.getBondedAsset().getHash()),
|
||||
blockHeight,
|
||||
bondedReputation.getLockTime()
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}).filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -17,11 +17,10 @@
|
||||
|
||||
package bisq.daonode.endpoints;
|
||||
|
||||
import bisq.core.dao.state.model.blockchain.Tx;
|
||||
import bisq.core.dao.governance.proofofburn.ProofOfBurnService;
|
||||
|
||||
import bisq.common.util.Hex;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -48,6 +47,11 @@ import jakarta.ws.rs.core.Application;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
|
||||
/**
|
||||
* Endpoint for getting the proof of burn data from a given block height.
|
||||
* Used for reputation system in Bisq 2.
|
||||
* <a href="http://localhost:8082/api/v1/proof-of-burn/get-proof-of-burn/0">Request with block height 0</a>
|
||||
*/
|
||||
@Slf4j
|
||||
@Path("/proof-of-burn")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -69,23 +73,13 @@ public class ProofOfBurnApi {
|
||||
@Path("get-proof-of-burn/{block-height}")
|
||||
public List<ProofOfBurnDto> getProofOfBurn(@Parameter(description = DESC_BLOCK_HEIGHT)
|
||||
@PathParam("block-height")
|
||||
int blockHeight) {
|
||||
int fromBlockHeight) {
|
||||
return checkNotNull(daoNode.getDaoStateService()).getProofOfBurnTxs().stream()
|
||||
.filter(tx -> tx.getBlockHeight() >= blockHeight)
|
||||
.map(tx -> new ProofOfBurnDto(tx.getId(),
|
||||
tx.getBurntBsq(),
|
||||
tx.getBlockHeight(),
|
||||
.filter(tx -> tx.getBlockHeight() >= fromBlockHeight)
|
||||
.map(tx -> new ProofOfBurnDto(tx.getBurntBsq(),
|
||||
tx.getTime(),
|
||||
getHash(tx)))
|
||||
Hex.encode(ProofOfBurnService.getHashFromOpReturnData(tx)),
|
||||
tx.getBlockHeight()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// We strip out the version bytes
|
||||
private String getHash(Tx tx) {
|
||||
byte[] opReturnData = tx.getLastTxOutput().getOpReturnData();
|
||||
if (opReturnData == null) {
|
||||
return "";
|
||||
}
|
||||
return Hex.encode(Arrays.copyOfRange(opReturnData, 2, 22));
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ class MyProofOfBurnListItem {
|
||||
amount = proofOfBurnService.getAmount(tx);
|
||||
amountAsString = bsqFormatter.formatCoinWithCode(Coin.valueOf(amount));
|
||||
txId = tx.getId();
|
||||
hashAsHex = Utilities.bytesAsHexString(proofOfBurnService.getHashFromOpReturnData(tx));
|
||||
hashAsHex = Utilities.bytesAsHexString(ProofOfBurnService.getHashFromOpReturnData(tx));
|
||||
pubKey = Utilities.bytesAsHexString(proofOfBurnService.getPubKey(txId));
|
||||
} else {
|
||||
amount = 0;
|
||||
|
@ -45,7 +45,7 @@ class ProofOfBurnListItem {
|
||||
amount = proofOfBurnService.getAmount(tx);
|
||||
amountAsString = bsqFormatter.formatCoinWithCode(Coin.valueOf(amount));
|
||||
txId = tx.getId();
|
||||
hashAsHex = Utilities.bytesAsHexString(proofOfBurnService.getHashFromOpReturnData(tx));
|
||||
hashAsHex = Utilities.bytesAsHexString(ProofOfBurnService.getHashFromOpReturnData(tx));
|
||||
pubKey = Utilities.bytesAsHexString(proofOfBurnService.getPubKey(txId));
|
||||
date = new Date(tx.getTime());
|
||||
dateAsString = DisplayUtils.formatDateTime(date);
|
||||
|
Loading…
Reference in New Issue
Block a user