github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/types/ibc-adapter/events.go (about) 1 package types 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "reflect" 7 "sort" 8 "strings" 9 10 abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types" 11 "github.com/gogo/protobuf/jsonpb" 12 proto "github.com/gogo/protobuf/proto" 13 14 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 15 kv "github.com/fibonacci-chain/fbc/libs/tendermint/libs/kv" 16 ) 17 18 // ---------------------------------------------------------------------------- 19 // Event Manager 20 // ---------------------------------------------------------------------------- 21 22 // EventManager implements a simple wrapper around a slice of Event objects that 23 // can be emitted from. 24 type EventManager struct { 25 events Events 26 } 27 28 func NewEventManager() *EventManager { 29 return &EventManager{EmptyEvents()} 30 } 31 32 func (em *EventManager) Events() Events { return em.events } 33 34 // EmitEvent stores a single Event object. 35 // Deprecated: Use EmitTypedEvent 36 func (em *EventManager) EmitEvent(event Event) { 37 em.events = em.events.AppendEvent(event) 38 } 39 40 // EmitEvents stores a series of Event objects. 41 // Deprecated: Use EmitTypedEvents 42 func (em *EventManager) EmitEvents(events Events) { 43 em.events = em.events.AppendEvents(events) 44 } 45 46 // ABCIEvents returns all stored Event objects as abci.Event objects. 47 func (em EventManager) ABCIEvents() []abci.Event { 48 return em.events.ToABCIEvents() 49 } 50 51 // EmitTypedEvent takes typed event and emits converting it into Event 52 func (em *EventManager) EmitTypedEvent(tev proto.Message) error { 53 event, err := TypedEventToEvent(tev) 54 if err != nil { 55 return err 56 } 57 58 em.EmitEvent(event) 59 return nil 60 } 61 62 // EmitTypedEvents takes series of typed events and emit 63 func (em *EventManager) EmitTypedEvents(tevs ...proto.Message) error { 64 events := make(Events, len(tevs)) 65 for i, tev := range tevs { 66 res, err := TypedEventToEvent(tev) 67 if err != nil { 68 return err 69 } 70 events[i] = res 71 } 72 73 em.EmitEvents(events) 74 return nil 75 } 76 77 // TypedEventToEvent takes typed event and converts to Event object 78 func TypedEventToEvent(tev proto.Message) (Event, error) { 79 evtType := proto.MessageName(tev) 80 evtJSON, err := codec.ProtoMarshalJSON(tev, nil) 81 if err != nil { 82 return Event{}, err 83 } 84 85 var attrMap map[string]json.RawMessage 86 err = json.Unmarshal(evtJSON, &attrMap) 87 if err != nil { 88 return Event{}, err 89 } 90 91 //attrs := make([]abci.EventAttribute, 0, len(attrMap)) 92 attrs := make([]kv.Pair, 0, len(attrMap)) 93 for k, v := range attrMap { 94 attrs = append(attrs, kv.Pair{ 95 Key: []byte(k), 96 Value: v, 97 }) 98 } 99 100 return Event{ 101 Type: evtType, 102 Attributes: attrs, 103 }, nil 104 } 105 106 // ParseTypedEvent converts abci.Event back to typed event 107 func ParseTypedEvent(event abci.Event) (proto.Message, error) { 108 concreteGoType := proto.MessageType(event.Type) 109 if concreteGoType == nil { 110 return nil, fmt.Errorf("failed to retrieve the message of type %q", event.Type) 111 } 112 113 var value reflect.Value 114 if concreteGoType.Kind() == reflect.Ptr { 115 value = reflect.New(concreteGoType.Elem()) 116 } else { 117 value = reflect.Zero(concreteGoType) 118 } 119 120 protoMsg, ok := value.Interface().(proto.Message) 121 if !ok { 122 return nil, fmt.Errorf("%q does not implement proto.Message", event.Type) 123 } 124 125 attrMap := make(map[string]json.RawMessage) 126 for _, attr := range event.Attributes { 127 attrMap[string(attr.Key)] = attr.Value 128 } 129 130 attrBytes, err := json.Marshal(attrMap) 131 if err != nil { 132 return nil, err 133 } 134 135 err = jsonpb.Unmarshal(strings.NewReader(string(attrBytes)), protoMsg) 136 if err != nil { 137 return nil, err 138 } 139 140 return protoMsg, nil 141 } 142 143 // ---------------------------------------------------------------------------- 144 // Events 145 // ---------------------------------------------------------------------------- 146 147 type ( 148 // Event is a type alias for an ABCI Event 149 Event abci.Event 150 151 // Events defines a slice of Event objects 152 Events []Event 153 ) 154 155 // NewEvent creates a new Event object with a given type and slice of one or more 156 // attributes. 157 func NewEvent(ty string, attrs ...Attribute) Event { 158 e := Event{Type: ty} 159 160 for _, attr := range attrs { 161 e.Attributes = append(e.Attributes, attr.ToKVPair()) 162 } 163 164 return e 165 } 166 167 // NewAttribute returns a new key/value Attribute object. 168 func NewAttribute(k, v string) Attribute { 169 return Attribute{k, v} 170 } 171 172 // EmptyEvents returns an empty slice of events. 173 func EmptyEvents() Events { 174 return make(Events, 0) 175 } 176 177 func (a Attribute) String() string { 178 return fmt.Sprintf("%s: %s", a.Key, a.Value) 179 } 180 181 // ToKVPair converts an Attribute object into a Tendermint key/value pair. 182 // 183 // func (a Attribute) ToKVPair() abci.EventAttribute { 184 // return abci.EventAttribute{Key: toBytes(a.Key), Value: toBytes(a.Value)} 185 // } 186 func (a Attribute) ToKVPair() kv.Pair { 187 return kv.Pair{Key: toBytes(a.Key), Value: toBytes(a.Value)} 188 } 189 190 // AppendAttributes adds one or more attributes to an Event. 191 func (e Event) AppendAttributes(attrs ...Attribute) Event { 192 for _, attr := range attrs { 193 //e.Attributes = append(e.Attributes, attr.ToKVPair()) 194 e.Attributes = append(e.Attributes, attr.ToKVPair()) 195 } 196 return e 197 } 198 199 // AppendEvent adds an Event to a slice of events. 200 func (e Events) AppendEvent(event Event) Events { 201 return append(e, event) 202 } 203 204 // AppendEvents adds a slice of Event objects to an exist slice of Event objects. 205 func (e Events) AppendEvents(events Events) Events { 206 return append(e, events...) 207 } 208 209 // ToABCIEvents converts a slice of Event objects to a slice of abci.Event 210 // objects. 211 func (e Events) ToABCIEvents() []abci.Event { 212 res := make([]abci.Event, len(e)) 213 for i, ev := range e { 214 res[i] = abci.Event{Type: ev.Type, Attributes: ev.Attributes} 215 } 216 217 return res 218 } 219 220 func toBytes(i interface{}) []byte { 221 switch x := i.(type) { 222 case []uint8: 223 return x 224 case string: 225 return []byte(x) 226 default: 227 panic(i) 228 } 229 } 230 231 // Common event types and attribute keys 232 var ( 233 EventTypeTx = "tx" 234 235 AttributeKeyAccountSequence = "acc_seq" 236 AttributeKeySignature = "signature" 237 AttributeKeyFee = "fee" 238 239 EventTypeMessage = "message" 240 241 AttributeKeyAction = "action" 242 AttributeKeyModule = "module" 243 AttributeKeySender = "sender" 244 AttributeKeyAmount = "amount" 245 ) 246 247 type ( 248 // StringAttributes defines a slice of StringEvents objects. 249 StringEvents []StringEvent 250 ) 251 252 func (se StringEvents) String() string { 253 var sb strings.Builder 254 255 for _, e := range se { 256 sb.WriteString(fmt.Sprintf("\t\t- %s\n", e.Type)) 257 258 for _, attr := range e.Attributes { 259 sb.WriteString(fmt.Sprintf("\t\t\t- %s\n", attr.String())) 260 } 261 } 262 263 return strings.TrimRight(sb.String(), "\n") 264 } 265 266 // Flatten returns a flattened version of StringEvents by grouping all attributes 267 // per unique event type. 268 func (se StringEvents) Flatten() StringEvents { 269 flatEvents := make(map[string][]Attribute) 270 271 for _, e := range se { 272 flatEvents[e.Type] = append(flatEvents[e.Type], e.Attributes...) 273 } 274 keys := make([]string, 0, len(flatEvents)) 275 res := make(StringEvents, 0, len(flatEvents)) // appeneded to keys, same length of what is allocated to keys 276 277 for ty := range flatEvents { 278 keys = append(keys, ty) 279 } 280 281 sort.Strings(keys) 282 for _, ty := range keys { 283 res = append(res, StringEvent{Type: ty, Attributes: flatEvents[ty]}) 284 } 285 286 return res 287 } 288 289 // StringifyEvent converts an Event object to a StringEvent object. 290 func StringifyEvent(e abci.Event) StringEvent { 291 res := StringEvent{Type: e.Type} 292 293 for _, attr := range e.Attributes { 294 res.Attributes = append( 295 res.Attributes, 296 Attribute{string(attr.Key), string(attr.Value)}, 297 ) 298 } 299 300 return res 301 } 302 303 // StringifyEvents converts a slice of Event objects into a slice of StringEvent 304 // objects. 305 func StringifyEvents(events []abci.Event) StringEvents { 306 res := make(StringEvents, 0, len(events)) 307 308 for _, e := range events { 309 res = append(res, StringifyEvent(e)) 310 } 311 312 return res.Flatten() 313 } 314 315 // MarkEventsToIndex returns the set of ABCI events, where each event's attribute 316 // has it's index value marked based on the provided set of events to index. 317 func MarkEventsToIndex(events []abci.Event, indexSet map[string]struct{}) []abci.Event { 318 //indexAll := len(indexSet) == 0 319 updatedEvents := make([]abci.Event, len(events)) 320 321 for i, e := range events { 322 updatedEvent := abci.Event{ 323 Type: e.Type, 324 Attributes: make([]kv.Pair, len(e.Attributes)), 325 } 326 327 for j, attr := range e.Attributes { 328 //_, index := indexSet[fmt.Sprintf("%s.%s", e.Type, attr.Key)] 329 updatedAttr := kv.Pair{ 330 Key: attr.Key, 331 Value: attr.Value, 332 //Index: index || indexAll, 333 } 334 335 updatedEvent.Attributes[j] = updatedAttr 336 } 337 338 updatedEvents[i] = updatedEvent 339 } 340 341 return updatedEvents 342 }