diff --git a/src/main/java/bdledger/api/Client.java b/src/main/java/bdledger/api/Client.java index db2c90f..efa43a8 100644 --- a/src/main/java/bdledger/api/Client.java +++ b/src/main/java/bdledger/api/Client.java @@ -12,6 +12,7 @@ import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.StatusRuntimeException; +import java.time.ZonedDateTime; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; @@ -225,7 +226,7 @@ public class Client { /** * 返回哈希所指定区块的信息 + * href="#">返回哈希所指定的区块 * (非阻塞) */ public ListenableFuture getBlockByHash( @@ -245,7 +246,7 @@ public class Client { /** * 返回哈希所指定区块的信息 + * href="#">返回哈希所指定的区块 * (阻塞) */ public GetBlockByHashResponse getBlockByHashSync(String ledger, String hash, boolean fullTransactions) { @@ -276,7 +277,99 @@ public class Client { /** * 返回符合条件的区块的数量 + * href="#">返回时间范围内的区块 + * (非阻塞) + */ + public ListenableFuture getBlocks(String ledger, ZonedDateTime startDateTime) { + return getBlocks(ledger, startDateTime.toEpochSecond()); + } + + /** + * 返回时间范围内的区块 + * (非阻塞) + */ + public ListenableFuture getBlocks(String ledger, ZonedDateTime startDateTime, ZonedDateTime endDateTime) { + return getBlocks(ledger, startDateTime.toEpochSecond(), endDateTime.toEpochSecond()); + } + + /** + * 返回时间范围内的区块 + * (阻塞) + */ + public GetBlocksResponse getBlocksSync(String ledger, ZonedDateTime startDateTime) { + return getBlocksSync(ledger, startDateTime.toEpochSecond()); + } + + /** + * 返回时间范围内的区块 + * (阻塞) + */ + public GetBlocksResponse getBlocksSync(String ledger, ZonedDateTime startDateTime, ZonedDateTime endDateTime) { + return getBlocksSync(ledger, startDateTime.toEpochSecond(), endDateTime.toEpochSecond()); + } + + /** + * 返回时间范围内的区块 + * (非阻塞) + */ + public ListenableFuture getBlocks(String ledger, long startUnixTime) { + return getBlocks(ledger, startUnixTime, -1); + } + + /** + * 返回时间范围内的区块 + * (非阻塞) + */ + public ListenableFuture getBlocks(String ledger, long startUnixTime, long endUnixTime) { + + info( + "*** getBlock: ledger={0} startUnixTime={1} endUnixTime={2}", + ledger, startUnixTime, endUnixTime); + + try { + return queryFutureStub.getBlocks(getBlocksRequest(ledger, startUnixTime, endUnixTime)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + /** + * 返回时间范围内的区块 + * (阻塞) + */ + public GetBlocksResponse getBlocksSync(String ledger, long startUnixTime) { + return getBlocksSync(ledger, startUnixTime, -1); + } + + /** + * 返回时间范围内的区块 + * (阻塞) + */ + public GetBlocksResponse getBlocksSync(String ledger, long startUnixTime, long endUnixTime) { + + info( + "*** getBlockSync: ledger={0} startUnixTime={1} endUnixTime={2}", + ledger, startUnixTime, endUnixTime); + + try { + return queryBlockingStub.getBlocks(getBlocksRequest(ledger, startUnixTime, endUnixTime)); + } catch (StatusRuntimeException e) { + warning("RPC failed: {0}", e.getStatus()); + return null; + } + } + + /** + * 返回账本中的区块数量 * (非阻塞) */ public ListenableFuture countBlocks(String ledger) { @@ -284,7 +377,7 @@ public class Client { info("*** blockNumber: ledger={0}", ledger); try { - return queryFutureStub.countBlocks(blocksRequest(ledger)); + return queryFutureStub.countBlocks(getBlocksRequest(ledger, -1, -1)); } catch (StatusRuntimeException e) { warning("RPC failed: {0}", e.getStatus()); return null; @@ -293,7 +386,7 @@ public class Client { /** * 返回符合条件的区块的数量 + * href="#">返回账本中的区块数量 * (阻塞) */ public CountBlocksResponse countBlocksSync(String ledger) { @@ -301,20 +394,30 @@ public class Client { info("*** blockNumberSync: ledger={0}", ledger); try { - return queryBlockingStub.countBlocks(blocksRequest(ledger)); + return queryBlockingStub.countBlocks(getBlocksRequest(ledger, -1, -1)); } catch (StatusRuntimeException e) { warning("RPC failed: {0}", e.getStatus()); return null; } } - private BlocksRequest blocksRequest(String ledger) { - return BlocksRequest.newBuilder().setLedger(ledger).build(); + private BlocksRequest getBlocksRequest(String ledger, long startTimestamp, long endTimestamp) { + + BlocksRequest.Builder reqBuilder = + BlocksRequest.newBuilder().setLedger(ledger); + if (startTimestamp != -1) { + reqBuilder.setStartTimestamp(startTimestamp); + } + if (endTimestamp != -1) { + reqBuilder.setEndTimestamp(endTimestamp); + } + + return reqBuilder.build(); } /** * 返回哈希所指定事务的信息 + * href="#">返回哈希所指定的事务 * (非阻塞) */ public ListenableFuture getTransactionByHash(String ledger, String hash) { @@ -331,7 +434,7 @@ public class Client { /** * 返回哈希所指定事务的信息 + * href="#">返回哈希所指定的事务 * (阻塞) */ public GetTransactionByHashResponse getTransactionByHashSync(String ledger, String hash) { @@ -359,7 +462,7 @@ public class Client { /** * 返回区块的哈希与事务的index所指定事务的信息 + * href="#">返回区块的哈希与事务的index所指定的事务 * (非阻塞) */ public ListenableFuture getTransactionByBlockHashAndIndex( @@ -380,7 +483,7 @@ public class Client { /** * 返回区块的哈希与事务的index所指定事务的信息 + * href="#">返回区块的哈希与事务的index所指定的事务 * (阻塞) */ public GetTransactionByBlockHashAndIndexResponse getTransactionByBlockHashAndIndexSync( @@ -414,7 +517,7 @@ public class Client { /** * 返回符合条件的数量 + * href="#">返回账本中的事务数量 * (非阻塞) */ public ListenableFuture countTransactions(String ledger) { @@ -431,7 +534,7 @@ public class Client { /** * 返回符合条件的事务的数量 + * href="#">返回账本中的事务数量 * (阻塞) */ public CountTransactionsResponse countTransactionsSync(String ledger) { diff --git a/src/test/java/bdledger/api/ClientTests.java b/src/test/java/bdledger/api/ClientTests.java index f93f1ad..28902fb 100644 --- a/src/test/java/bdledger/api/ClientTests.java +++ b/src/test/java/bdledger/api/ClientTests.java @@ -2,8 +2,8 @@ package bdledger.api; import bdledger.api.grpc.common.Block; import bdledger.api.grpc.common.Transaction; -import bdledger.api.grpc.ledger.GetLedgersResponse; import bdledger.api.grpc.common.TransactionType; +import bdledger.api.grpc.ledger.GetLedgersResponse; import com.google.protobuf.ByteString; import io.grpc.Status; import org.junit.jupiter.api.AfterAll; @@ -23,7 +23,6 @@ import static org.junit.jupiter.api.Assertions.*; class ClientTests { private static final String ledger = "test"; - private static final String[] ledgers = new String[]{"first", "second", "third"}; private static final int blockCount = 2018; private static final int transactionCount = 2020; @@ -132,7 +131,7 @@ class ClientTests { assertEquals(3, r.getLedgersCount()); String[] expected = new String[]{"first", "second", "third"}; assertAll( - IntStream.range(0, 3).boxed().map(i -> () -> assertEquals(ledgers[i], r.getLedgers(i)))); + IntStream.range(0, 3).boxed().map(i -> () -> assertEquals(expected[i], r.getLedgers(i)))); } @Test @@ -175,6 +174,29 @@ class ClientTests { assertEquals(block, b); } + // TODO + @Test + @DisplayName("getBlocks#1") + void getBlocks1() throws ExecutionException, InterruptedException { + client.getBlocks(ledger, 0).get(); + } + + // TODO + @Test + @DisplayName("getBlocks#2") + void getBlocks2() throws ExecutionException, InterruptedException { + client.getBlocks(ledger, 0, 0).get(); + } + + @Test + @DisplayName("getBlocks#3") + void getBlocks3() { + Throwable e = assertThrows(Exception.class, () -> client.getBlocks("", 0, 0).get()); + Status s = Status.fromThrowable(e); + assertEquals(Status.Code.INVALID_ARGUMENT, s.getCode()); + assertEquals("ledger must not be empty", s.getDescription()); + } + @Test @DisplayName("CountBlocks#1") void blockNumber1() throws ExecutionException, InterruptedException { @@ -204,6 +226,7 @@ class ClientTests { assertEquals(tx, t); } + @Test @DisplayName("CountTransactions#1") void CountTransactions1() throws ExecutionException, InterruptedException { assertEquals(transactionCount, client.countTransactions(ledger).get().getCount());