structs.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. package vaa
  2. import (
  3. "bytes"
  4. "crypto/ecdsa"
  5. "encoding"
  6. "encoding/binary"
  7. "encoding/hex"
  8. "errors"
  9. "fmt"
  10. "io"
  11. "math/big"
  12. "strings"
  13. "time"
  14. "github.com/ethereum/go-ethereum/common"
  15. "github.com/ethereum/go-ethereum/crypto"
  16. )
  17. type (
  18. // VAA is a verifiable action approval of the Wormhole protocol
  19. VAA struct {
  20. // Version of the VAA schema
  21. Version uint8
  22. // GuardianSetIndex is the index of the guardian set that signed this VAA
  23. GuardianSetIndex uint32
  24. // SignatureData is the signature of the guardian set
  25. Signatures []*Signature
  26. // Timestamp when the VAA was created
  27. Timestamp time.Time
  28. // Nonce of the VAA
  29. Nonce uint32
  30. // Sequence of the VAA
  31. Sequence uint64
  32. /// ConsistencyLevel of the VAA
  33. ConsistencyLevel uint8
  34. // EmitterChain the VAA was emitted on
  35. EmitterChain ChainID
  36. // EmitterAddress of the contract that emitted the Message
  37. EmitterAddress Address
  38. // Payload of the message
  39. Payload []byte
  40. }
  41. // ChainID of a Wormhole chain
  42. ChainID uint16
  43. // Action of a VAA
  44. Action uint8
  45. // Address is a Wormhole protocol address, it contains the native chain's address. If the address data type of a
  46. // chain is < 32bytes the value is zero-padded on the left.
  47. Address [32]byte
  48. // Signature of a single guardian
  49. Signature struct {
  50. // Index of the validator
  51. Index uint8
  52. // Signature data
  53. Signature SignatureData
  54. }
  55. SignatureData [65]byte
  56. Observation struct {
  57. // Index of the observation in a Batch array
  58. Index uint8
  59. // Signed Observation data
  60. Observation *VAA
  61. }
  62. TransferPayloadHdr struct {
  63. Type uint8
  64. Amount *big.Int
  65. OriginAddress Address
  66. OriginChain ChainID
  67. TargetAddress Address
  68. TargetChain ChainID
  69. }
  70. // Attestation interface contains the methods common to all VAA types
  71. Attestation interface {
  72. encoding.BinaryMarshaler
  73. encoding.BinaryUnmarshaler
  74. serializeBody()
  75. signingBody() []byte
  76. SigningMsg() common.Hash
  77. VerifySignatures(addrs []common.Address) bool
  78. UniqueID() string
  79. HexDigest() string
  80. AddSignature(key *ecdsa.PrivateKey, index uint8)
  81. GetEmitterChain() ChainID
  82. }
  83. )
  84. const (
  85. ConsistencyLevelPublishImmediately = uint8(200)
  86. ConsistencyLevelSafe = uint8(201)
  87. )
  88. func (a Address) MarshalJSON() ([]byte, error) {
  89. return []byte(fmt.Sprintf(`"%s"`, a)), nil
  90. }
  91. // Standard marshal stores the Address like this: "[0,0,0,0,0,0,0,0,0,0,0,0,2,144,251,22,114,8,175,69,91,177,55,120,1,99,183,183,169,161,12,22]"
  92. // The above MarshalJSON stores it like this (66 bytes): ""0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16""
  93. func (a *Address) UnmarshalJSON(data []byte) error {
  94. addr, err := StringToAddress(strings.Trim(string(data), `"`))
  95. if err != nil {
  96. return err
  97. }
  98. *a = addr
  99. return nil
  100. }
  101. func (a Address) String() string {
  102. return hex.EncodeToString(a[:])
  103. }
  104. func (a Address) Bytes() []byte {
  105. return a[:]
  106. }
  107. func (a SignatureData) MarshalJSON() ([]byte, error) {
  108. return []byte(fmt.Sprintf(`"%s"`, a)), nil
  109. }
  110. func (a SignatureData) String() string {
  111. return hex.EncodeToString(a[:])
  112. }
  113. func (c ChainID) String() string {
  114. switch c {
  115. case ChainIDUnset:
  116. return "unset"
  117. case ChainIDSolana:
  118. return "solana"
  119. case ChainIDEthereum:
  120. return "ethereum"
  121. case ChainIDTerra:
  122. return "terra"
  123. case ChainIDBSC:
  124. return "bsc"
  125. case ChainIDPolygon:
  126. return "polygon"
  127. case ChainIDAvalanche:
  128. return "avalanche"
  129. case ChainIDOasis:
  130. return "oasis"
  131. case ChainIDAurora:
  132. return "aurora"
  133. case ChainIDFantom:
  134. return "fantom"
  135. case ChainIDAlgorand:
  136. return "algorand"
  137. case ChainIDNear:
  138. return "near"
  139. case ChainIDAptos:
  140. return "aptos"
  141. case ChainIDSui:
  142. return "sui"
  143. case ChainIDKarura:
  144. return "karura"
  145. case ChainIDAcala:
  146. return "acala"
  147. case ChainIDKlaytn:
  148. return "klaytn"
  149. case ChainIDCelo:
  150. return "celo"
  151. case ChainIDMoonbeam:
  152. return "moonbeam"
  153. case ChainIDTerra2:
  154. return "terra2"
  155. case ChainIDInjective:
  156. return "injective"
  157. case ChainIDOsmosis:
  158. return "osmosis"
  159. case ChainIDArbitrum:
  160. return "arbitrum"
  161. case ChainIDOptimism:
  162. return "optimism"
  163. case ChainIDGnosis:
  164. return "gnosis"
  165. case ChainIDPythNet:
  166. return "pythnet"
  167. case ChainIDWormchain:
  168. return "wormchain"
  169. case ChainIDXpla:
  170. return "xpla"
  171. case ChainIDBtc:
  172. return "btc"
  173. case ChainIDBase:
  174. return "base"
  175. case ChainIDSei:
  176. return "sei"
  177. case ChainIDRootstock:
  178. return "rootstock"
  179. case ChainIDScroll:
  180. return "scroll"
  181. case ChainIDMantle:
  182. return "mantle"
  183. case ChainIDCosmoshub:
  184. return "cosmoshub"
  185. case ChainIDEvmos:
  186. return "evmos"
  187. case ChainIDKujira:
  188. return "kujira"
  189. case ChainIDNeutron:
  190. return "neutron"
  191. case ChainIDCelestia:
  192. return "celestia"
  193. case ChainIDStargaze:
  194. return "stargaze"
  195. case ChainIDSeda:
  196. return "seda"
  197. case ChainIDDymension:
  198. return "dymension"
  199. case ChainIDSepolia:
  200. return "sepolia"
  201. case ChainIDArbitrumSepolia:
  202. return "arbitrum_sepolia"
  203. case ChainIDBaseSepolia:
  204. return "base_sepolia"
  205. case ChainIDOptimismSepolia:
  206. return "optimism_sepolia"
  207. case ChainIDHolesky:
  208. return "holesky"
  209. case ChainIDPolygonSepolia:
  210. return "polygon_sepolia"
  211. default:
  212. return fmt.Sprintf("unknown chain ID: %d", c)
  213. }
  214. }
  215. func ChainIDFromString(s string) (ChainID, error) {
  216. s = strings.ToLower(s)
  217. switch s {
  218. case "solana":
  219. return ChainIDSolana, nil
  220. case "ethereum":
  221. return ChainIDEthereum, nil
  222. case "terra":
  223. return ChainIDTerra, nil
  224. case "bsc":
  225. return ChainIDBSC, nil
  226. case "polygon":
  227. return ChainIDPolygon, nil
  228. case "avalanche":
  229. return ChainIDAvalanche, nil
  230. case "oasis":
  231. return ChainIDOasis, nil
  232. case "aurora":
  233. return ChainIDAurora, nil
  234. case "fantom":
  235. return ChainIDFantom, nil
  236. case "algorand":
  237. return ChainIDAlgorand, nil
  238. case "near":
  239. return ChainIDNear, nil
  240. case "sui":
  241. return ChainIDSui, nil
  242. case "aptos":
  243. return ChainIDAptos, nil
  244. case "karura":
  245. return ChainIDKarura, nil
  246. case "acala":
  247. return ChainIDAcala, nil
  248. case "klaytn":
  249. return ChainIDKlaytn, nil
  250. case "celo":
  251. return ChainIDCelo, nil
  252. case "moonbeam":
  253. return ChainIDMoonbeam, nil
  254. case "terra2":
  255. return ChainIDTerra2, nil
  256. case "injective":
  257. return ChainIDInjective, nil
  258. case "osmosis":
  259. return ChainIDOsmosis, nil
  260. case "arbitrum":
  261. return ChainIDArbitrum, nil
  262. case "optimism":
  263. return ChainIDOptimism, nil
  264. case "gnosis":
  265. return ChainIDGnosis, nil
  266. case "pythnet":
  267. return ChainIDPythNet, nil
  268. case "wormchain":
  269. return ChainIDWormchain, nil
  270. case "xpla":
  271. return ChainIDXpla, nil
  272. case "btc":
  273. return ChainIDBtc, nil
  274. case "base":
  275. return ChainIDBase, nil
  276. case "sei":
  277. return ChainIDSei, nil
  278. case "rootstock":
  279. return ChainIDRootstock, nil
  280. case "scroll":
  281. return ChainIDScroll, nil
  282. case "mantle":
  283. return ChainIDMantle, nil
  284. case "cosmoshub":
  285. return ChainIDCosmoshub, nil
  286. case "evmos":
  287. return ChainIDEvmos, nil
  288. case "kujira":
  289. return ChainIDKujira, nil
  290. case "neutron":
  291. return ChainIDNeutron, nil
  292. case "celestia":
  293. return ChainIDCelestia, nil
  294. case "stargaze":
  295. return ChainIDStargaze, nil
  296. case "seda":
  297. return ChainIDSeda, nil
  298. case "dymension":
  299. return ChainIDDymension, nil
  300. case "sepolia":
  301. return ChainIDSepolia, nil
  302. case "arbitrum_sepolia":
  303. return ChainIDArbitrumSepolia, nil
  304. case "base_sepolia":
  305. return ChainIDBaseSepolia, nil
  306. case "optimism_sepolia":
  307. return ChainIDOptimismSepolia, nil
  308. case "holesky":
  309. return ChainIDHolesky, nil
  310. case "polygon_sepolia":
  311. return ChainIDPolygonSepolia, nil
  312. default:
  313. return ChainIDUnset, fmt.Errorf("unknown chain ID: %s", s)
  314. }
  315. }
  316. func GetAllNetworkIDs() []ChainID {
  317. return []ChainID{
  318. ChainIDSolana,
  319. ChainIDEthereum,
  320. ChainIDTerra,
  321. ChainIDBSC,
  322. ChainIDPolygon,
  323. ChainIDAvalanche,
  324. ChainIDOasis,
  325. ChainIDAlgorand,
  326. ChainIDAurora,
  327. ChainIDFantom,
  328. ChainIDKarura,
  329. ChainIDAcala,
  330. ChainIDKlaytn,
  331. ChainIDCelo,
  332. ChainIDNear,
  333. ChainIDMoonbeam,
  334. ChainIDTerra2,
  335. ChainIDInjective,
  336. ChainIDOsmosis,
  337. ChainIDSui,
  338. ChainIDAptos,
  339. ChainIDArbitrum,
  340. ChainIDOptimism,
  341. ChainIDGnosis,
  342. ChainIDPythNet,
  343. ChainIDXpla,
  344. ChainIDBtc,
  345. ChainIDBase,
  346. ChainIDSei,
  347. ChainIDRootstock,
  348. ChainIDScroll,
  349. ChainIDMantle,
  350. ChainIDWormchain,
  351. ChainIDCosmoshub,
  352. ChainIDEvmos,
  353. ChainIDKujira,
  354. ChainIDNeutron,
  355. ChainIDCelestia,
  356. ChainIDStargaze,
  357. ChainIDSeda,
  358. ChainIDDymension,
  359. ChainIDSepolia,
  360. ChainIDArbitrumSepolia,
  361. ChainIDBaseSepolia,
  362. ChainIDOptimismSepolia,
  363. ChainIDHolesky,
  364. ChainIDPolygonSepolia,
  365. }
  366. }
  367. const (
  368. ChainIDUnset ChainID = 0
  369. // ChainIDSolana is the ChainID of Solana
  370. ChainIDSolana ChainID = 1
  371. // ChainIDEthereum is the ChainID of Ethereum
  372. ChainIDEthereum ChainID = 2
  373. // ChainIDTerra is the ChainID of Terra
  374. ChainIDTerra ChainID = 3
  375. // ChainIDBSC is the ChainID of Binance Smart Chain
  376. ChainIDBSC ChainID = 4
  377. // ChainIDPolygon is the ChainID of Polygon
  378. ChainIDPolygon ChainID = 5
  379. // ChainIDAvalanche is the ChainID of Avalanche
  380. ChainIDAvalanche ChainID = 6
  381. // ChainIDOasis is the ChainID of Oasis
  382. ChainIDOasis ChainID = 7
  383. // ChainIDAlgorand is the ChainID of Algorand
  384. ChainIDAlgorand ChainID = 8
  385. // ChainIDAurora is the ChainID of Aurora
  386. ChainIDAurora ChainID = 9
  387. // ChainIDFantom is the ChainID of Fantom
  388. ChainIDFantom ChainID = 10
  389. // ChainIDKarura is the ChainID of Karura
  390. ChainIDKarura ChainID = 11
  391. // ChainIDAcala is the ChainID of Acala
  392. ChainIDAcala ChainID = 12
  393. // ChainIDKlaytn is the ChainID of Klaytn
  394. ChainIDKlaytn ChainID = 13
  395. // ChainIDCelo is the ChainID of Celo
  396. ChainIDCelo ChainID = 14
  397. // ChainIDNear is the ChainID of Near
  398. ChainIDNear ChainID = 15
  399. // ChainIDMoonbeam is the ChainID of Moonbeam
  400. ChainIDMoonbeam ChainID = 16
  401. // OBSOLETE: ChainIDNeon ChainID = 17
  402. // ChainIDTerra2 is the ChainID of Terra 2
  403. ChainIDTerra2 ChainID = 18
  404. // ChainIDInjective is the ChainID of Injective
  405. ChainIDInjective ChainID = 19
  406. // ChainIDOsmosis is the ChainID of Osmosis
  407. ChainIDOsmosis ChainID = 20
  408. // ChainIDSui is the ChainID of Sui
  409. ChainIDSui ChainID = 21
  410. // ChainIDAptos is the ChainID of Aptos
  411. ChainIDAptos ChainID = 22
  412. // ChainIDArbitrum is the ChainID of Arbitrum
  413. ChainIDArbitrum ChainID = 23
  414. // ChainIDOptimism is the ChainID of Optimism
  415. ChainIDOptimism ChainID = 24
  416. // ChainIDGnosis is the ChainID of Gnosis
  417. ChainIDGnosis ChainID = 25
  418. // ChainIDPythNet is the ChainID of PythNet
  419. ChainIDPythNet ChainID = 26
  420. // ChainIDXpla is the ChainID of Xpla
  421. ChainIDXpla ChainID = 28
  422. //ChainIDBtc is the ChainID of Bitcoin
  423. ChainIDBtc ChainID = 29
  424. // ChainIDBase is the ChainID of Base
  425. ChainIDBase ChainID = 30
  426. // ChainIDSei is the ChainID of Sei
  427. ChainIDSei ChainID = 32
  428. // ChainIDRootstock is the ChainID of Rootstock
  429. ChainIDRootstock ChainID = 33
  430. // ChainIDScroll is the ChainID of Scroll
  431. ChainIDScroll ChainID = 34
  432. // ChainIDMantle is the ChainID of Mantle
  433. ChainIDMantle ChainID = 35
  434. //ChainIDWormchain is the ChainID of Wormchain
  435. ChainIDWormchain ChainID = 3104
  436. // ChainIDCosmoshub is the ChainID of Cosmoshub
  437. ChainIDCosmoshub ChainID = 4000
  438. // ChainIDEvmos is the ChainID of Evmos
  439. ChainIDEvmos ChainID = 4001
  440. // ChainIDKujira is the ChainID of Kujira
  441. ChainIDKujira ChainID = 4002
  442. // ChainIDNeutron is the ChainID of Neutron
  443. ChainIDNeutron ChainID = 4003
  444. // ChainIDCelestia is the ChainID of Celestia
  445. ChainIDCelestia ChainID = 4004
  446. // ChainIDStargaze is the ChainID of Stargaze
  447. ChainIDStargaze ChainID = 4005
  448. // ChainIDSeda is the ChainID of Seda
  449. ChainIDSeda ChainID = 4006
  450. // ChainIDSeda is the ChainID of Dymension
  451. ChainIDDymension ChainID = 4007
  452. // ChainIDSepolia is the ChainID of Sepolia
  453. ChainIDSepolia ChainID = 10002
  454. // ChainIDArbitrumSepolia is the ChainID of Arbitrum on Sepolia
  455. ChainIDArbitrumSepolia ChainID = 10003
  456. // ChainIDBaseSepolia is the ChainID of Base on Sepolia
  457. ChainIDBaseSepolia ChainID = 10004
  458. // ChainIDOptimismSepolia is the ChainID of Optimism on Sepolia
  459. ChainIDOptimismSepolia ChainID = 10005
  460. // ChainIDHolesky is the ChainID of Holesky
  461. ChainIDHolesky ChainID = 10006
  462. // ChainIDPolygonSepolia is the ChainID of Polygon on Sepolia
  463. ChainIDPolygonSepolia ChainID = 10007
  464. // Minimum VAA size is derrived from the following assumptions:
  465. // HEADER
  466. // - Supported VAA Version (1 byte)
  467. // - Guardian Set Index (4 bytes)
  468. // - Length of Signatures (1 byte) <== assume no signatures
  469. // - Actual Signatures (0 bytes)
  470. // BODY
  471. // - timestamp (4 bytes)
  472. // - nonce (4 bytes)
  473. // - emitter chain (2 bytes)
  474. // - emitter address (32 bytes)
  475. // - sequence (8 bytes)
  476. // - consistency level (1 byte)
  477. // - payload (0 bytes)
  478. // BATCH
  479. // - Length of Observation Hashes (1 byte) <== minimum one
  480. // - Observation Hash (32 bytes)
  481. // - Length of Observations (1 byte) <== minimum one
  482. // - Observation Index (1 byte)
  483. // - Observation Length (1 byte)
  484. // - Observation, aka BODY, aka Headless (51 bytes)
  485. // From Above:
  486. // HEADER: 1 + 4 + 1 + 0 = 6
  487. // BODY: 4 + 4 + 2 + 32 + 8 + 1 + 0 = 51
  488. // BATCH: 1 + 32 + 1 + 1 + 1 + 51 = 88
  489. //
  490. // More details here: https://docs.wormholenetwork.com/wormhole/vaas
  491. minHeadlessVAALength = 51 // HEADER
  492. minVAALength = 57 // HEADER + BODY
  493. SupportedVAAVersion = 0x01
  494. )
  495. // UnmarshalBody deserializes the binary representation of a VAA's "BODY" properties
  496. // The BODY fields are common among multiple types of VAA - v1, v2, etc
  497. func UnmarshalBody(data []byte, reader *bytes.Reader, v *VAA) (*VAA, error) {
  498. unixSeconds := uint32(0)
  499. if err := binary.Read(reader, binary.BigEndian, &unixSeconds); err != nil {
  500. return nil, fmt.Errorf("failed to read timestamp: %w", err)
  501. }
  502. v.Timestamp = time.Unix(int64(unixSeconds), 0)
  503. if err := binary.Read(reader, binary.BigEndian, &v.Nonce); err != nil {
  504. return nil, fmt.Errorf("failed to read nonce: %w", err)
  505. }
  506. if err := binary.Read(reader, binary.BigEndian, &v.EmitterChain); err != nil {
  507. return nil, fmt.Errorf("failed to read emitter chain: %w", err)
  508. }
  509. emitterAddress := Address{}
  510. if n, err := reader.Read(emitterAddress[:]); err != nil || n != 32 {
  511. return nil, fmt.Errorf("failed to read emitter address [%d]: %w", n, err)
  512. }
  513. v.EmitterAddress = emitterAddress
  514. if err := binary.Read(reader, binary.BigEndian, &v.Sequence); err != nil {
  515. return nil, fmt.Errorf("failed to read sequence: %w", err)
  516. }
  517. if err := binary.Read(reader, binary.BigEndian, &v.ConsistencyLevel); err != nil {
  518. return nil, fmt.Errorf("failed to read commitment: %w", err)
  519. }
  520. // Make sure to only read the payload if the VAA has one; VAAs may have a 0 length payload
  521. if reader.Len() != 0 {
  522. payload := make([]byte, reader.Len())
  523. n, err := reader.Read(payload)
  524. if err != nil {
  525. return nil, fmt.Errorf("failed to read payload [%d]: %w", n, err)
  526. }
  527. v.Payload = payload[:n]
  528. } else {
  529. v.Payload = []byte{}
  530. }
  531. return v, nil
  532. }
  533. // Unmarshal deserializes the binary representation of a VAA
  534. func Unmarshal(data []byte) (*VAA, error) {
  535. if len(data) < minVAALength {
  536. return nil, fmt.Errorf("VAA is too short")
  537. }
  538. v := &VAA{}
  539. v.Version = data[0]
  540. if v.Version != SupportedVAAVersion {
  541. return nil, fmt.Errorf("unsupported VAA version: %d", v.Version)
  542. }
  543. reader := bytes.NewReader(data[1:])
  544. if err := binary.Read(reader, binary.BigEndian, &v.GuardianSetIndex); err != nil {
  545. return nil, fmt.Errorf("failed to read guardian set index: %w", err)
  546. }
  547. lenSignatures, er := reader.ReadByte()
  548. if er != nil {
  549. return nil, fmt.Errorf("failed to read signature length")
  550. }
  551. v.Signatures = make([]*Signature, lenSignatures)
  552. for i := 0; i < int(lenSignatures); i++ {
  553. index, err := reader.ReadByte()
  554. if err != nil {
  555. return nil, fmt.Errorf("failed to read validator index [%d]", i)
  556. }
  557. signature := [65]byte{}
  558. if n, err := reader.Read(signature[:]); err != nil || n != 65 {
  559. return nil, fmt.Errorf("failed to read signature [%d]: %w", i, err)
  560. }
  561. v.Signatures[i] = &Signature{
  562. Index: index,
  563. Signature: signature,
  564. }
  565. }
  566. return UnmarshalBody(data, reader, v)
  567. }
  568. // signingBody returns the binary representation of the data that is relevant for signing and verifying the VAA
  569. func (v *VAA) signingBody() []byte {
  570. return v.serializeBody()
  571. }
  572. func doubleKeccak(bz []byte) common.Hash {
  573. // In order to save space in the solana signature verification instruction, we hash twice so we only need to pass in
  574. // the first hash (32 bytes) vs the full body data.
  575. return crypto.Keccak256Hash(crypto.Keccak256Hash(bz).Bytes())
  576. }
  577. // This is a temporary method to produce a vaa signing digest on raw bytes.
  578. // It is error prone and we should use `v.SigningDigest()` instead.
  579. // whenever possible.
  580. // This will be removed in a subsequent release.
  581. func DeprecatedSigningDigest(bz []byte) common.Hash {
  582. return doubleKeccak(bz)
  583. }
  584. // MessageSigningDigest returns the hash of the data prepended with it's signing prefix.
  585. // This is intending to be used for signing messages of different types from VAA's.
  586. // The message prefix helps protect from message collisions.
  587. func MessageSigningDigest(prefix []byte, data []byte) (common.Hash, error) {
  588. if len(prefix) < 32 {
  589. // Prefixes must be at least 32 bytes
  590. // https://github.com/wormhole-foundation/wormhole/blob/main/whitepapers/0009_guardian_key.md
  591. return common.Hash([32]byte{}), errors.New("prefix must be at least 32 bytes")
  592. }
  593. return crypto.Keccak256Hash(prefix[:], data), nil
  594. }
  595. // SigningDigest returns the hash of the vaa hash to be signed directly.
  596. // This is used for signature generation and verification
  597. func (v *VAA) SigningDigest() common.Hash {
  598. return doubleKeccak(v.signingBody())
  599. }
  600. // Verify Signature checks that the provided address matches the address that created the signature for the provided digest
  601. // Digest should be the output of SigningMsg(data).Bytes()
  602. // Should not be public as other message types should be verified using a message prefix.
  603. func verifySignature(vaa_digest []byte, signature *Signature, address common.Address) bool {
  604. // retrieve the address that signed the data
  605. pubKey, err := crypto.Ecrecover(vaa_digest, signature.Signature[:])
  606. if err != nil {
  607. return false
  608. }
  609. addr := common.BytesToAddress(crypto.Keccak256(pubKey[1:])[12:])
  610. // check that the recovered address equals the provided address
  611. return addr == address
  612. }
  613. // Digest should be the output of SigningMsg(data).Bytes()
  614. // Should not be public as other message types should be verified using a message prefix.
  615. func verifySignatures(vaa_digest []byte, signatures []*Signature, addresses []common.Address) bool {
  616. if len(addresses) < len(signatures) {
  617. return false
  618. }
  619. last_index := -1
  620. signing_addresses := []common.Address{}
  621. for _, sig := range signatures {
  622. if int(sig.Index) >= len(addresses) {
  623. return false
  624. }
  625. // Ensure increasing indexes
  626. if int(sig.Index) <= last_index {
  627. return false
  628. }
  629. last_index = int(sig.Index)
  630. // verify this signature
  631. addr := addresses[sig.Index]
  632. ok := verifySignature(vaa_digest, sig, addr)
  633. if !ok {
  634. return false
  635. }
  636. // Ensure we never see the same signer twice
  637. for _, signing_address := range signing_addresses {
  638. if signing_address == addr {
  639. return false
  640. }
  641. }
  642. signing_addresses = append(signing_addresses, addr)
  643. }
  644. return true
  645. }
  646. // Operating on bytes directly is error prone. We should use `vaa.VerifyingSignatures()` whenever possible.
  647. // This function will be removed in a subsequent release.
  648. func DeprecatedVerifySignatures(vaaBody []byte, signatures []*Signature, addresses []common.Address) bool {
  649. vaaDigest := doubleKeccak(vaaBody)
  650. return verifySignatures(vaaDigest[:], signatures, addresses)
  651. }
  652. func VerifyMessageSignature(prefix []byte, messageBody []byte, signatures *Signature, addresses common.Address) bool {
  653. if len(prefix) < 32 {
  654. return false
  655. }
  656. msgDigest, err := MessageSigningDigest(prefix, messageBody)
  657. if err != nil {
  658. return false
  659. }
  660. return verifySignature(msgDigest[:], signatures, addresses)
  661. }
  662. // VerifySignatures verifies the signature of the VAA given the signer addresses.
  663. // Returns true if the signatures were verified successfully.
  664. func (v *VAA) VerifySignatures(addresses []common.Address) bool {
  665. return verifySignatures(v.SigningDigest().Bytes(), v.Signatures, addresses)
  666. }
  667. // Verify is a function on the VAA that takes a complete set of guardian keys as input and attempts certain checks with respect to this guardian.
  668. // Verify will return nil if the VAA passes checks. Otherwise, Verify will return an error containing the text of the first check to fail.
  669. // NOTE: Verify will not work correctly if a subset of the guardian set keys is passed in. The complete guardian set must be passed in.
  670. // Verify does the following checks:
  671. // - If the guardian does not have or know its own guardian set keys, then the VAA cannot be verified.
  672. // - Quorum is calculated on the guardian set passed in and checks if the VAA has enough signatures.
  673. // - The signatures in the VAA is verified against the guardian set keys.
  674. func (v *VAA) Verify(addresses []common.Address) error {
  675. if addresses == nil {
  676. return errors.New("no addresses were provided")
  677. }
  678. // Check if VAA doesn't have any signatures
  679. if len(v.Signatures) == 0 {
  680. return errors.New("VAA was not signed")
  681. }
  682. // Verify VAA has enough signatures for quorum
  683. quorum := CalculateQuorum(len(addresses))
  684. if len(v.Signatures) < quorum {
  685. return errors.New("VAA did not have a quorum")
  686. }
  687. // Verify VAA signatures to prevent a DoS attack on our local store.
  688. if !v.VerifySignatures(addresses) {
  689. return errors.New("VAA had bad signatures")
  690. }
  691. return nil
  692. }
  693. // Marshal returns the binary representation of the VAA
  694. func (v *VAA) Marshal() ([]byte, error) {
  695. buf := new(bytes.Buffer)
  696. MustWrite(buf, binary.BigEndian, v.Version)
  697. MustWrite(buf, binary.BigEndian, v.GuardianSetIndex)
  698. // Write signatures
  699. MustWrite(buf, binary.BigEndian, uint8(len(v.Signatures)))
  700. for _, sig := range v.Signatures {
  701. MustWrite(buf, binary.BigEndian, sig.Index)
  702. buf.Write(sig.Signature[:])
  703. }
  704. // Write Body
  705. buf.Write(v.serializeBody())
  706. return buf.Bytes(), nil
  707. }
  708. // implement encoding.BinaryMarshaler interface for the VAA struct
  709. func (v VAA) MarshalBinary() ([]byte, error) {
  710. return v.Marshal()
  711. }
  712. // implement encoding.BinaryUnmarshaler interface for the VAA struct
  713. func (v *VAA) UnmarshalBinary(data []byte) error {
  714. vaa, err := Unmarshal(data)
  715. if err != nil {
  716. return err
  717. }
  718. // derefernce the stuct created by Unmarshal, and assign it to the method's context
  719. *v = *vaa
  720. return nil
  721. }
  722. // MessageID returns a human-readable emitter_chain/emitter_address/sequence tuple.
  723. func (v *VAA) MessageID() string {
  724. return fmt.Sprintf("%d/%s/%d", v.EmitterChain, v.EmitterAddress, v.Sequence)
  725. }
  726. // UniqueID normalizes the ID of the VAA (any type) for the Attestation interface
  727. // UniqueID returns the MessageID that uniquely identifies the Attestation
  728. func (v *VAA) UniqueID() string {
  729. return v.MessageID()
  730. }
  731. // HexDigest returns the hex-encoded digest.
  732. func (v *VAA) HexDigest() string {
  733. return hex.EncodeToString(v.SigningDigest().Bytes())
  734. }
  735. /*
  736. SECURITY: Do not change this code! Changing it could result in two different hashes for
  737. the same observation. But xDapps rely on the hash of an observation for replay protection.
  738. */
  739. func (v *VAA) serializeBody() []byte {
  740. buf := new(bytes.Buffer)
  741. MustWrite(buf, binary.BigEndian, uint32(v.Timestamp.Unix()))
  742. MustWrite(buf, binary.BigEndian, v.Nonce)
  743. MustWrite(buf, binary.BigEndian, v.EmitterChain)
  744. buf.Write(v.EmitterAddress[:])
  745. MustWrite(buf, binary.BigEndian, v.Sequence)
  746. MustWrite(buf, binary.BigEndian, v.ConsistencyLevel)
  747. buf.Write(v.Payload)
  748. return buf.Bytes()
  749. }
  750. func (v *VAA) AddSignature(key *ecdsa.PrivateKey, index uint8) {
  751. sig, err := crypto.Sign(v.SigningDigest().Bytes(), key)
  752. if err != nil {
  753. panic(err)
  754. }
  755. sigData := [65]byte{}
  756. copy(sigData[:], sig)
  757. v.Signatures = append(v.Signatures, &Signature{
  758. Index: index,
  759. Signature: sigData,
  760. })
  761. }
  762. // NOTE: This function assumes that the caller has verified that the VAA is from the token bridge.
  763. func IsTransfer(payload []byte) bool {
  764. return (len(payload) > 0) && ((payload[0] == 1) || (payload[0] == 3))
  765. }
  766. func DecodeTransferPayloadHdr(payload []byte) (*TransferPayloadHdr, error) {
  767. if !IsTransfer(payload) {
  768. return nil, fmt.Errorf("unsupported payload type")
  769. }
  770. if len(payload) < 101 {
  771. return nil, fmt.Errorf("buffer too short")
  772. }
  773. p := &TransferPayloadHdr{}
  774. // Payload type: payload[0]
  775. p.Type = uint8(payload[0])
  776. // Amount: payload[1] for 32
  777. p.Amount = new(big.Int)
  778. p.Amount.SetBytes(payload[1:33])
  779. reader := bytes.NewReader(payload[33:])
  780. // Origin address: payload[33] for 32
  781. err := binary.Read(reader, binary.BigEndian, &p.OriginAddress)
  782. if err != nil {
  783. return nil, err
  784. }
  785. // Origin chain ID: payload[65] for 2
  786. err = binary.Read(reader, binary.BigEndian, &p.OriginChain)
  787. if err != nil {
  788. return nil, err
  789. }
  790. // Target address: payload[67] for 32
  791. err = binary.Read(reader, binary.BigEndian, &p.TargetAddress)
  792. if err != nil {
  793. return nil, err
  794. }
  795. // Target chain ID: payload[99] for 2
  796. err = binary.Read(reader, binary.BigEndian, &p.TargetChain)
  797. if err != nil {
  798. return nil, err
  799. }
  800. return p, nil
  801. }
  802. // GetEmitterChain implements the processor.Observation interface for *VAA.
  803. func (v *VAA) GetEmitterChain() ChainID {
  804. return v.EmitterChain
  805. }
  806. // MustWrite calls binary.Write and panics on errors
  807. func MustWrite(w io.Writer, order binary.ByteOrder, data interface{}) {
  808. if err := binary.Write(w, order, data); err != nil {
  809. panic(fmt.Errorf("failed to write binary data: %v", data).Error())
  810. }
  811. }
  812. // StringToAddress converts a hex-encoded address into a vaa.Address
  813. func StringToAddress(value string) (Address, error) {
  814. var address Address
  815. // Make sure we have enough to decode
  816. if len(value) < 2 {
  817. return address, fmt.Errorf("value must be at least 1 byte")
  818. }
  819. // Trim any preceding "0x" to the address
  820. value = strings.TrimPrefix(value, "0x")
  821. // Decode the string from hex to binary
  822. res, err := hex.DecodeString(value)
  823. if err != nil {
  824. return address, err
  825. }
  826. // Make sure we don't have too many bytes
  827. if len(res) > 32 {
  828. return address, fmt.Errorf("value must be no more than 32 bytes")
  829. }
  830. copy(address[32-len(res):], res)
  831. return address, nil
  832. }
  833. func BytesToAddress(b []byte) (Address, error) {
  834. var address Address
  835. if len(b) > 32 {
  836. return address, fmt.Errorf("value must be no more than 32 bytes")
  837. }
  838. copy(address[32-len(b):], b)
  839. return address, nil
  840. }
  841. // StringToHash converts a hex-encoded string into a common.Hash
  842. func StringToHash(value string) (common.Hash, error) {
  843. var tx common.Hash
  844. // Make sure we have enough to decode
  845. if len(value) < 2 {
  846. return tx, fmt.Errorf("value must be at least 1 byte")
  847. }
  848. // Trim any preceding "0x" to the address
  849. value = strings.TrimPrefix(value, "0x")
  850. res, err := hex.DecodeString(value)
  851. if err != nil {
  852. return tx, err
  853. }
  854. tx = common.BytesToHash(res)
  855. return tx, nil
  856. }
  857. func BytesToHash(b []byte) (common.Hash, error) {
  858. var hash common.Hash
  859. if len(b) > 32 {
  860. return hash, fmt.Errorf("value must be no more than 32 bytes")
  861. }
  862. hash = common.BytesToHash(b)
  863. return hash, nil
  864. }