code.vegaprotocol.io/vega@v0.79.0/datanode/entities/erc20_multisig_event.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package entities 17 18 import ( 19 "context" 20 "encoding/json" 21 "fmt" 22 "strconv" 23 "time" 24 25 v2 "code.vegaprotocol.io/vega/protos/data-node/api/v2" 26 eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1" 27 ) 28 29 type NotaryService interface { 30 GetByResourceID(ctx context.Context, id string, pagination CursorPagination) ([]NodeSignature, PageInfo, error) 31 } 32 33 type ERC20MultiSigSignerEventType string 34 35 const ( 36 ERC20MultiSigSignerEventTypeAdded ERC20MultiSigSignerEventType = "SIGNER_ADDED" 37 ERC20MultiSigSignerEventTypeRemoved ERC20MultiSigSignerEventType = "SIGNER_REMOVED" 38 ) 39 40 type _ERC20MultiSigSignerEvent struct{} 41 42 type ERC20MultiSigSignerEventID = ID[_ERC20MultiSigSignerEvent] 43 44 type ERC20MultiSigSignerEvent struct { 45 ID ERC20MultiSigSignerEventID 46 ValidatorID NodeID 47 SignerChange EthereumAddress 48 Submitter EthereumAddress 49 Nonce string 50 TxHash TxHash 51 VegaTime time.Time 52 EpochID int64 53 Event ERC20MultiSigSignerEventType 54 ChainID string 55 } 56 57 func (e ERC20MultiSigSignerEvent) Cursor() *Cursor { 58 ec := ERC20MultiSigSignerEventCursor{ 59 VegaTime: e.VegaTime, 60 ID: e.ID, 61 } 62 63 return NewCursor(ec.String()) 64 } 65 66 func ERC20MultiSigSignerEventFromAddedProto(e *eventspb.ERC20MultiSigSignerAdded, txHash TxHash) (*ERC20MultiSigSignerEvent, error) { 67 epochID, err := strconv.ParseInt(e.EpochSeq, 10, 64) 68 if err != nil { 69 return &ERC20MultiSigSignerEvent{}, fmt.Errorf("parsing epoch '%v': %w", e.EpochSeq, err) 70 } 71 return &ERC20MultiSigSignerEvent{ 72 ID: ERC20MultiSigSignerEventID(e.SignatureId), 73 ValidatorID: NodeID(e.ValidatorId), 74 SignerChange: EthereumAddress(e.NewSigner), 75 Submitter: EthereumAddress(e.Submitter), 76 Nonce: e.Nonce, 77 TxHash: txHash, 78 VegaTime: time.Unix(0, e.Timestamp), 79 EpochID: epochID, 80 Event: ERC20MultiSigSignerEventTypeAdded, 81 ChainID: e.ChainId, 82 }, nil 83 } 84 85 func ERC20MultiSigSignerEventFromRemovedProto(e *eventspb.ERC20MultiSigSignerRemoved, txHash TxHash) ([]*ERC20MultiSigSignerEvent, error) { 86 events := []*ERC20MultiSigSignerEvent{} 87 88 epochID, err := strconv.ParseInt(e.EpochSeq, 10, 64) 89 if err != nil { 90 return nil, fmt.Errorf("parsing epoch '%v': %w", e.EpochSeq, err) 91 } 92 for _, s := range e.SignatureSubmitters { 93 events = append(events, &ERC20MultiSigSignerEvent{ 94 ID: ERC20MultiSigSignerEventID(s.SignatureId), 95 Submitter: EthereumAddress(s.Submitter), 96 SignerChange: EthereumAddress(e.OldSigner), 97 ValidatorID: NodeID(e.ValidatorId), 98 Nonce: e.Nonce, 99 TxHash: txHash, 100 VegaTime: time.Unix(0, e.Timestamp), 101 EpochID: epochID, 102 Event: ERC20MultiSigSignerEventTypeRemoved, 103 ChainID: e.ChainId, 104 }, 105 ) 106 } 107 108 return events, nil 109 } 110 111 type ERC20MultiSigSignerEventCursor struct { 112 VegaTime time.Time `json:"vega_time"` 113 ID ERC20MultiSigSignerEventID `json:"id"` 114 } 115 116 func (c ERC20MultiSigSignerEventCursor) String() string { 117 bs, err := json.Marshal(c) 118 // This should never fail so we should panic if it does 119 if err != nil { 120 panic(fmt.Errorf("failed to convert")) 121 } 122 return string(bs) 123 } 124 125 func (c *ERC20MultiSigSignerEventCursor) Parse(cursorString string) error { 126 if cursorString == "" { 127 return nil 128 } 129 130 return json.Unmarshal([]byte(cursorString), c) 131 } 132 133 type ERC20MultiSigSignerAddedEvent struct { 134 ERC20MultiSigSignerEvent 135 } 136 137 func (e ERC20MultiSigSignerAddedEvent) Cursor() *Cursor { 138 ec := ERC20MultiSigSignerEventCursor{ 139 VegaTime: e.VegaTime, 140 ID: e.ID, 141 } 142 143 return NewCursor(ec.String()) 144 } 145 146 func (e ERC20MultiSigSignerAddedEvent) ToProto() *eventspb.ERC20MultiSigSignerAdded { 147 return &eventspb.ERC20MultiSigSignerAdded{ 148 SignatureId: e.ID.String(), 149 ValidatorId: e.ValidatorID.String(), 150 Timestamp: e.VegaTime.UnixNano(), 151 NewSigner: e.SignerChange.String(), 152 Submitter: e.Submitter.String(), 153 Nonce: e.Nonce, 154 EpochSeq: strconv.FormatInt(e.EpochID, 10), 155 ChainId: e.ChainID, 156 } 157 } 158 159 func (e ERC20MultiSigSignerAddedEvent) ToDataNodeApiV2Proto(ctx context.Context, notaryService NotaryService) (*v2.ERC20MultiSigSignerAddedBundle, error) { 160 signatures, _, err := notaryService.GetByResourceID(ctx, e.ID.String(), CursorPagination{}) 161 if err != nil { 162 return nil, err 163 } 164 165 return &v2.ERC20MultiSigSignerAddedBundle{ 166 NewSigner: e.SignerChange.String(), 167 Submitter: e.Submitter.String(), 168 Nonce: e.Nonce, 169 Timestamp: e.VegaTime.UnixNano(), 170 Signatures: PackNodeSignatures(signatures), 171 EpochSeq: strconv.FormatInt(e.EpochID, 10), 172 ChainId: e.ChainID, 173 }, nil 174 } 175 176 func (e ERC20MultiSigSignerAddedEvent) ToProtoEdge(_ ...any) (*v2.ERC20MultiSigSignerAddedEdge, error) { 177 return &v2.ERC20MultiSigSignerAddedEdge{ 178 Node: e.ToProto(), 179 Cursor: e.Cursor().Encode(), 180 }, nil 181 } 182 183 type ERC20MultiSigSignerRemovedEvent struct { 184 ERC20MultiSigSignerEvent 185 } 186 187 func (e ERC20MultiSigSignerRemovedEvent) Cursor() *Cursor { 188 ec := ERC20MultiSigSignerEventCursor{ 189 VegaTime: e.VegaTime, 190 ID: e.ID, 191 } 192 193 return NewCursor(ec.String()) 194 } 195 196 func (e ERC20MultiSigSignerRemovedEvent) ToProto() *eventspb.ERC20MultiSigSignerRemoved { 197 return &eventspb.ERC20MultiSigSignerRemoved{ 198 SignatureSubmitters: nil, 199 ValidatorId: e.ValidatorID.String(), 200 Timestamp: e.VegaTime.UnixNano(), 201 OldSigner: e.SignerChange.String(), 202 Nonce: e.Nonce, 203 EpochSeq: strconv.FormatInt(e.EpochID, 10), 204 ChainId: e.ChainID, 205 } 206 } 207 208 func (e ERC20MultiSigSignerRemovedEvent) ToDataNodeApiV2Proto(ctx context.Context, notaryService NotaryService) (*v2.ERC20MultiSigSignerRemovedBundle, error) { 209 signatures, _, err := notaryService.GetByResourceID(ctx, e.ID.String(), CursorPagination{}) 210 if err != nil { 211 return nil, err 212 } 213 214 return &v2.ERC20MultiSigSignerRemovedBundle{ 215 OldSigner: e.SignerChange.String(), 216 Submitter: e.Submitter.String(), 217 Nonce: e.Nonce, 218 Timestamp: e.VegaTime.UnixNano(), 219 Signatures: PackNodeSignatures(signatures), 220 EpochSeq: strconv.FormatInt(e.EpochID, 10), 221 ChainId: e.ChainID, 222 }, nil 223 } 224 225 func (e ERC20MultiSigSignerRemovedEvent) ToProtoEdge(_ ...any) (*v2.ERC20MultiSigSignerRemovedEdge, error) { 226 return &v2.ERC20MultiSigSignerRemovedEdge{ 227 Node: e.ToProto(), 228 Cursor: e.Cursor().Encode(), 229 }, nil 230 }