1
1
package assets
2
2
3
+ import (
4
+ "net/http"
5
+ "time"
6
+
7
+ "github.com/goledgerdev/cc-tools/errors"
8
+ sw "github.com/goledgerdev/cc-tools/stubwrapper"
9
+ )
10
+
3
11
// AssetTypeList returns a copy of the assetTypeList variable.
4
12
func AssetTypeList () []AssetType {
5
13
listCopy := make ([]AssetType , len (assetTypeList ))
@@ -19,5 +27,194 @@ func FetchAssetType(assetTypeTag string) *AssetType {
19
27
20
28
// InitAssetList appends custom assets to assetTypeList to avoid initialization loop.
21
29
func InitAssetList (l []AssetType ) {
30
+ if GetEnabledDynamicAssetType () {
31
+ l = append (l , GetListAssetType ())
32
+ }
33
+ assetTypeList = l
34
+ }
35
+
36
+ // ReplaceAssetList replace assetTypeList to for a new one
37
+ func ReplaceAssetList (l []AssetType ) {
22
38
assetTypeList = l
23
39
}
40
+
41
+ // UpdateAssetList updates the assetTypeList variable on runtime
42
+ func UpdateAssetList (l []AssetType ) {
43
+ assetTypeList = append (assetTypeList , l ... )
44
+ }
45
+
46
+ // RemoveAssetType removes an asset type from an AssetType List and returns the new list
47
+ func RemoveAssetType (tag string , l []AssetType ) []AssetType {
48
+ for i , assetType := range l {
49
+ if assetType .Tag == tag {
50
+ l = append (l [:i ], l [i + 1 :]... )
51
+ }
52
+ }
53
+ return l
54
+ }
55
+
56
+ // ReplaceAssetType replaces an asset type from an AssetType List with an updated version and returns the new list
57
+ // This function does not automatically update the assetTypeList variable
58
+ func ReplaceAssetType (assetType AssetType , l []AssetType ) []AssetType {
59
+ for i , v := range l {
60
+ if v .Tag == assetType .Tag {
61
+ l [i ] = assetType
62
+ }
63
+ }
64
+ return l
65
+ }
66
+
67
+ // StoreAssetList stores the current assetList on the blockchain
68
+ func StoreAssetList (stub * sw.StubWrapper ) errors.ICCError {
69
+ assetList := AssetTypeList ()
70
+ l := ArrayFromAssetTypeList (assetList )
71
+
72
+ txTimestamp , err := stub .Stub .GetTxTimestamp ()
73
+ if err != nil {
74
+ return errors .WrapError (err , "failed to get tx timestamp" )
75
+ }
76
+ txTime := txTimestamp .AsTime ()
77
+ txTimeStr := txTime .Format (time .RFC3339 )
78
+
79
+ listKey , err := NewKey (map [string ]interface {}{
80
+ "@assetType" : "assetTypeListData" ,
81
+ "id" : "primary" ,
82
+ })
83
+ if err != nil {
84
+ return errors .NewCCError ("error getting asset list key" , http .StatusInternalServerError )
85
+ }
86
+
87
+ exists , err := listKey .ExistsInLedger (stub )
88
+ if err != nil {
89
+ return errors .NewCCError ("error checking if asset list exists" , http .StatusInternalServerError )
90
+ }
91
+
92
+ if exists {
93
+ listAsset , err := listKey .Get (stub )
94
+ if err != nil {
95
+ return errors .WrapError (err , "error getting asset list" )
96
+ }
97
+ listMap := (map [string ]interface {})(* listAsset )
98
+
99
+ listMap ["list" ] = l
100
+ listMap ["lastUpdated" ] = txTimeStr
101
+
102
+ _ , err = listAsset .Update (stub , listMap )
103
+ if err != nil {
104
+ return errors .WrapError (err , "error updating asset list" )
105
+ }
106
+ } else {
107
+ listMap := map [string ]interface {}{
108
+ "@assetType" : "assetTypeListData" ,
109
+ "id" : "primary" ,
110
+ "list" : l ,
111
+ "lastUpdated" : txTimeStr ,
112
+ }
113
+
114
+ listAsset , err := NewAsset (listMap )
115
+ if err != nil {
116
+ return errors .WrapError (err , "error creating asset list" )
117
+ }
118
+
119
+ _ , err = listAsset .PutNew (stub )
120
+ if err != nil {
121
+ return errors .WrapError (err , "error putting asset list" )
122
+ }
123
+ }
124
+
125
+ SetAssetListUpdateTime (txTime )
126
+
127
+ return nil
128
+ }
129
+
130
+ // RestoreAssetList restores the assetList from the blockchain
131
+ func RestoreAssetList (stub * sw.StubWrapper , init bool ) errors.ICCError {
132
+ listKey , err := NewKey (map [string ]interface {}{
133
+ "@assetType" : "assetTypeListData" ,
134
+ "id" : "primary" ,
135
+ })
136
+ if err != nil {
137
+ return errors .NewCCError ("error gettin asset list key" , http .StatusInternalServerError )
138
+ }
139
+
140
+ exists , err := listKey .ExistsInLedger (stub )
141
+ if err != nil {
142
+ return errors .NewCCError ("error checking if asset list exists" , http .StatusInternalServerError )
143
+ }
144
+
145
+ if exists {
146
+ listAsset , err := listKey .Get (stub )
147
+ if err != nil {
148
+ return errors .NewCCError ("error getting asset list" , http .StatusInternalServerError )
149
+ }
150
+ listMap := (map [string ]interface {})(* listAsset )
151
+
152
+ txTime := listMap ["lastUpdated" ].(time.Time )
153
+
154
+ if GetAssetListUpdateTime ().After (txTime ) {
155
+ return nil
156
+ }
157
+
158
+ l := AssetTypeListFromArray (listMap ["list" ].([]interface {}))
159
+
160
+ l = getRestoredList (l , init )
161
+
162
+ ReplaceAssetList (l )
163
+
164
+ SetAssetListUpdateTime (txTime )
165
+ }
166
+
167
+ return nil
168
+ }
169
+
170
+ // getRestoredList reconstructs the assetTypeList from the stored list comparing to the current list
171
+ func getRestoredList (storedList []AssetType , init bool ) []AssetType {
172
+ assetList := AssetTypeList ()
173
+
174
+ deleteds := AssetTypeList ()
175
+
176
+ for _ , assetTypeStored := range storedList {
177
+ if ! assetTypeStored .Dynamic {
178
+ continue
179
+ }
180
+
181
+ exists := false
182
+ for i , assetType := range assetList {
183
+ if assetType .Tag == assetTypeStored .Tag {
184
+ exists = true
185
+
186
+ assetTypeStored .Validate = assetType .Validate
187
+ assetList [i ] = assetTypeStored
188
+
189
+ deleteds = RemoveAssetType (assetType .Tag , deleteds )
190
+
191
+ break
192
+ }
193
+ }
194
+ if ! exists {
195
+ assetList = append (assetList , assetTypeStored )
196
+ }
197
+ }
198
+
199
+ if ! init {
200
+ for _ , deleted := range deleteds {
201
+ if ! deleted .Dynamic {
202
+ continue
203
+ }
204
+
205
+ assetList = RemoveAssetType (deleted .Tag , assetList )
206
+ }
207
+ }
208
+
209
+ return assetList
210
+ }
211
+
212
+ // GetAssetListUpdateTime returns the last time the asset list was updated
213
+ func GetAssetListUpdateTime () time.Time {
214
+ return listUpdateTime
215
+ }
216
+
217
+ // SetAssetListUpdateTime sets the last time the asset list was updated
218
+ func SetAssetListUpdateTime (t time.Time ) {
219
+ listUpdateTime = t
220
+ }
0 commit comments