mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-17 07:25:10 +00:00
Add getCreator() to parsed transaction in off_chain_data sample (#806)
Example of how the client identity that submitted a transaction can be obtained. Signed-off-by: Mark S. Lewis <mark_lewis@uk.ibm.com>
This commit is contained in:
parent
cb4355125f
commit
51397fe78a
6 changed files with 120 additions and 103 deletions
|
|
@ -10,6 +10,7 @@ import com.google.protobuf.InvalidProtocolBufferException;
|
|||
import org.hyperledger.fabric.protos.common.ChannelHeader;
|
||||
import org.hyperledger.fabric.protos.common.HeaderType;
|
||||
import org.hyperledger.fabric.protos.common.Payload;
|
||||
import org.hyperledger.fabric.protos.common.SignatureHeader;
|
||||
import org.hyperledger.fabric.protos.peer.TxValidationCode;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
|
@ -18,6 +19,7 @@ class ParsedPayload {
|
|||
private final Payload payload;
|
||||
private final TxValidationCode statusCode;
|
||||
private final AtomicReference<ChannelHeader> cachedChannelHeader = new AtomicReference<>();
|
||||
private final AtomicReference<SignatureHeader> cachedSignatureHeader = new AtomicReference<>();
|
||||
|
||||
ParsedPayload(final Payload payload, final TxValidationCode statusCode) {
|
||||
this.payload = payload;
|
||||
|
|
@ -28,6 +30,10 @@ class ParsedPayload {
|
|||
return Utils.getCachedProto(cachedChannelHeader, () -> ChannelHeader.parseFrom(payload.getHeader().getChannelHeader()));
|
||||
}
|
||||
|
||||
public SignatureHeader getSignatureHeader() throws InvalidProtocolBufferException {
|
||||
return Utils.getCachedProto(cachedSignatureHeader, () -> SignatureHeader.parseFrom(payload.getHeader().getSignatureHeader()));
|
||||
}
|
||||
|
||||
public TxValidationCode getValidationCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ final class ParsedTransaction implements Transaction {
|
|||
return payload.getChannelHeader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getCreator() throws InvalidProtocolBufferException {
|
||||
return payload.getSignatureHeader().getCreator().toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TxValidationCode getValidationCode() {
|
||||
return payload.getValidationCode();
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import java.util.List;
|
|||
|
||||
public interface Transaction {
|
||||
ChannelHeader getChannelHeader() throws InvalidProtocolBufferException;
|
||||
byte[] getCreator() throws InvalidProtocolBufferException;
|
||||
TxValidationCode getValidationCode();
|
||||
boolean isValid();
|
||||
List<NamespaceReadWriteSet> getNamespaceReadWriteSets() throws InvalidProtocolBufferException;
|
||||
|
|
|
|||
99
off_chain_data/application-typescript/.eslintrc.js
Normal file
99
off_chain_data/application-typescript/.eslintrc.js
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
module.exports = {
|
||||
env: {
|
||||
node: true,
|
||||
es2020: true,
|
||||
},
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
],
|
||||
root: true,
|
||||
ignorePatterns: [
|
||||
'dist/',
|
||||
],
|
||||
rules: {
|
||||
'arrow-spacing': ['error'],
|
||||
'comma-style': ['error'],
|
||||
complexity: ['error', 10],
|
||||
'eol-last': ['error'],
|
||||
'generator-star-spacing': ['error', 'after'],
|
||||
'key-spacing': [
|
||||
'error',
|
||||
{
|
||||
beforeColon: false,
|
||||
afterColon: true,
|
||||
mode: 'minimum',
|
||||
},
|
||||
],
|
||||
'keyword-spacing': ['error'],
|
||||
'no-multiple-empty-lines': ['error'],
|
||||
'no-trailing-spaces': ['error'],
|
||||
'no-whitespace-before-property': ['error'],
|
||||
'object-curly-newline': ['error'],
|
||||
'padded-blocks': ['error', 'never'],
|
||||
'rest-spread-spacing': ['error'],
|
||||
'semi-style': ['error'],
|
||||
'space-before-blocks': ['error'],
|
||||
'space-in-parens': ['error'],
|
||||
'space-unary-ops': ['error'],
|
||||
'spaced-comment': ['error'],
|
||||
'template-curly-spacing': ['error'],
|
||||
'yield-star-spacing': ['error', 'after'],
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
'**/*.ts',
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
impliedStrict: true,
|
||||
},
|
||||
project: './tsconfig.json',
|
||||
tsconfigRootDir: process.env.TSCONFIG_ROOT_DIR || __dirname,
|
||||
},
|
||||
plugins: [
|
||||
'@typescript-eslint',
|
||||
],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||
],
|
||||
rules: {
|
||||
'@typescript-eslint/comma-spacing': ['error'],
|
||||
'@typescript-eslint/explicit-function-return-type': [
|
||||
'error',
|
||||
{
|
||||
allowExpressions: true,
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/func-call-spacing': ['error'],
|
||||
'@typescript-eslint/member-delimiter-style': ['error'],
|
||||
'@typescript-eslint/indent': [
|
||||
'error',
|
||||
4,
|
||||
{
|
||||
SwitchCase: 0,
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/prefer-nullish-coalescing': ['error'],
|
||||
'@typescript-eslint/prefer-optional-chain': ['error'],
|
||||
'@typescript-eslint/prefer-reduce-type-parameter': ['error'],
|
||||
'@typescript-eslint/prefer-return-this-type': ['error'],
|
||||
'@typescript-eslint/quotes': ['error', 'single'],
|
||||
'@typescript-eslint/type-annotation-spacing': ['error'],
|
||||
'@typescript-eslint/semi': ['error'],
|
||||
'@typescript-eslint/space-before-function-paren': [
|
||||
'error',
|
||||
{
|
||||
anonymous: 'never',
|
||||
named: 'never',
|
||||
asyncArrow: 'always',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
env:
|
||||
node: true
|
||||
es2020: true
|
||||
extends:
|
||||
- eslint:recommended
|
||||
rules:
|
||||
arrow-spacing:
|
||||
- error
|
||||
comma-style:
|
||||
- error
|
||||
complexity:
|
||||
- error
|
||||
- 10
|
||||
eol-last:
|
||||
- error
|
||||
generator-star-spacing:
|
||||
- error
|
||||
- after
|
||||
key-spacing:
|
||||
- error
|
||||
- beforeColon: false
|
||||
afterColon: true
|
||||
mode: minimum
|
||||
keyword-spacing:
|
||||
- error
|
||||
no-multiple-empty-lines:
|
||||
- error
|
||||
no-trailing-spaces:
|
||||
- error
|
||||
no-whitespace-before-property:
|
||||
- error
|
||||
object-curly-newline:
|
||||
- error
|
||||
padded-blocks:
|
||||
- error
|
||||
- never
|
||||
rest-spread-spacing:
|
||||
- error
|
||||
semi-style:
|
||||
- error
|
||||
space-before-blocks:
|
||||
- error
|
||||
space-in-parens:
|
||||
- error
|
||||
space-unary-ops:
|
||||
- error
|
||||
spaced-comment:
|
||||
- error
|
||||
template-curly-spacing:
|
||||
- error
|
||||
yield-star-spacing:
|
||||
- error
|
||||
- after
|
||||
overrides:
|
||||
- files:
|
||||
- "**/*.ts"
|
||||
parser: "@typescript-eslint/parser"
|
||||
parserOptions:
|
||||
sourceType: module
|
||||
ecmaFeatures:
|
||||
impliedStrict: true
|
||||
project: "tsconfig.json"
|
||||
tsconfigRootDir: "."
|
||||
plugins:
|
||||
- "@typescript-eslint"
|
||||
extends:
|
||||
- eslint:recommended
|
||||
- plugin:@typescript-eslint/recommended
|
||||
- plugin:@typescript-eslint/recommended-requiring-type-checking
|
||||
rules:
|
||||
"@typescript-eslint/comma-spacing":
|
||||
- error
|
||||
"@typescript-eslint/explicit-function-return-type":
|
||||
- error
|
||||
- allowExpressions: true
|
||||
"@typescript-eslint/func-call-spacing":
|
||||
- error
|
||||
"@typescript-eslint/member-delimiter-style":
|
||||
- error
|
||||
"@typescript-eslint/indent":
|
||||
- error
|
||||
- 4
|
||||
- SwitchCase: 0
|
||||
"@typescript-eslint/prefer-nullish-coalescing":
|
||||
- error
|
||||
"@typescript-eslint/prefer-optional-chain":
|
||||
- error
|
||||
"@typescript-eslint/prefer-reduce-type-parameter":
|
||||
- error
|
||||
"@typescript-eslint/prefer-return-this-type":
|
||||
- error
|
||||
"@typescript-eslint/quotes":
|
||||
- error
|
||||
- single
|
||||
"@typescript-eslint/type-annotation-spacing":
|
||||
- error
|
||||
"@typescript-eslint/semi":
|
||||
- error
|
||||
"@typescript-eslint/space-before-function-paren":
|
||||
- error
|
||||
- anonymous: never
|
||||
named: never
|
||||
asyncArrow: always
|
||||
|
|
@ -15,6 +15,7 @@ export interface Block {
|
|||
|
||||
export interface Transaction {
|
||||
getChannelHeader(): common.ChannelHeader;
|
||||
getCreator(): Uint8Array;
|
||||
getValidationCode(): number;
|
||||
isValid(): boolean;
|
||||
getNamespaceReadWriteSets(): NamespaceReadWriteSet[];
|
||||
|
|
@ -46,6 +47,7 @@ export function parseBlock(block: common.Block): Block {
|
|||
interface Payload {
|
||||
getChannelHeader(): common.ChannelHeader;
|
||||
getEndorserTransaction(): EndorserTransaction;
|
||||
getSignatureHeader(): common.SignatureHeader;
|
||||
getTransactionValidationCode(): number;
|
||||
isEndorserTransaction(): boolean;
|
||||
isValid(): boolean;
|
||||
|
|
@ -75,6 +77,7 @@ function parsePayload(payload: common.Payload, statusCode: number): Payload {
|
|||
const transaction = peer.Transaction.deserializeBinary(payload.getData_asU8());
|
||||
return parseEndorserTransaction(transaction);
|
||||
},
|
||||
getSignatureHeader: cache(() => getSignatureHeader(payload)),
|
||||
getTransactionValidationCode: () => statusCode,
|
||||
isEndorserTransaction,
|
||||
isValid: () => statusCode === peer.TxValidationCode.VALID,
|
||||
|
|
@ -103,6 +106,7 @@ function newTransaction(payload: Payload): Transaction {
|
|||
|
||||
return {
|
||||
getChannelHeader: () => payload.getChannelHeader(),
|
||||
getCreator: () => payload.getSignatureHeader().getCreator_asU8(),
|
||||
getNamespaceReadWriteSets: () => transaction.getReadWriteSets()
|
||||
.flatMap(readWriteSet => readWriteSet.getNamespaceReadWriteSets()),
|
||||
getValidationCode: () => payload.getTransactionValidationCode(),
|
||||
|
|
@ -151,6 +155,11 @@ function getChannelHeader(payload: common.Payload): common.ChannelHeader {
|
|||
return common.ChannelHeader.deserializeBinary(header.getChannelHeader_asU8());
|
||||
}
|
||||
|
||||
function getSignatureHeader(payload: common.Payload): common.SignatureHeader {
|
||||
const header = assertDefined(payload.getHeader(), 'Missing payload header');
|
||||
return common.SignatureHeader.deserializeBinary(header.getSignatureHeader_asU8());
|
||||
}
|
||||
|
||||
function getChaincodeActionPayloads(transaction: peer.Transaction): peer.ChaincodeActionPayload[] {
|
||||
return transaction.getActionsList()
|
||||
.map(transactionAction => transactionAction.getPayload_asU8())
|
||||
|
|
|
|||
Loading…
Reference in a new issue