code.vegaprotocol.io/vega@v0.79.0/core/datasource/external/ethcall/contract.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 ethcall 17 18 import ( 19 "encoding/hex" 20 "errors" 21 "strconv" 22 23 "code.vegaprotocol.io/vega/libs/crypto" 24 vegapb "code.vegaprotocol.io/vega/protos/vega" 25 ) 26 27 type ContractCallEvent struct { 28 BlockHeight uint64 29 BlockTime uint64 30 SpecId string 31 Result []byte 32 Error *string 33 SourceChainID *uint64 34 Heartbeat bool 35 } 36 37 func EthereumContractCallResultFromProto( 38 qr *vegapb.EthContractCallEvent, 39 ) (ContractCallEvent, error) { 40 res := ContractCallEvent{ 41 SpecId: qr.SpecId, 42 BlockHeight: qr.BlockHeight, 43 BlockTime: qr.BlockTime, 44 Result: qr.Result, 45 Error: qr.Error, 46 SourceChainID: qr.SourceChainId, 47 Heartbeat: qr.Heartbeat, 48 } 49 50 if qr.BlockHeight == 0 || qr.BlockTime <= 0 { 51 return ContractCallEvent{}, errors.New("invalid contract call payload") 52 } 53 54 if qr.Heartbeat { 55 return res, nil 56 } 57 58 if (len(qr.Result) <= 0 && qr.Error == nil) || len(qr.SpecId) <= 0 { 59 return ContractCallEvent{}, errors.New("invalid contract call payload") 60 } 61 62 return res, nil 63 } 64 65 func (q *ContractCallEvent) IntoProto() *vegapb.EthContractCallEvent { 66 return &vegapb.EthContractCallEvent{ 67 SpecId: q.SpecId, 68 BlockHeight: q.BlockHeight, 69 BlockTime: q.BlockTime, 70 Result: q.Result, 71 Error: q.Error, 72 SourceChainId: q.SourceChainID, 73 Heartbeat: q.Heartbeat, 74 } 75 } 76 77 func (q ContractCallEvent) Hash() string { 78 blockHeight := strconv.FormatUint(q.BlockHeight, 10) 79 blockTime := strconv.FormatUint(q.BlockTime, 10) 80 bytes := []byte(blockHeight + blockTime + q.SpecId) 81 bytes = append(bytes, q.Result...) 82 if q.Error != nil { 83 bytes = append(bytes, []byte(*q.Error)...) 84 } 85 86 if q.Heartbeat { 87 // only append if its true so that old events pre this flag existing hash to the same value 88 strconv.AppendBool(bytes, q.Heartbeat) 89 } 90 91 return hex.EncodeToString( 92 crypto.Hash(bytes), 93 ) 94 }