Skip to content

Commit 667a684

Browse files
authored
Merge pull request #16 from unicitynetwork/bft-uc
Inclusion proof verifies the unicity certificate
2 parents 60b66c5 + a524f17 commit 667a684

130 files changed

Lines changed: 6916 additions & 3745 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11

22
package org.unicitylabs.sdk;
33

4+
import java.util.List;
5+
import java.util.Objects;
6+
import java.util.concurrent.CompletableFuture;
47
import org.unicitylabs.sdk.api.IAggregatorClient;
8+
import org.unicitylabs.sdk.api.InclusionProofResponse;
59
import org.unicitylabs.sdk.api.RequestId;
610
import org.unicitylabs.sdk.api.SubmitCommitmentResponse;
11+
import org.unicitylabs.sdk.bft.RootTrustBase;
12+
import org.unicitylabs.sdk.predicate.PredicateEngineService;
713
import org.unicitylabs.sdk.token.Token;
814
import org.unicitylabs.sdk.token.TokenState;
15+
import org.unicitylabs.sdk.verification.VerificationException;
916
import org.unicitylabs.sdk.transaction.Commitment;
10-
import org.unicitylabs.sdk.transaction.InclusionProof;
1117
import org.unicitylabs.sdk.transaction.InclusionProofVerificationStatus;
1218
import org.unicitylabs.sdk.transaction.MintCommitment;
1319
import org.unicitylabs.sdk.transaction.MintTransactionData;
1420
import org.unicitylabs.sdk.transaction.Transaction;
1521
import org.unicitylabs.sdk.transaction.TransferCommitment;
1622
import org.unicitylabs.sdk.transaction.TransferTransactionData;
17-
import java.util.List;
18-
import java.util.Objects;
19-
import java.util.concurrent.CompletableFuture;
2023

