structs_test.go 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package vaa
  2. import (
  3. "crypto/ecdsa"
  4. "crypto/elliptic"
  5. "crypto/rand"
  6. "encoding/hex"
  7. "github.com/ethereum/go-ethereum/common"
  8. "github.com/ethereum/go-ethereum/crypto"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. "testing"
  12. "time"
  13. )
  14. func getVAA() *VAA {
  15. var payload = []byte{97, 97, 97, 97, 97, 97}
  16. var governanceEmitter = Address{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}
  17. vaa := &VAA{
  18. Version: uint8(1),
  19. GuardianSetIndex: uint32(1),
  20. Signatures: nil,
  21. Timestamp: time.Unix(0, 0),
  22. Nonce: uint32(1),
  23. Sequence: uint64(1),
  24. ConsistencyLevel: uint8(32),
  25. EmitterChain: ChainIDSolana,
  26. EmitterAddress: governanceEmitter,
  27. Payload: payload,
  28. }
  29. return vaa
  30. }
  31. func TestChainIDFromString(t *testing.T) {
  32. type test struct {
  33. input string
  34. output ChainID
  35. }
  36. // Positive Test Cases
  37. p_tests := []test{
  38. {input: "solana", output: ChainIDSolana},
  39. {input: "ethereum", output: ChainIDEthereum},
  40. {input: "terra", output: ChainIDTerra},
  41. {input: "bsc", output: ChainIDBSC},
  42. {input: "polygon", output: ChainIDPolygon},
  43. {input: "avalanche", output: ChainIDAvalanche},
  44. {input: "oasis", output: ChainIDOasis},
  45. {input: "algorand", output: ChainIDAlgorand},
  46. {input: "aurora", output: ChainIDAurora},
  47. {input: "fantom", output: ChainIDFantom},
  48. {input: "karura", output: ChainIDKarura},
  49. {input: "acala", output: ChainIDAcala},
  50. {input: "ethereum-ropsten", output: ChainIDEthereumRopsten},
  51. {input: "Solana", output: ChainIDSolana},
  52. {input: "Ethereum", output: ChainIDEthereum},
  53. {input: "Terra", output: ChainIDTerra},
  54. {input: "Bsc", output: ChainIDBSC},
  55. {input: "Polygon", output: ChainIDPolygon},
  56. {input: "Avalanche", output: ChainIDAvalanche},
  57. {input: "Oasis", output: ChainIDOasis},
  58. {input: "Algorand", output: ChainIDAlgorand},
  59. {input: "Aurora", output: ChainIDAurora},
  60. {input: "Fantom", output: ChainIDFantom},
  61. {input: "Karura", output: ChainIDKarura},
  62. {input: "Acala", output: ChainIDAcala},
  63. {input: "Ethereum-ropsten", output: ChainIDEthereumRopsten},
  64. }
  65. // Negative Test Cases
  66. n_tests := []test{
  67. {input: "Unknown", output: ChainIDUnset},
  68. }
  69. for _, tc := range p_tests {
  70. t.Run(tc.input, func(t *testing.T) {
  71. chainId, err := ChainIDFromString(tc.input)
  72. assert.Equal(t, tc.output, chainId)
  73. assert.Nil(t, err)
  74. })
  75. }
  76. for _, tc := range n_tests {
  77. t.Run(tc.input, func(t *testing.T) {
  78. chainId, err := ChainIDFromString(tc.input)
  79. assert.Equal(t, tc.output, chainId)
  80. assert.NotNil(t, err)
  81. })
  82. }
  83. }
  84. func TestAddress_MarshalJSON(t *testing.T) {
  85. addr := Address{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}
  86. expected := "223030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303422"
  87. marshalJsonAddress, err := addr.MarshalJSON()
  88. assert.Equal(t, hex.EncodeToString(marshalJsonAddress), expected)
  89. assert.Nil(t, err)
  90. }
  91. func TestAddress_String(t *testing.T) {
  92. addr := Address{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}
  93. expected := "0000000000000000000000000000000000000000000000000000000000000004"
  94. assert.Equal(t, addr.String(), expected)
  95. }
  96. func TestAddress_Bytes(t *testing.T) {
  97. addr := Address{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}
  98. expected := []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4}
  99. assert.Equal(t, addr.Bytes(), expected)
  100. }
  101. func TestSignatureData_MarshalJSON(t *testing.T) {
  102. sigData := SignatureData{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0}
  103. marshalJsonSigData, err := sigData.MarshalJSON()
  104. require.Nil(t, err)
  105. expected := "223030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303034303022"
  106. assert.Equal(t, hex.EncodeToString(marshalJsonSigData), expected)
  107. }
  108. func TestSignature_DataString(t *testing.T) {
  109. sigData := SignatureData{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0}
  110. expected := "0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000400"
  111. assert.Equal(t, sigData.String(), expected)
  112. }
  113. func TestChainId_String(t *testing.T) {
  114. type test struct {
  115. input ChainID
  116. output string
  117. }
  118. tests := []test{
  119. {input: 0, output: "unset"},
  120. {input: 1, output: "solana"},
  121. {input: 2, output: "ethereum"},
  122. {input: 3, output: "terra"},
  123. {input: 4, output: "bsc"},
  124. {input: 5, output: "polygon"},
  125. {input: 6, output: "avalanche"},
  126. {input: 7, output: "oasis"},
  127. {input: 8, output: "algorand"},
  128. {input: 9, output: "aurora"},
  129. {input: 10, output: "fantom"},
  130. {input: 11, output: "karura"},
  131. {input: 12, output: "acala"},
  132. {input: 10001, output: "ethereum-ropsten"},
  133. }
  134. for _, tc := range tests {
  135. t.Run(tc.output, func(t *testing.T) {
  136. assert.Equal(t, ChainID(tc.input).String(), tc.output)
  137. })
  138. }
  139. }
  140. func TestAddSignature(t *testing.T) {
  141. vaa := getVAA()
  142. // Generate a random private key to sign with
  143. key, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  144. assert.Nil(t, vaa.Signatures)
  145. // Add a signature and make sure it's added
  146. vaa.AddSignature(key, 0)
  147. assert.Equal(t, len(vaa.Signatures), 1)
  148. }
  149. func TestSerializeBody(t *testing.T) {
  150. vaa := getVAA()
  151. expected := []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61}
  152. assert.Equal(t, vaa.serializeBody(), expected)
  153. }
  154. func TestSigningBody(t *testing.T) {
  155. vaa := getVAA()
  156. expected := []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x20, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61}
  157. assert.Equal(t, vaa.signingBody(), expected)
  158. }
  159. func TestSigningMsg(t *testing.T) {
  160. vaa := getVAA()
  161. expected := common.HexToHash("4fae136bb1fd782fe1b5180ba735cdc83bcece3f9b7fd0e5e35300a61c8acd8f")
  162. assert.Equal(t, vaa.SigningMsg(), expected)
  163. }
  164. func TestMessageID(t *testing.T) {
  165. vaa := getVAA()
  166. expected := "1/0000000000000000000000000000000000000000000000000000000000000004/1"
  167. assert.Equal(t, vaa.MessageID(), expected)
  168. }
  169. func TestHexDigest(t *testing.T) {
  170. vaa := getVAA()
  171. expected := "4fae136bb1fd782fe1b5180ba735cdc83bcece3f9b7fd0e5e35300a61c8acd8f"
  172. assert.Equal(t, vaa.HexDigest(), expected)
  173. }
  174. func TestVerifySignatures(t *testing.T) {
  175. vaa := getVAA()
  176. // Generate a random private key to sign with
  177. privKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  178. assert.Nil(t, vaa.Signatures)
  179. // Add a signature and make sure it's added
  180. vaa.AddSignature(privKey, 0)
  181. assert.Equal(t, len(vaa.Signatures), 1)
  182. // Generate a public key to compare to from our private key
  183. h := vaa.SigningMsg()
  184. pubKey, err := crypto.Ecrecover(h.Bytes(), vaa.Signatures[0].Signature[:])
  185. assert.Nil(t, err)
  186. assert.NotNil(t, pubKey)
  187. // Translate that public key back to an address
  188. addr := common.BytesToAddress(crypto.Keccak256(pubKey[1:])[12:])
  189. // Make sure that it verifies
  190. assert.True(t, vaa.VerifySignatures([]common.Address{addr}))
  191. }
  192. func TestStringToAddress(t *testing.T) {
  193. expected := Address{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4}
  194. addr, err := StringToAddress("0000000000000000000000000000000000000000000000000000000000000004")
  195. assert.Nil(t, err)
  196. assert.Equal(t, expected, addr)
  197. }