Skip to content

Commit ebd2a3b

Browse files
author
Srinivasan Muralidharan
committedAug 26, 2016
Protocol buffer messages associated with the next architecture
This change includes a new fabric.proto file that defines messages between the SDK, endorsers, ordering service, and committers. These messages are required by the next architecture. The messages have been derived from the Hyperledger Protocol Working Group and many others working on the next architecture. This API is not the final form, but a proposed start that can be used and evolved as the new components are built. Appended "2" to those structs that are common with fabric.proto. This allows us fabric-next to co-exist with fabric and helps keep track of structures that would need to be renamed as integration progresses. Also introduced a ID field in Proposal to help make transition from current "Transaction" processing code in the fabric smoother (such as in chaincode execution paths which relies on a txid to keep track of transactions currently being processed). Added fabric-next_test.go to test for exact match for fields Change-Id: I42130175d6a81dc5de3d92c6adba7de0d3266bed Signed-off-by: Srinivasan Muralidharan <muralisr@us.ibm.com>
1 parent 8e5e8eb commit ebd2a3b

File tree

4 files changed

+671
-0
lines changed

4 files changed

+671
-0
lines changed
 

‎protos/api.pb.go

+11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎protos/fabric-next.pb.go

+307
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎protos/fabric-next.proto

+263
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
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.
15+
*/
16+
17+
syntax = "proto3";
18+
19+
package protos;
20+
21+
import "google/protobuf/timestamp.proto";
22+
23+
// This proto file defines messages that are passed between the SDK, endorsers,
24+
// the ordering service, and committers. The top level message is an
25+
// Envelope. This is used for all message passing. An Envelope contains a
26+
// Message2 (note the capital 'M' as this is a message named Message2) and a
27+
// Message2 has a payload.
28+
// Envelope -> Message2 -> payload
29+
//
30+
// The flow is as follows
31+
// SDK -[Proposal]-> Endorser -[ProposalResponse]-> SDK -[Transaction2]->
32+
// Ordering Service -[batch of Transaction2] -> Committer
33+
//
34+
// The SDK constructs a Proposal and sends it to one or more endorsers for
35+
// endorsement
36+
//
37+
// Endorsers create an Action for the given proposal and include the Action
38+
// in a ProposalResponse which is sent back to the SDK. The ProposalResponse
39+
// also contains an Endorsement which is the signature of the Action.
40+
//
41+
// When an SDK receives a ProposalResponse from and Endorser, it must look
42+
// at the proposalHash within the Action to correlate it with the
43+
// Proposal that was sent. After correlation, an SDK should
44+
// 1. Inspect the response within the PrposalResponse to confirm the
45+
// endorsement of the proposal was successful
46+
// 2. Confirm that the 'actionBytes' match for all ProposalResponses that
47+
// correlate to the same proposal hash.
48+
//
49+
// At this point, the SDK can construct an EndorsedAction. This is simply a
50+
// combination of the Action, all Endorsements, and the Proposal as an
51+
// optional field. One or more EndorsedActions can then be added to a
52+
// Transaction2. This Transaction2 is then submitted to the ordering service.
53+
// All endorsed actions contained in a single transaction are committed
54+
// atomically, meaning that either all actions in the transaction will be
55+
// committed or none will be committed.
56+
57+
// Protocol Buffer Limitation:
58+
// Something important to understand about protocol buffers is that while
59+
// serialization is deterministic in that it will always produce the same
60+
// bytes, deserialization is non-deterministic. This creates the following
61+
// issue. If a message is serialized and a hash is calculated based on the
62+
// bytes, then the message is deserialized, serialized, and the hash is
63+
// calculated again, the hashes may not match! To avoid this problem, you
64+
// will notice cases where the bytes of a message are included in a field
65+
// instead of the message itself. In locations where this is done, you will
66+
// see the acronym NDD (non-deterministic serialization).
67+
68+
// Envelope is used to deliver a message
69+
message Envelope {
70+
71+
// Signature of the message.
72+
bytes signature = 1;
73+
74+
// The message.
75+
Message2 message = 2;
76+
77+
}
78+
79+
// A Message2 encapsulates a payload of the indicated type in this message.
80+
message Message2 {
81+
82+
enum Type {
83+
84+
// Undefined exists to prevent invalid message construction.
85+
UNDEFINED = 0;
86+
87+
// Handshake messages.
88+
DISCOVERY = 1;
89+
90+
// Sent to catch up with existing peers.
91+
SYNC = 2;
92+
93+
// Sent from SDK to endorser. Payload is a Proposal.
94+
PROPOSAL = 3;
95+
96+
// Reserved for future use.
97+
PROPOSAL_SET = 4;
98+
99+
// Sent from endorser to SDK. Payload is a ProposalResponse.
100+
PROPOSAL_RESULT = 5;
101+
102+
// Reserved for future use.
103+
PROPOSAL_SET_RESULT = 6;
104+
105+
// Sent from SDK to peer for relay or ordering service. Payload is a
106+
// Transaction2.
107+
TRANSACTION = 7;
108+
109+
}
110+
111+
// Type of this message.
112+
Type type = 1;
113+
114+
// Version indicates message protocol version.
115+
int32 version = 2;
116+
117+
// Timestamp is the time that the message was created as defined by the
118+
// sender.
119+
google.protobuf.Timestamp timestamp = 3;
120+
121+
// The payload in this message.
122+
bytes payload = 4;
123+
124+
}
125+
126+
// A Proposal is sent to an endorser for endorsement. The proposal contains
127+
// a payload (such as a ChaincodeSpec) based on the type field.
128+
message Proposal {
129+
130+
enum Type {
131+
132+
// Undefined exists to prevent invalid message construction.
133+
UNDEFINED = 0;
134+
135+
// A chaincode. The payload is a ChaincodeSpec.
136+
CHAINCODE = 1;
137+
138+
}
139+
140+
// Type of this message.
141+
Type type = 1;
142+
143+
// Unique ID corresponding to this proposal
144+
string id = 2;
145+
146+
// The payload of the proposal as defined by the proposal type.
147+
bytes payload = 3;
148+
149+
}
150+
151+
// A response with a representation similar to an HTTP response that can
152+
// be used within another message.
153+
message Response2 {
154+
155+
// A status code that should follow the HTTP status codes.
156+
int32 status = 1;
157+
158+
// A message associated with the response code.
159+
string message = 2;
160+
161+
// A payload that can be used to include metadata with this response.
162+
bytes payload = 3;
163+
164+
}
165+
166+
// A SystemChaincode is a chaincode compiled into the peer that cannot
167+
// be modified at runtime. These are used to perform critical system level
168+
// functions, including processing endorsements and validating transactions.
169+
message SystemChaincode {
170+
171+
// The ID used to identify a system chaincode.
172+
string id = 1;
173+
174+
}
175+
176+
// An action to be taken against the ledger.
177+
message Action {
178+
179+
// Hash of proposal encoded in the Message2 payload. NDD.
180+
bytes proposalHash = 1;
181+
182+
// Uncommitted state changes (simulated) as calculated by the endorser.
183+
// This generally would include MVCC and PostImage information for both the
184+
// read set and write set. This is to be forwarded to the ordering
185+
// service as part of the transaction and must match the simulationResult
186+
// returned by other endorsers for the proposal.
187+
bytes simulationResult = 2;
188+
189+
// Events that should be sent by committers after the transaction is written
190+
// to the ledger. This is to be forwarded to the ordering
191+
// service as part of the transaction and must match the events
192+
// returned by other endorsers for the proposal.
193+
repeated bytes events = 3;
194+
195+
// ESCC (Endorser System Chaincode) is logic that is run prior to the
196+
// ProposalResponse being returned to the SDK. It can manipulate the
197+
// ProposalResponse as needed.
198+
SystemChaincode escc = 4;
199+
200+
// VSCC (Validaing System Chaincode) is logic that is run to transform the
201+
// raw ledger into the validated ledger.
202+
SystemChaincode vscc = 5;
203+
204+
}
205+
206+
// Endorsement is included within a proposal response.
207+
message Endorsement {
208+
209+
// Signature of the actionBytes included in the Endorsement.
210+
bytes signature = 1;
211+
212+
}
213+
214+
// A ProposalResponse is returned from an endorser to the proposal submitter.
215+
message ProposalResponse {
216+
217+
// A response message indicating whether the endorsement of the action
218+
// was successful. Additional metadata can be included. This will not
219+
// be forwarded from the SDK to the ordering service.
220+
Response2 response = 1;
221+
222+
// A serialized Action message. NDD.
223+
bytes actionBytes = 2;
224+
225+
// The endorsement of the action included in the proposal response
226+
Endorsement endorsement = 3;
227+
228+
}
229+
230+
// An EndorsedAction describes a single action endorsed by one or more
231+
// endorsers. Multiple endorsed actions can be included in a single
232+
// transaction. The transaction is atomic meaning that either all
233+
// actions in the transaction will be committed or none will be committed.
234+
message EndorsedAction {
235+
236+
// The action to be taken against the ledger. This is generally constructed
237+
// by an endorser. NDD.
238+
bytes actionBytes = 1;
239+
240+
// The endorsements of the action.
241+
repeated Endorsement endorsements = 2;
242+
243+
// The proposal. This is optional and only needed if the SDK wants to store
244+
// the Proposal on the ledger as opposed to just the hash. The proposal is
245+
// not included within the Action because it is the SDK's decision whether
246+
// or not they would like to include this information in the Transaction2.
247+
// If it was in the Action and signed, either the Endorsers would be
248+
// required to make the decision or the SDK would need to provide a hint
249+
// in the Proposal about whether it should be included in the Action.
250+
// TODO Revisit this decision.
251+
bytes proposalBytes = 3;
252+
253+
}
254+
255+
// The transaction to be sent to the ordering service. A transaction contains
256+
// one or more endorsed actions. The transaction is atomic meaning that either
257+
// all actions in the transaction will be committed or none will be committed.
258+
message Transaction2 {
259+
260+
// One or more endorsed actions to be committed to the ledger.
261+
repeated EndorsedAction endorsedActions = 1;
262+
263+
}