2124
public class StateTransitionClient {
2225

@@ -27,7 +30,8 @@ public StateTransitionClient(IAggregatorClient client) {
2730
}
2831

2932
public <T extends MintTransactionData<?>> CompletableFuture<SubmitCommitmentResponse> submitCommitment(
30-
MintCommitment<T> commitment) {
33+
MintCommitment<T> commitment
34+
) {
3135
return this.client.submitCommitment(
3236
commitment.getRequestId(),
3337
commitment.getTransactionData().calculateHash(),
@@ -36,47 +40,53 @@ public <T extends MintTransactionData<?>> CompletableFuture<SubmitCommitmentResp
3640
}
3741

3842
public CompletableFuture<SubmitCommitmentResponse> submitCommitment(
39-
Token<?> token,
40-
TransferCommitment commitment) {
41-
if (!commitment.getTransactionData().getSourceState().getUnlockPredicate()
42-
.isOwner(commitment.getAuthenticator().getPublicKey())) {
43+
TransferCommitment commitment
44+
) {
45+
if (
46+
!PredicateEngineService.createPredicate(
47+
commitment.getTransactionData().getSourceState().getPredicate()
48+
).isOwner(commitment.getAuthenticator().getPublicKey())
49+
) {
4350
throw new IllegalArgumentException(
4451
"Ownership verification failed: Authenticator does not match source state predicate.");
4552
}
4653

4754
return this.client.submitCommitment(commitment.getRequestId(), commitment.getTransactionData()
48-
.calculateHash(token.getId(), token.getType()), commitment.getAuthenticator());
55+
.calculateHash(), commitment.getAuthenticator());
4956
}
5057

5158
public <T extends MintTransactionData<?>> Token<T> finalizeTransaction(
59+
RootTrustBase trustBase,
5260
Token<T> token,
5361
TokenState state,
5462
Transaction<TransferTransactionData> transaction
55-
) {
56-
return this.finalizeTransaction(token, state, transaction, List.of());
63+
) throws VerificationException {
64+
return this.finalizeTransaction(trustBase, token, state, transaction, List.of());
5765
}
5866

5967
public <T extends MintTransactionData<?>> Token<T> finalizeTransaction(
68+
RootTrustBase trustBase,
6069
Token<T> token,
6170
TokenState state,
6271
Transaction<TransferTransactionData> transaction,
63-
List<Token<?>> nametagTokens
64-
) {
72+
List<Token<?>> nametags
73+
) throws VerificationException {
6574
Objects.requireNonNull(token, "Token is null");
6675

67-
return token.update(state, transaction, nametagTokens);
76+
return token.update(trustBase, state, transaction, nametags);
6877
}
6978

7079
public CompletableFuture<InclusionProofVerificationStatus> getTokenStatus(
7180
Token<? extends MintTransactionData<?>> token,
72-
byte[] publicKey) {
73-
RequestId requestId = RequestId.create(publicKey,
74-
token.getState().calculateHash(token.getId(), token.getType()));
81+
byte[] publicKey,
82+
RootTrustBase trustBase
83+
) {
84+
RequestId requestId = RequestId.create(publicKey, token.getState().calculateHash());
7585
return this.client.getInclusionProof(requestId)
76-
.thenApply(inclusionProof -> inclusionProof.verify(requestId));
86+
.thenApply(response -> response.getInclusionProof().verify(requestId, trustBase));
7787
}
7888

79-
public CompletableFuture<InclusionProof> getInclusionProof(Commitment<?> commitment) {
89+
public CompletableFuture<InclusionProofResponse> getInclusionProof(Commitment<?> commitment) {
8090
return this.client.getInclusionProof(commitment.getRequestId());
8191
}
8292
}

src/main/java/org/unicitylabs/sdk/api/AggregatorClient.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
package org.unicitylabs.sdk.api;
22

3-
import org.unicitylabs.sdk.hash.DataHash;
4-
import org.unicitylabs.sdk.jsonrpc.JsonRpcHttpTransport;
5-
import org.unicitylabs.sdk.transaction.InclusionProof;
63
import java.util.Collections;
74
import java.util.concurrent.CompletableFuture;
5+
import org.unicitylabs.sdk.hash.DataHash;
6+
import org.unicitylabs.sdk.jsonrpc.JsonRpcHttpTransport;
87

98
public class AggregatorClient implements IAggregatorClient {
109

@@ -24,10 +23,10 @@ public CompletableFuture<SubmitCommitmentResponse> submitCommitment(
2423
return this.transport.request("submit_commitment", request, SubmitCommitmentResponse.class);
2524
}
2625

27-
public CompletableFuture<InclusionProof> getInclusionProof(RequestId requestId) {
26+
public CompletableFuture<InclusionProofResponse> getInclusionProof(RequestId requestId) {
2827
InclusionProofRequest request = new InclusionProofRequest(requestId);
2928

30-
return this.transport.request("get_inclusion_proof", request, InclusionProof.class);
29+
return this.transport.request("get_inclusion_proof", request, InclusionProofResponse.class);
3130
}
3231

3332
public CompletableFuture<Long> getBlockHeight() {
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11

22
package org.unicitylabs.sdk.api;
33

4-
import org.unicitylabs.sdk.hash.DataHash;
5-
import org.unicitylabs.sdk.transaction.InclusionProof;
6-
74
import java.util.concurrent.CompletableFuture;
5+
import org.unicitylabs.sdk.hash.DataHash;
86

97
public interface IAggregatorClient {
108

@@ -13,7 +11,7 @@ CompletableFuture<SubmitCommitmentResponse> submitCommitment(
1311
DataHash transactionHash,
1412
Authenticator authenticator);
1513

16-
CompletableFuture<InclusionProof> getInclusionProof(RequestId requestId);
14+
CompletableFuture<InclusionProofResponse> getInclusionProof(RequestId requestId);
1715

1816
CompletableFuture<Long> getBlockHeight();
1917
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.unicitylabs.sdk.api;
2+
3+
import org.unicitylabs.sdk.transaction.InclusionProof;
4+
5+
public class InclusionProofResponse {
6+
7+
private final InclusionProof inclusionProof;
8+
9+
public InclusionProofResponse(InclusionProof inclusionProof) {
10+
this.inclusionProof = inclusionProof;
11+
}
12+
13+
public InclusionProof getInclusionProof() {
14+
return this.inclusionProof;
15+
}
16+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package org.unicitylabs.sdk.bft;
2+
3+
import java.util.Arrays;
4+
import java.util.Objects;
5+
import org.unicitylabs.sdk.util.HexConverter;
6+
7+
public class InputRecord {
8+
9+
private final int version;
10+
private final long roundNumber;
11+
private final long epoch;
12+
private final byte[] previousHash;
13+
private final byte[] hash;
14+
private final byte[] summaryValue;
15+
private final long timestamp;
16+
private final byte[] blockHash;
17+
private final long sumOfEarnedFees;
18+
private final byte[] executedTransactionsHash;
19+
20+
public InputRecord(
21+
int version,
22+
long roundNumber,
23+
long epoch,
24+
byte[] previousHash,
25+
byte[] hash,
26+
byte[] summaryValue,
27+
long timestamp,
28+
byte[] blockHash,
29+
long sumOfEarnedFees,
30+
byte[] executedTransactionsHash
31+
) {
32+
Objects.requireNonNull(hash, "Hash cannot be null");
33+
Objects.requireNonNull(summaryValue, "Summary value cannot be null");
34+
35+
this.version = version;
36+
this.roundNumber = roundNumber;
37+
this.epoch = epoch;
38+
this.previousHash = previousHash;
39+
this.hash = hash;
40+
this.summaryValue = summaryValue;
41+
this.timestamp = timestamp;
42+
this.blockHash = blockHash;
43+
this.sumOfEarnedFees = sumOfEarnedFees;
44+
this.executedTransactionsHash = executedTransactionsHash;
45+
}
46+
47+
public int getVersion() {
48+
return this.version;
49+
}
50+
51+
public long getRoundNumber() {
52+
return this.roundNumber;
53+
}
54+
55+
public long getEpoch() {
56+
return this.epoch;
57+
}
58+
59+
public byte[] getPreviousHash() {
60+
return this.previousHash != null ? Arrays.copyOf(this.previousHash, this.previousHash.length) : null;
61+
}
62+
63+
public byte[] getHash() {
64+
return this.hash != null ? Arrays.copyOf(this.hash, this.hash.length) : null;
65+
}
66+
67+
public byte[] getSummaryValue() {
68+
return Arrays.copyOf(this.summaryValue, this.summaryValue.length);
69+
}
70+
71+
public long getTimestamp() {
72+
return this.timestamp;
73+
}
74+
75+
public byte[] getBlockHash() {
76+
return this.blockHash != null ? Arrays.copyOf(this.blockHash, this.blockHash.length) : null;
77+
}
78+
79+
public long getSumOfEarnedFees() {
80+
return this.sumOfEarnedFees;
81+
}
82+
83+
public byte[] getExecutedTransactionsHash() {
84+
return this.executedTransactionsHash != null ? Arrays.copyOf(this.executedTransactionsHash, this.executedTransactionsHash.length) : null;
85+
}
86+
87+
@Override
88+
public boolean equals(Object o) {
89+
if (!(o instanceof InputRecord)) {
90+
return false;
91+
}
92+
InputRecord that = (InputRecord) o;
93+
return Objects.equals(this.version, that.version) && Objects.equals(this.roundNumber,
94+
that.roundNumber) && Objects.equals(this.epoch, that.epoch)
95+
&& Objects.deepEquals(this.previousHash, that.previousHash)
96+
&& Objects.deepEquals(this.hash, that.hash) && Objects.deepEquals(this.summaryValue,
97+
that.summaryValue) && Objects.equals(this.timestamp, that.timestamp)
98+
&& Objects.deepEquals(this.blockHash, that.blockHash) && Objects.equals(
99+
this.sumOfEarnedFees, that.sumOfEarnedFees) && Objects.deepEquals(
100+
this.executedTransactionsHash, that.executedTransactionsHash);
101+
}
102+
103+
@Override
104+
public int hashCode() {
105+
return Objects.hash(this.version, this.roundNumber, this.epoch,
106+
Arrays.hashCode(this.previousHash),
107+
Arrays.hashCode(this.hash), Arrays.hashCode(this.summaryValue), this.timestamp,
108+
Arrays.hashCode(this.blockHash),
109+
this.sumOfEarnedFees, Arrays.hashCode(this.executedTransactionsHash));
110+
}
111+
112+
@Override
113+
public String toString() {
114+
return String.format("InputRecord{version=%s, roundNumber=%s, epoch=%s, previousHash=%s, "
115+
+ "hash=%s, summaryValue=%s, timestamp=%s, blockHash=%s, sumOfEarnedFees=%s, "
116+
+ "executedTransactionsHash=%s}",
117+
this.version,
118+
this.roundNumber,
119+
this.epoch,
120+
this.previousHash != null ? HexConverter.encode(this.previousHash) : null,
121+
this.hash != null ? HexConverter.encode(this.hash) : null,
122+
HexConverter.encode(this.summaryValue),
123+
this.timestamp,
124+
this.blockHash != null ? HexConverter.encode(this.blockHash) : null,
125+
this.sumOfEarnedFees,
126+
this.executedTransactionsHash != null ? HexConverter.encode(this.executedTransactionsHash) : null
127+
);
128+
}
129+
}

0 commit comments

Comments
 (0)