Skip to content
This repository has been archived by the owner on Nov 8, 2022. It is now read-only.

Commit

Permalink
release: fix rate service cache
Browse files Browse the repository at this point in the history
  • Loading branch information
reemuru committed Jul 27, 2021
1 parent 2ebc0fd commit e4e0503
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 26 deletions.
4 changes: 2 additions & 2 deletions api.http
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Content-Type: application/json

{
"amount": 0.123,
"address": "54gqcJZAtgzBFnQWEQHec3RoWfmoHqL4H8sASqdQMGshfqdpG1fzT5ddCpz9y4C2MwQkB5GE2o6vUVCGKbokJJa6S6NSatn"
"address": "56fK1PpmCjz5CEiAb8dbpyQZtpJ8s4B2WaXPqyFD2FU9DUobuSDJZztEPeppvAqT2DPWcdp7qtW6KasCbYoWJC7qBcwWrSH"
}

### Validate Monero address
Expand Down Expand Up @@ -57,7 +57,7 @@ POST http://localhost:6789/swap/xmr
Content-Type: application/json

{
"hash": "63eb4534535a4c4afa9455f7dacde8cecbbac91e2bcd390407e1b88704a9a758"
"hash": "2161997ea4adcaa2806c0a0e66f30b3ac48ed9f969108742a6b163148f5c7b6c"
}

