@@ -23,13 +23,49 @@ import (
23
23
24
24
"github.com/golang/protobuf/proto"
25
25
26
+ "bytes"
27
+
28
+ "github.com/hyperledger/fabric/bccsp"
29
+ "github.com/hyperledger/fabric/bccsp/factory"
26
30
pb "github.com/hyperledger/fabric/protos/peer"
27
31
)
28
32
33
+ //----- CDSData ------
34
+
35
+ //CDSData is data stored in the LCCC on instantiation of a CC
36
+ //for CDSPackage. This needs to be serialized for ChaincodeData
37
+ //hence the protobuf format
38
+ type CDSData struct {
39
+ //CodeHash hash of CodePackage from ChaincodeDeploymentSpec
40
+ CodeHash []byte `protobuf:"bytes,1,opt,name=codehash,proto3"`
41
+
42
+ //MetaDataHash hash of Name and Version from ChaincodeDeploymentSpec
43
+ MetaDataHash []byte `protobuf:"bytes,2,opt,name=metadatahash,proto3"`
44
+ }
45
+
46
+ //----implement functions needed from proto.Message for proto's mar/unmarshal functions
47
+
48
+ //Reset resets
49
+ func (data * CDSData ) Reset () { * data = CDSData {} }
50
+
51
+ //String convers to string
52
+ func (data * CDSData ) String () string { return proto .CompactTextString (data ) }
53
+
54
+ //ProtoMessage just exists to make proto happy
55
+ func (* CDSData ) ProtoMessage () {}
56
+
57
+ //Equals data equals other
58
+ func (data * CDSData ) Equals (other * CDSData ) bool {
59
+ return other != nil && bytes .Equal (data .CodeHash , other .CodeHash ) && bytes .Equal (data .MetaDataHash , other .MetaDataHash )
60
+ }
61
+
62
+ //--------- CDSPackage ------------
63
+
29
64
//CDSPackage encapsulates ChaincodeDeploymentSpec.
30
65
type CDSPackage struct {
31
66
buf []byte
32
67
depSpec * pb.ChaincodeDeploymentSpec
68
+ data * CDSData
33
69
}
34
70
35
71
// GetDepSpec gets the ChaincodeDeploymentSpec from the package
@@ -42,16 +78,75 @@ func (ccpack *CDSPackage) GetPackageObject() proto.Message {
42
78
return ccpack .depSpec
43
79
}
44
80
81
+ func (ccpack * CDSPackage ) getCDSData (cds * pb.ChaincodeDeploymentSpec ) ([]byte , * CDSData , error ) {
82
+ // check for nil argument. It is an assertion that getCDSData
83
+ // is never called on a package that did not go through/succeed
84
+ // package initialization.
85
+ if cds == nil {
86
+ panic ("nil cds" )
87
+ }
88
+
89
+ b , err := proto .Marshal (cds )
90
+ if err != nil {
91
+ return nil , nil , err
92
+ }
93
+
94
+ if err = factory .InitFactories (nil ); err != nil {
95
+ return nil , nil , fmt .Errorf ("Internal error, BCCSP could not be initialized : %s" , err )
96
+ }
97
+
98
+ //compute hashes now
99
+ hash , err := factory .GetDefault ().GetHash (& bccsp.SHAOpts {})
100
+ if err != nil {
101
+ return nil , nil , err
102
+ }
103
+
104
+ cdsdata := & CDSData {}
105
+
106
+ //code hash
107
+ cdsdata .CodeHash = hash .Sum (cds .CodePackage )
108
+
109
+ hash .Reset ()
110
+
111
+ //metadata hash
112
+ hash .Write ([]byte (cds .ChaincodeSpec .ChaincodeId .Name ))
113
+ hash .Write ([]byte (cds .ChaincodeSpec .ChaincodeId .Version ))
114
+
115
+ cdsdata .MetaDataHash = hash .Sum (nil )
116
+
117
+ b , err = proto .Marshal (cdsdata )
118
+ if err != nil {
119
+ return nil , nil , err
120
+ }
121
+
122
+ return b , cdsdata , nil
123
+ }
124
+
45
125
// ValidateCC returns error if the chaincode is not found or if its not a
46
126
// ChaincodeDeploymentSpec
47
127
func (ccpack * CDSPackage ) ValidateCC (ccdata * ChaincodeData ) (* pb.ChaincodeDeploymentSpec , error ) {
48
128
if ccpack .depSpec == nil {
49
129
return nil , fmt .Errorf ("uninitialized package" )
50
130
}
131
+
132
+ if ccpack .data == nil {
133
+ return nil , fmt .Errorf ("nil data" )
134
+ }
135
+
51
136
if ccdata .Name != ccpack .depSpec .ChaincodeSpec .ChaincodeId .Name || ccdata .Version != ccpack .depSpec .ChaincodeSpec .ChaincodeId .Version {
52
137
return nil , fmt .Errorf ("invalid chaincode data %v (%v)" , ccdata , ccpack .depSpec .ChaincodeSpec .ChaincodeId )
53
138
}
54
- //for now just return chaincode. When we introduce Hash we will do more checks
139
+
140
+ otherdata := & CDSData {}
141
+ err := proto .Unmarshal (ccdata .Data , otherdata )
142
+ if err != nil {
143
+ return nil , err
144
+ }
145
+
146
+ if ! ccpack .data .Equals (otherdata ) {
147
+ return nil , fmt .Errorf ("data mismatch" )
148
+ }
149
+
55
150
return ccpack .depSpec , nil
56
151
}
57
152
@@ -60,22 +155,32 @@ func (ccpack *CDSPackage) InitFromBuffer(buf []byte) (*ChaincodeData, error) {
60
155
//incase ccpack is reused
61
156
ccpack .buf = nil
62
157
ccpack .depSpec = nil
158
+ ccpack .data = nil
63
159
64
160
depSpec := & pb.ChaincodeDeploymentSpec {}
65
161
err := proto .Unmarshal (buf , depSpec )
66
162
if err != nil {
67
163
return nil , fmt .Errorf ("failed to unmarshal deployment spec from bytes" )
68
164
}
165
+
166
+ databytes , data , err := ccpack .getCDSData (depSpec )
167
+ if err != nil {
168
+ return nil , err
169
+ }
170
+
69
171
ccpack .buf = buf
70
172
ccpack .depSpec = depSpec
71
- return & ChaincodeData {Name : depSpec .ChaincodeSpec .ChaincodeId .Name , Version : depSpec .ChaincodeSpec .ChaincodeId .Version }, nil
173
+ ccpack .data = data
174
+
175
+ return & ChaincodeData {Name : depSpec .ChaincodeSpec .ChaincodeId .Name , Version : depSpec .ChaincodeSpec .ChaincodeId .Version , Data : databytes }, nil
72
176
}
73
177
74
178
//InitFromFS returns the chaincode and its package from the file system
75
179
func (ccpack * CDSPackage ) InitFromFS (ccname string , ccversion string ) ([]byte , * pb.ChaincodeDeploymentSpec , error ) {
76
180
//incase ccpack is reused
77
181
ccpack .buf = nil
78
182
ccpack .depSpec = nil
183
+ ccpack .data = nil
79
184
80
185
buf , err := GetChaincodePackage (ccname , ccversion )
81
186
if err != nil {
@@ -88,8 +193,14 @@ func (ccpack *CDSPackage) InitFromFS(ccname string, ccversion string) ([]byte, *
88
193
return nil , nil , fmt .Errorf ("failed to unmarshal fs deployment spec for %s, %s" , ccname , ccversion )
89
194
}
90
195
196
+ _ , data , err := ccpack .getCDSData (depSpec )
197
+ if err != nil {
198
+ return nil , nil , err
199
+ }
200
+
91
201
ccpack .buf = buf
92
202
ccpack .depSpec = depSpec
203
+ ccpack .data = data
93
204
94
205
return buf , depSpec , nil
95
206
}
@@ -104,6 +215,10 @@ func (ccpack *CDSPackage) PutChaincodeToFS() error {
104
215
return fmt .Errorf ("depspec cannot be nil if buf is not nil" )
105
216
}
106
217
218
+ if ccpack .data == nil {
219
+ return fmt .Errorf ("nil data" )
220
+ }
221
+
107
222
ccname := ccpack .depSpec .ChaincodeSpec .ChaincodeId .Name
108
223
ccversion := ccpack .depSpec .ChaincodeSpec .ChaincodeId .Version
109
224
0 commit comments