Skip to content

Commit 3cb86b0

Browse files
Luis SanchezJingxiao Gu
authored andcommitted
[FAB-3648] add getCreator() API
Change-Id: I854268bc3f20d8bece9d0ae3f4529e2a62bb67bf Signed-off-by: Luis Sanchez <sanchezl@us.ibm.com>
1 parent 5982e40 commit 3cb86b0

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

shim/src/main/java/org/hyperledger/fabric/shim/ChaincodeStub.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,12 @@ default void putStringState(String key, String value) {
301301
*/
302302
Instant getTxTimestamp();
303303

304+
/**
305+
* Returns the identity of the agent (or user) submitting the transaction.
306+
*
307+
* @return the bytes of the creator field of the proposal's signature
308+
* header.
309+
*/
310+
byte[] getCreator();
311+
304312
}

shim/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeStubImpl.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
import com.google.protobuf.ByteString;
1010
import com.google.protobuf.InvalidProtocolBufferException;
1111
import com.google.protobuf.Timestamp;
12+
import org.hyperledger.fabric.protos.common.Common;
1213
import org.hyperledger.fabric.protos.common.Common.ChannelHeader;
1314
import org.hyperledger.fabric.protos.common.Common.Header;
15+
import org.hyperledger.fabric.protos.common.Common.HeaderType;
16+
import org.hyperledger.fabric.protos.common.Common.SignatureHeader;
1417
import org.hyperledger.fabric.protos.ledger.queryresult.KvQueryResult;
1518
import org.hyperledger.fabric.protos.ledger.queryresult.KvQueryResult.KV;
1619
import org.hyperledger.fabric.protos.peer.ChaincodeEventPackage.ChaincodeEvent;
@@ -40,6 +43,7 @@ class ChaincodeStubImpl implements ChaincodeStub {
4043
private final List<ByteString> args;
4144
private final SignedProposal signedProposal;
4245
private final Instant txTimestamp;
46+
private final ByteString creator;
4347
private ChaincodeEvent event;
4448

4549
ChaincodeStubImpl(String txId, Handler handler, List<ByteString> args, SignedProposal signedProposal) {
@@ -48,20 +52,35 @@ class ChaincodeStubImpl implements ChaincodeStub {
4852
this.args = Collections.unmodifiableList(args);
4953
this.signedProposal = signedProposal;
5054
if(this.signedProposal == null) {
55+
this.creator = null;
5156
this.txTimestamp = null;
5257
} else {
5358
try {
5459
final Proposal proposal = Proposal.parseFrom(signedProposal.getProposalBytes());
5560
final Header header = Header.parseFrom(proposal.getHeader());
5661
final ChannelHeader channelHeader = ChannelHeader.parseFrom(header.getChannelHeader());
62+
validateProposalType(channelHeader);
63+
final SignatureHeader signatureHeader = SignatureHeader.parseFrom(header.getSignatureHeader());
64+
5765
final Timestamp timestamp = channelHeader.getTimestamp();
5866
this.txTimestamp = Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos());
67+
this.creator = signatureHeader.getCreator();
5968
} catch (InvalidProtocolBufferException e) {
6069
throw new RuntimeException(e);
6170
}
6271
}
6372
}
6473

74+
private void validateProposalType(ChannelHeader channelHeader) {
75+
switch (Common.HeaderType.forNumber(channelHeader.getType())) {
76+
case ENDORSER_TRANSACTION:
77+
case CONFIG:
78+
return;
79+
default:
80+
throw new RuntimeException(String.format("Unexpected transaction type: %s", HeaderType.forNumber(channelHeader.getType())));
81+
}
82+
}
83+
6584
@Override
6685
public List<byte[]> getArgs() {
6786
return args.stream().map(x -> x.toByteArray()).collect(Collectors.toList());
@@ -212,4 +231,9 @@ public Instant getTxTimestamp() {
212231
return txTimestamp;
213232
}
214233

234+
@Override
235+
public byte[] getCreator() {
236+
if(creator == null) return null;
237+
return creator.toByteArray();
238+
}
215239
}

shim/src/test/java/org/hyperledger/fabric/shim/impl/ChaincodeStubImplTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.hamcrest.Matchers;
1212
import org.hyperledger.fabric.protos.common.Common.ChannelHeader;
1313
import org.hyperledger.fabric.protos.common.Common.Header;
14+
import org.hyperledger.fabric.protos.common.Common.SignatureHeader;
1415
import org.hyperledger.fabric.protos.ledger.queryresult.KvQueryResult;
1516
import org.hyperledger.fabric.protos.ledger.queryresult.KvQueryResult.KV;
1617
import org.hyperledger.fabric.protos.peer.ChaincodeEventPackage.ChaincodeEvent;
@@ -373,4 +374,30 @@ public void testGetTxTimestampNullSignedProposal() {
373374
final ChaincodeStubImpl stub = new ChaincodeStubImpl("txid", handler, new ArrayList<>(), null);
374375
assertThat(stub.getTxTimestamp(), is(nullValue()));
375376
}
377+
378+
@Test
379+
public void testGetCreator() {
380+
final Instant instant = Instant.now();
381+
final byte[] creator = "CREATOR".getBytes(UTF_8);
382+
final Timestamp timestamp = Timestamp.newBuilder().setSeconds(instant.getEpochSecond()).setNanos(instant.getNano()).build();
383+
final SignedProposal signedProposal = SignedProposal.newBuilder()
384+
.setProposalBytes(Proposal.newBuilder()
385+
.setHeader(Header.newBuilder()
386+
.setChannelHeader(ChannelHeader.newBuilder()
387+
.setType(ENDORSER_TRANSACTION_VALUE)
388+
.setTimestamp(timestamp)
389+
.build().toByteString()
390+
)
391+
.setSignatureHeader(SignatureHeader.newBuilder()
392+
.setCreator(ByteString.copyFrom(creator))
393+
.build().toByteString()
394+
)
395+
.build().toByteString()
396+
)
397+
.build().toByteString()
398+
).build();
399+
final ChaincodeStubImpl stub = new ChaincodeStubImpl("txid", handler, new ArrayList<>(), signedProposal);
400+
assertThat(stub.getCreator(), is(creator));
401+
}
402+
376403
}

0 commit comments

Comments
 (0)