### get balances of xmr wallet
Expand Down
31 changes: 15 additions & 16 deletions src/main/java/org/hiahatf/mass/services/monero/QuoteService.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,21 @@ public QuoteService(RateService rateService, MassUtil massUtil,
* @return Mono<MoneroQuote>
*/
public Mono<Quote> processMoneroQuote(Request request) {
return rateService.getMoneroRate().flatMap(r -> {
Double rate = massUtil.parseMoneroRate(r);
Double value = (rate * request.getAmount()) * Constants.COIN;
/*
* The quote amount is validated before a response is sent.
* Minimum and maximum payments are configured via the MASS
* application.yml. There is no limit on requests. The amount
* is also validated with Monero reserve proof.
*/
return validateInboundLiquidity(value).flatMap(l -> {
if(l) {
return generateReserveProof(request, value, rate);
}
// edge case, this should never happen...
return Mono.error(new MassException(Constants.UNK_ERROR));
});
String rate = rateService.getMoneroRate();
Double parsedRate = massUtil.parseMoneroRate(rate);
Double value = (parsedRate* request.getAmount()) * Constants.COIN;
/*
* The quote amount is validated before a response is sent.
* Minimum and maximum payments are configured via the MASS
* application.yml. There is no limit on requests. The amount
* is also validated with Monero reserve proof.
*/
return validateInboundLiquidity(value).flatMap(l -> {
if(l) {
return generateReserveProof(request, value, parsedRate);
}
// edge case, this should never happen...
return Mono.error(new MassException(Constants.UNK_ERROR));
});
}

Expand Down
7 changes: 4 additions & 3 deletions src/main/java/org/hiahatf/mass/services/rate/RateService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class RateService {
private Logger logger = LoggerFactory.getLogger(RateService.class);
private static final int FREQUENCY = 600000;
private static final int INITIAL_DELAY = 10000;
private Mono<String> moneroRate;
private String moneroRate;

private String xmrPriceUrl;

Expand All @@ -32,7 +32,7 @@ public RateService(@Value(Constants.RATE_HOST) String url) {
* Accessor for the Monero rate
* @return monero rate
*/
public Mono<String> getMoneroRate() {
public String getMoneroRate() {
return this.moneroRate;
}

Expand All @@ -54,7 +54,8 @@ public void updateMoneroRate() {
.build())
.retrieve()
.bodyToMono(String.class);
this.moneroRate = xmrRate.retry(1);
// normally wouldn't use block, but is needed here to cache price data
this.moneroRate = xmrRate.retry(1).block();
}

}
2 changes: 1 addition & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ host:
# reserve proof address
rp-address: 56fK1PpmCjz5CEiAb8dbpyQZtpJ8s4B2WaXPqyFD2FU9DUobuSDJZztEPeppvAqT2DPWcdp7qtW6KasCbYoWJC7qBcwWrSH
# macaroon path
macaroon-path: /home/nigellchristian/.lnd2/data/chain/bitcoin/regtest/admin.macaroon
macaroon-path: /home/rimuru/.lnd-regtest-2/data/chain/bitcoin/regtest/admin.macaroon
# markup so we can pay the bills
markup: 0.01
# payment thresholds in satoshis
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public void processQuoteTest() throws SSLException, IOException {
AddHoldInvoiceResponse addHoldInvoiceResponse = AddHoldInvoiceResponse.builder()
.payment_request("lntest123xxx").build();
// mocks
when(rateService.getMoneroRate()).thenReturn(Mono.just("{BTC: 0.00777}"));
when(rateService.getMoneroRate()).thenReturn("{BTC: 0.00777}");
when(massUtil.parseMoneroRate(anyString())).thenReturn(0.008);
when(lightning.fetchBalance()).thenReturn(Mono.just(liquidity));
when(moneroRpc.getReserveProof(req.getAmount())).thenReturn(Mono.just(reserveProof));
Expand All @@ -107,7 +107,7 @@ public void paymentThresholdErrorTest() throws SSLException, IOException {
Request req = Request.builder().address("54xxx")
.amount(100.0).build();
// mocks
when(rateService.getMoneroRate()).thenReturn(Mono.just("{BTC: 0.00777}"));
when(rateService.getMoneroRate()).thenReturn("{BTC: 0.00777}");
when(massUtil.parseMoneroRate(anyString())).thenReturn(0.008);
try {
Quote test = quoteService.processMoneroQuote(req).block();
Expand All @@ -129,7 +129,7 @@ public void liquidityErrorTest() throws SSLException, IOException {
Liquidity liquidity = Liquidity.builder()
.remote_balance(amt).build();
// mocks
when(rateService.getMoneroRate()).thenReturn(Mono.just("{BTC: 0.00777}"));
when(rateService.getMoneroRate()).thenReturn("{BTC: 0.00777}");
when(massUtil.parseMoneroRate(anyString())).thenReturn(0.008);
when(lightning.fetchBalance()).thenReturn(Mono.just(liquidity));
try {
Expand All @@ -155,7 +155,7 @@ public void reserveProofErrorTest() throws SSLException, IOException {
.builder().result(null)
.build();
// mocks
when(rateService.getMoneroRate()).thenReturn(Mono.just("{BTC: 0.00777}"));
when(rateService.getMoneroRate()).thenReturn("{BTC: 0.00777}");
when(massUtil.parseMoneroRate(anyString())).thenReturn(0.008);
when(lightning.fetchBalance()).thenReturn(Mono.just(liquidity));
when(moneroRpc.getReserveProof(req.getAmount())).thenReturn(Mono.just(reserveProof));
Expand Down
68 changes: 68 additions & 0 deletions src/test/java/org/hiahatf/mass/service/rate/RateServiceTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,73 @@
package org.hiahatf.mass.service.rate;


import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;
import java.util.HashMap;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.net.HttpHeaders;

import org.hiahatf.mass.services.rate.RateService;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import org.mockito.junit.jupiter.MockitoExtension;

import io.netty.handler.codec.http.HttpHeaderValues;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;

/**
* Tests for Rate Service
*/
@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
public class RateServiceTest {

public static MockWebServer mockBackEnd;
private ObjectMapper objectMapper = new ObjectMapper();
private RateService rateService;

@BeforeAll
static void setUp() throws IOException {
mockBackEnd = new MockWebServer();
mockBackEnd.start();
}

@AfterAll
static void tearDown() throws IOException {
mockBackEnd.shutdown();
}

@BeforeEach
void initialize() {
String baseUrl = String.format("http://localhost:%s",
mockBackEnd.getPort());
rateService = new RateService(baseUrl);
}

@Test
@DisplayName("Rate Service Test")
public void getRateTest() throws JsonProcessingException {
String expectedRate = "{\"BTC\":\"0.00777\"}";
HashMap<String,String> res = new HashMap<>();
res.put("BTC", "0.00777");
mockBackEnd.enqueue(new MockResponse()
.setBody(objectMapper.writeValueAsString(res))
.addHeader(HttpHeaders.CONTENT_TYPE,
HttpHeaderValues.APPLICATION_JSON.toString()));

rateService.updateMoneroRate();
String testRate = rateService.getMoneroRate();
assertEquals(expectedRate, testRate);
}

}

0 comments on commit e4e0503

Please sign in to comment.