Skip to content

Commit 15a9028

Browse files
author
Jason Yellick
committed
[FAB-4370] Basic EndorserTx support in protolator
There have been numerous requests on rocketchat with people attempting to inspect the endorser transaction contents. Thanks to the complicated structure of the endorser tx protos, it is very difficult for a casual user to turn the binary blob into a human readable form. This CR adds basic support for decoding typical endorser transactions. Note: It makes no effort to handle transactions which have the proposal visibility set to anything other than full, and no effort to support endorser transactions which are not chaincode related (to my knowledge, these are unimplemented). Change-Id: I246b5a4ec60ae5748a4eedc064da54f1d3e92672 Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
1 parent b0632c0 commit 15a9028

File tree

5 files changed

+115
-20
lines changed

5 files changed

+115
-20
lines changed

protos/common/common.go

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
11
/*
2-
Copyright IBM Corp. 2017 All Rights Reserved.
2+
Copyright IBM Corp. All Rights Reserved.
33
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
4+
SPDX-License-Identifier: Apache-2.0
155
*/
166

177
package common
@@ -37,6 +27,11 @@ func (p *Payload) VariablyOpaqueFields() []string {
3727
return []string{"data"}
3828
}
3929

30+
var PayloadDataMap = map[int32]proto.Message{
31+
int32(HeaderType_CONFIG): &ConfigEnvelope{},
32+
int32(HeaderType_CONFIG_UPDATE): &ConfigUpdateEnvelope{},
33+
}
34+
4035
func (p *Payload) VariablyOpaqueFieldProto(name string) (proto.Message, error) {
4136
if name != p.VariablyOpaqueFields()[0] {
4237
return nil, fmt.Errorf("not a marshaled field: %s", name)
@@ -49,15 +44,10 @@ func (p *Payload) VariablyOpaqueFieldProto(name string) (proto.Message, error) {
4944
return nil, fmt.Errorf("corrupt channel header: %s", err)
5045
}
5146

52-
switch ch.Type {
53-
case int32(HeaderType_CONFIG):
54-
return &ConfigEnvelope{}, nil
55-
case int32(HeaderType_CONFIG_UPDATE):
56-
return &ConfigUpdateEnvelope{}, nil
57-
// TODO implement the other well known types, particularly endorser txs
58-
default:
59-
return nil, fmt.Errorf("decoding type %v is unimplemented", ch.Type)
47+
if msg, ok := PayloadDataMap[ch.Type]; ok {
48+
return msg, nil
6049
}
50+
return nil, fmt.Errorf("decoding type %v is unimplemented", ch.Type)
6151
}
6252

6353
func (h *Header) StaticallyOpaqueFields() []string {

protos/peer/proposal.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package peer
8+
9+
import (
10+
"fmt"
11+
12+
"github.com/golang/protobuf/proto"
13+
)
14+
15+
func (cpp *ChaincodeProposalPayload) StaticallyOpaqueFields() []string {
16+
return []string{"input"}
17+
}
18+
19+
func (cpp *ChaincodeProposalPayload) StaticallyOpaqueFieldProto(name string) (proto.Message, error) {
20+
if name != cpp.StaticallyOpaqueFields()[0] {
21+
return nil, fmt.Errorf("not a marshaled field: %s", name)
22+
}
23+
return &ChaincodeInvocationSpec{}, nil
24+
}

protos/peer/proposal.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ message ChaincodeProposalPayload {
240240

241241
// Input contains the arguments for this invocation. If this invocation
242242
// deploys a new chaincode, ESCC/VSCC are part of this field.
243+
// This is usually a marshaled ChaincodeInvocationSpec
243244
bytes input = 1;
244245

245246
// TransientMap contains data (e.g. cryptographic material) that might be used

protos/peer/proposal_response.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package peer
8+
9+
import (
10+
"fmt"
11+
12+
"github.com/golang/protobuf/proto"
13+
)
14+
15+
func (ppr *ProposalResponsePayload) StaticallyOpaqueFields() []string {
16+
return []string{"extension"}
17+
}
18+
19+
func (ppr *ProposalResponsePayload) StaticallyOpaqueFieldProto(name string) (proto.Message, error) {
20+
if name != ppr.StaticallyOpaqueFields()[0] {
21+
return nil, fmt.Errorf("not a marshaled field: %s", name)
22+
}
23+
return &ChaincodeAction{}, nil
24+
}

protos/peer/transaction.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package peer
8+
9+
import (
10+
"fmt"
11+
12+
"github.com/hyperledger/fabric/protos/common"
13+
14+
"github.com/golang/protobuf/proto"
15+
)
16+
17+
func init() {
18+
common.PayloadDataMap[int32(common.HeaderType_ENDORSER_TRANSACTION)] = &Transaction{}
19+
}
20+
21+
func (ta *TransactionAction) StaticallyOpaqueFields() []string {
22+
return []string{"header", "payload"}
23+
}
24+
25+
func (ta *TransactionAction) StaticallyOpaqueFieldProto(name string) (proto.Message, error) {
26+
switch name {
27+
case ta.StaticallyOpaqueFields()[0]:
28+
return &common.SignatureHeader{}, nil
29+
case ta.StaticallyOpaqueFields()[1]:
30+
return &ChaincodeActionPayload{}, nil
31+
default:
32+
return nil, fmt.Errorf("not a marshaled field: %s", name)
33+
}
34+
}
35+
36+
func (cap *ChaincodeActionPayload) StaticallyOpaqueFields() []string {
37+
return []string{"chaincode_proposal_payload"}
38+
}
39+
40+
func (cap *ChaincodeActionPayload) StaticallyOpaqueFieldProto(name string) (proto.Message, error) {
41+
if name != cap.StaticallyOpaqueFields()[0] {
42+
return nil, fmt.Errorf("not a marshaled field: %s", name)
43+
}
44+
return &ChaincodeProposalPayload{}, nil
45+
}
46+
47+
func (cae *ChaincodeEndorsedAction) StaticallyOpaqueFields() []string {
48+
return []string{"proposal_response_payload"}
49+
}
50+
51+
func (cae *ChaincodeEndorsedAction) StaticallyOpaqueFieldProto(name string) (proto.Message, error) {
52+
if name != cae.StaticallyOpaqueFields()[0] {
53+
return nil, fmt.Errorf("not a marshaled field: %s", name)
54+
}
55+
return &ProposalResponsePayload{}, nil
56+
}

0 commit comments

Comments
 (0)