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());