Skip to content

Commit 1541a2a

Browse files
authored
REST API: Add algod block hash endpoint, add indexer block header-only param. (#413)
1 parent 29b3233 commit 1541a2a

File tree

13 files changed

+231
-1
lines changed

13 files changed

+231
-1
lines changed

.test-env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ SDK_TESTING_URL="https://github.com/algorand/algorand-sdk-testing"
33
SDK_TESTING_BRANCH="master"
44
SDK_TESTING_HARNESS="test-harness"
55

6+
INSTALL_ONLY=0
7+
68
VERBOSE_HARNESS=0
79

810
# WARNING: If set to 1, new features will be LOST when downloading the test harness.

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ display-all-java-steps:
1111
find src/test/java/com/algorand/algosdk -name "*.java" | xargs grep "io.cucumber.java.en" 2>/dev/null | grep -v Binary | cut -d: -f1 | sort | uniq | xargs grep -E "@(Given|Then|When)"
1212

1313
harness:
14-
./test-harness.sh
14+
./test-harness.sh up
15+
16+
harness-down:
17+
./test-harness.sh down
1518

1619
docker-javasdk-build:
1720
# Build SDK testing environment
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.algorand.algosdk.v2.client.algod;
2+
3+
import com.algorand.algosdk.v2.client.common.Client;
4+
import com.algorand.algosdk.v2.client.common.HttpMethod;
5+
import com.algorand.algosdk.v2.client.common.Query;
6+
import com.algorand.algosdk.v2.client.common.QueryData;
7+
import com.algorand.algosdk.v2.client.common.Response;
8+
import com.algorand.algosdk.v2.client.model.BlockHashResponse;
9+
10+
11+
/**
12+
* Get the block hash for the block on the given round.
13+
* /v2/blocks/{round}/hash
14+
*/
15+
public class GetBlockHash extends Query {
16+
17+
private Long round;
18+
19+
/**
20+
* @param round The round from which to fetch block hash information.
21+
*/
22+
public GetBlockHash(Client client, Long round) {
23+
super(client, new HttpMethod("get"));
24+
this.round = round;
25+
}
26+
27+
/**
28+
* Execute the query.
29+
* @return the query response object.
30+
* @throws Exception
31+
*/
32+
@Override
33+
public Response<BlockHashResponse> execute() throws Exception {
34+
Response<BlockHashResponse> resp = baseExecute();
35+
resp.setValueType(BlockHashResponse.class);
36+
return resp;
37+
}
38+
39+
/**
40+
* Execute the query with custom headers, there must be an equal number of keys and values
41+
* or else an error will be generated.
42+
* @param headers an array of header keys
43+
* @param values an array of header values
44+
* @return the query response object.
45+
* @throws Exception
46+
*/
47+
@Override
48+
public Response<BlockHashResponse> execute(String[] headers, String[] values) throws Exception {
49+
Response<BlockHashResponse> resp = baseExecute(headers, values);
50+
resp.setValueType(BlockHashResponse.class);
51+
return resp;
52+
}
53+
54+
protected QueryData getRequestString() {
55+
if (this.round == null) {
56+
throw new RuntimeException("round is not set. It is a required parameter.");
57+
}
58+
addPathSegment(String.valueOf("v2"));
59+
addPathSegment(String.valueOf("blocks"));
60+
addPathSegment(String.valueOf(round));
61+
addPathSegment(String.valueOf("hash"));
62+
63+
return qd;
64+
}
65+
}

src/main/java/com/algorand/algosdk/v2/client/common/AlgodClient.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.algorand.algosdk.v2.client.algod.AccountApplicationInformation;
1111
import com.algorand.algosdk.v2.client.algod.GetPendingTransactionsByAddress;
1212
import com.algorand.algosdk.v2.client.algod.GetBlock;
13+
import com.algorand.algosdk.v2.client.algod.GetBlockHash;
1314
import com.algorand.algosdk.v2.client.algod.GetTransactionProof;
1415
import com.algorand.algosdk.v2.client.algod.GetSupply;
1516
import com.algorand.algosdk.v2.client.algod.GetStatus;
@@ -141,6 +142,14 @@ public GetBlock GetBlock(Long round) {
141142
return new GetBlock((Client) this, round);
142143
}
143144

145+
/**
146+
* Get the block hash for the block on the given round.
147+
* /v2/blocks/{round}/hash
148+
*/
149+
public GetBlockHash GetBlockHash(Long round) {
150+
return new GetBlockHash((Client) this, round);
151+
}
152+
144153
/**
145154
* Get a proof for a transaction in a block.
146155
* /v2/blocks/{round}/transactions/{txid}/proof

src/main/java/com/algorand/algosdk/v2/client/indexer/LookupBlock.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ public LookupBlock(Client client, Long roundNumber) {
2424
this.roundNumber = roundNumber;
2525
}
2626

27+
/**
28+
* Header only flag. When this is set to true, returned block does not contain the
29+
* transactions
30+
*/
31+
public LookupBlock headerOnly(Boolean headerOnly) {
32+
addQuery("header-only", String.valueOf(headerOnly));
33+
return this;
34+
}
35+
2736
/**
2837
* Execute the query.
2938
* @return the query response object.

src/main/java/com/algorand/algosdk/v2/client/model/Block.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ public String genesisHash() {
3333
@JsonProperty("genesis-id")
3434
public String genesisId;
3535

36+
/**
37+
* Participation account data that needs to be checked/acted on by the network.
38+
*/
39+
@JsonProperty("participation-updates")
40+
public ParticipationUpdates participationUpdates;
41+
3642
/**
3743
* (prev) Previous block hash.
3844
*/
@@ -150,6 +156,7 @@ public boolean equals(Object o) {
150156
Block other = (Block) o;
151157
if (!Objects.deepEquals(this.genesisHash, other.genesisHash)) return false;
152158
if (!Objects.deepEquals(this.genesisId, other.genesisId)) return false;
159+
if (!Objects.deepEquals(this.participationUpdates, other.participationUpdates)) return false;
153160
if (!Objects.deepEquals(this.previousBlockHash, other.previousBlockHash)) return false;
154161
if (!Objects.deepEquals(this.rewards, other.rewards)) return false;
155162
if (!Objects.deepEquals(this.round, other.round)) return false;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.algorand.algosdk.v2.client.model;
2+
3+
import java.util.Objects;
4+
5+
import com.algorand.algosdk.v2.client.common.PathResponse;
6+
import com.fasterxml.jackson.annotation.JsonProperty;
7+
8+
/**
9+
* Hash of a block header.
10+
*/
11+
public class BlockHashResponse extends PathResponse {
12+
13+
/**
14+
* Block header hash.
15+
*/
16+
@JsonProperty("blockHash")
17+
public String blockHash;
18+
19+
@Override
20+
public boolean equals(Object o) {
21+
22+
if (this == o) return true;
23+
if (o == null) return false;
24+
25+
BlockHashResponse other = (BlockHashResponse) o;
26+
if (!Objects.deepEquals(this.blockHash, other.blockHash)) return false;
27+
28+
return true;
29+
}
30+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.algorand.algosdk.v2.client.model;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Objects;
6+
7+
import com.algorand.algosdk.v2.client.common.PathResponse;
8+
import com.fasterxml.jackson.annotation.JsonProperty;
9+
10+
/**
11+
* Participation account data that needs to be checked/acted on by the network.
12+
*/
13+
public class ParticipationUpdates extends PathResponse {
14+
15+
/**
16+
* (partupdrmv) a list of online accounts that needs to be converted to offline
17+
* since their participation key expired.
18+
*/
19+
@JsonProperty("expired-participation-accounts")
20+
public List<String> expiredParticipationAccounts = new ArrayList<String>();
21+
22+
@Override
23+
public boolean equals(Object o) {
24+
25+
if (this == o) return true;
26+
if (o == null) return false;
27+
28+
ParticipationUpdates other = (ParticipationUpdates) o;
29+
if (!Objects.deepEquals(this.expiredParticipationAccounts, other.expiredParticipationAccounts)) return false;
30+
31+
return true;
32+
}
33+
}

src/test/java/com/algorand/algosdk/unit/AlgodPaths.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,9 @@ public void getLightBlockHeaderProof(Long round) {
9898
public void getStateProof(Long round) {
9999
ps.q = algodClient.GetStateProof(round);
100100
}
101+
102+
@When("we make a Lookup Block Hash call against round {long}")
103+
public void getBlockHash(Long round) {
104+
ps.q = algodClient.GetBlockHash(round);
105+
}
101106
}

src/test/java/com/algorand/algosdk/unit/IndexerPaths.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,4 +333,11 @@ public void searchForApplications(String string) {
333333
ps.q = q;
334334
}
335335

336+
337+
@When("we make a Lookup Block call against round {long} and header {string}")
338+
public void anyBlockLookupCall(Long round, String headerOnly) {
339+
LookupBlock q = this.indexerClient.lookupBlock(round);
340+
if (headerOnly.contentEquals("true")) q.headerOnly(true);
341+
ps.q = q;
342+
}
336343
}

0 commit comments

Comments
 (0)