‎protos/fabric-next_test.go

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
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.
15+
*/
16+
17+
package protos
18+
19+
import (
20+
"testing"
21+
22+
"github.com/hyperledger/fabric/core/util"
23+
)
24+
25+
//Tests in this file are existential tests against fabric-next.
26+
//They test for exact match of fields and types. The intent is to catch
27+
//changes to fabric-next.proto file. Explicit initializers are deliberately
28+
//avoided (but in comments for comparison) for enforcing field match
29+
30+
//TestEnvelope tests fields in the Envelope structure
31+
func TestEnvelope(t *testing.T) {
32+
//Following equivalent to
33+
// _ = Envelope{Signature: []byte(""), Message: &Message2{Type: 0, Version: 0, Timestamp: util.CreateUtcTimestamp(), Payload: nil}}
34+
_ = Envelope{[]byte(""), &Message2{0, 0, util.CreateUtcTimestamp(), nil}}
35+
}
36+
37+
//TestProposal tests fields in the Proposal structure
38+
func TestProposal(t *testing.T) {
39+
//Following equivalent to
40+
// _ = Proposal{Type: 0, Id: "", Payload: []byte("")}
41+
_ = Proposal{0, "", []byte("")}
42+
}
43+
44+
//TestResponse2 tests fields in the Response2 structure
45+
func TestResponse2(t *testing.T) {
46+
//Following equivalent to
47+
// _ = Response2{Status: 0, Message: "", Payload: []byte("")}
48+
_ = Response2{0, "", []byte("")}
49+
}
50+
51+
//TestSystemChaincode tests fields in the SystemChaincode structure
52+
func TestSystemChaincode(t *testing.T) {
53+
//Following equivalent to
54+
// _ = SystemChaincode{Id: ""}
55+
}
56+
57+
//TestAction tests fields in the Action structure
58+
func TestAction(t *testing.T) {
59+
//Following equivalent to
60+
// _ = Action{ProposalHash: []byte(""), SimulationResult: []byte(""), Events: [][]byte{[]byte(""), []byte("")}, Escc: &SystemChaincode{Id: "cc1"}, Vscc: &SystemChaincode{Id: "cc2"}}
61+
_ = Action{[]byte(""), []byte(""), [][]byte{[]byte(""), []byte("")}, &SystemChaincode{"cc1"}, &SystemChaincode{"cc2"}}
62+
}
63+
64+
//TestEndorsement tests fields in the Endorsement structure
65+
func TestEndorsement(t *testing.T) {
66+
//Following equivalent to
67+
// _ = Endorsement{Signature: []byte("")}
68+
_ = Endorsement{[]byte("")}
69+
}
70+
71+
//TestProposalResponse tests fields in the ProposalResponse structure
72+
func TestProposalResponse(t *testing.T) {
73+
//Following equivalent to
74+
// _ = ProposalResponse{Response: &Response2{Status: 0, Message: "", Payload: []byte("")}, ActionBytes: []byte(""), Endorsement: &Endorsement{Signature: []byte("")}}
75+
_ = ProposalResponse{&Response2{0, "", []byte("")}, []byte(""), &Endorsement{[]byte("")}}
76+
}
77+
78+
//TestEndorsedAction tests fields in the EndorsedAction structure
79+
func TestEndorsedAction(t *testing.T) {
80+
//Following equivalent to
81+
// _ = EndorsedAction{ActionBytes: []byte(""), Endorsements: []*Endorsement{&Endorsement{Signature: []byte("")}}, ProposalBytes: []byte("")}
82+
_ = EndorsedAction{[]byte(""), []*Endorsement{&Endorsement{[]byte("")}}, []byte("")}
83+
}
84+
85+
//TestTransaction2 tests fields in the EndorsedAction structure
86+
func TestTransaction2(t *testing.T) {
87+
//Following equivalent to
88+
// _ = Transaction2{EndorsedActions: []*EndorsedAction{&EndorsedAction{ActionBytes: []byte(""), Endorsements: []*Endorsement{&Endorsement{Signature: []byte("")}}, ProposalBytes: []byte("")}}}
89+
_ = Transaction2{[]*EndorsedAction{&EndorsedAction{[]byte(""), []*Endorsement{&Endorsement{[]byte("")}}, []byte("")}}}
90+
}

0 commit comments

Comments
 (0)
Please sign in to comment.