diff --git a/Tiltfile b/Tiltfile index 76cfaf6471..b8f7cd3c22 100644 --- a/Tiltfile +++ b/Tiltfile @@ -660,12 +660,6 @@ if ci_tests: trigger_mode = trigger_mode, resource_deps = [], # uses devnet-consts.json, but wormchain/contracts/tools/test_ntt_accountant.sh handles waiting for guardian, not having deps gets the build earlier ) - k8s_resource( - "query-ci-tests", - labels = ["ci"], - trigger_mode = trigger_mode, - resource_deps = [], # node/hack/query/test/test_query.sh handles waiting for guardian, not having deps gets the build earlier - ) k8s_resource( "query-sdk-ci-tests", labels = ["ci"], diff --git a/devnet/node.yaml b/devnet/node.yaml index a2bb2bf924..b6407bc33a 100644 --- a/devnet/node.yaml +++ b/devnet/node.yaml @@ -182,8 +182,8 @@ metadata: name: node-wormchain-key type: Opaque data: - accountantKey0: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0Ka2RmOiBiY3J5cHQKc2FsdDogNDc2ODc2NkE3OEZEN0ZBQjMwMUJGOTM5MUYwQ0Y2M0YKdHlwZTogc2VjcDI1NmsxCgpkbEZuN1ZqRk02RnJjYkdaVDRWeE5yRlE3SUhQS2RyVVBCRTYraW8yK0w0VFZqcis5emNIQTF3dzNubWtqNVFlCnVSekJWMjQyeUdTc3hNTTJZckI2Q1ZXdzlaWXJJY3JFeks1c0FuST0KPXB2aHkKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t - accountantKey1: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0Ka2RmOiBiY3J5cHQKc2FsdDogNzc1M0NCQTBBMUQ0NTJCMkE2QzlERDM4ODc3MTg0NEEKdHlwZTogc2VjcDI1NmsxCgpSYnhRVWRnK2ZHcjMzZTAyVWFFQW1YTDFlNFkrTGJUMFdqbnl4RVR3OXBoL2JXOGI0MzdhWmErOWlCc3NBa0UyCnRScUwvb0J1NWFnQXJocHNnWUgxNlhOWjJHMXRwY0R3V0dQZ1VWVT0KPUd6YUwKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t + accountantKey0: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0Ka2RmOiBiY3J5cHQKc2FsdDogRjlGRUFBRDQ4NzJCNjQzN0JFRTI2MEU3QTUwOTFBOTEKdHlwZTogc2VjcDI1NmsxCgpxMEFsUHBqMFhxL1cvcStHUEUwRjVzOUZreVcwOHVZUFJKVFc5OENpbFNUZGhiQ3Z3T2kwWlVXb0pta2xoMm5ICnRmZEViTDF1NHEycnJjcDF5b0dLVHRNRmVOQm9aMW5IeWxlQ3lxMD0KPXk3cjAKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t + accountantKey1: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0Ka2RmOiBiY3J5cHQKc2FsdDogNzIyNDgyNzNBRjMzMDM4NTFDNjc0MURENzQ2MjMyNDAKdHlwZTogc2VjcDI1NmsxCgpaMmZwdHRRN0lCK1Y0NjBRZ0RqMGdqZmJIYlN5a0VCTGl6ZS9NQ1g4N2dBSkdyZzBIMTZPamtybUNQNkZVeERZClpadG1GOUx5ZEE5eVg3Z2pQbzd3ZlBGOW44cTFGMXV1RUVqQ3cvcz0KPU9nOXYKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t gwrelayerKey0: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0KdHlwZTogc2VjcDI1NmsxCmtkZjogYmNyeXB0CnNhbHQ6IDc4OUYzRTBCMkVGNDcyNjAyQzNFMUE0OUI2OENFQzlBCgpGWHAvSllPS3E4WmZtOWxHZ3ZFNEM3NXFyUXFNZFp2RHNWRjhObTdMQU1oR2dHbXBnZnpoZjUrZ3IwZ1hjYjVWCmtSTXA2c0p0NkxCVzRPYWF2ckk3ay84Vml2NWhMVU1la1dPMHg5bz0KPUxrb1MKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t gwrelayerKey1: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0Ka2RmOiBiY3J5cHQKc2FsdDogNDc5RDk3RDE2OTE0QkQ4QjlFNUUwQzkzMDA0RDA4RUEKdHlwZTogc2VjcDI1NmsxCgpvTEJ0aUkwT2pudXo5bHlzeVlZOFhQeEVkTnpwYUJOVWFkL0UySlJld2pFWFZNVVNTWll2QVZKbERiN3hEQjlSCmEvdm45SFNPM2hKOFc1QTBKOVFqUVZXRzVoZXBNZVpQUEI4M1FCUT0KPVJuTGEKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t accountantNttKey0: LS0tLS1CRUdJTiBURU5ERVJNSU5UIFBSSVZBVEUgS0VZLS0tLS0Ka2RmOiBiY3J5cHQKc2FsdDogNzI4NTBEREJFNDQ4NzZBN0Q1Q0YxNDlBQjBGQjNBQzEKdHlwZTogc2VjcDI1NmsxCgpYN1BGMUJaZFBZMmlvRHdVRm9KcXdVdVg4YlFmcFNGckk4UklPS2g1ZUg5cCtDUzZYMm5lM2hVWGFPTDB3YXhUCnM3QVduTzErU241L1g1V0NicklqNHdDVUcwUWdNb0IyN2VFQnB2ND0KPWJiSEkKLS0tLS1FTkQgVEVOREVSTUlOVCBQUklWQVRFIEtFWS0tLS0t diff --git a/devnet/tests.yaml b/devnet/tests.yaml index 3f5d698108..b4cdff5c02 100644 --- a/devnet/tests.yaml +++ b/devnet/tests.yaml @@ -100,31 +100,6 @@ spec: --- kind: Job apiVersion: batch/v1 -metadata: - name: query-ci-tests -spec: - backoffLimit: 0 - template: - spec: - restartPolicy: Never - containers: - - name: query-ci-tests - image: guardiand-image - command: - - /bin/sh - - -c - - "cd /app/node/hack/query/test && bash test_query.sh && touch success" - readinessProbe: - exec: - command: - - test - - -e - - "/app/node/hack/query/test/success" - initialDelaySeconds: 5 - periodSeconds: 5 ---- -kind: Job -apiVersion: batch/v1 metadata: name: query-sdk-ci-tests spec: diff --git a/node/hack/query/test/query_test.go b/node/hack/query/test/query_test.go deleted file mode 100644 index 5dadbebafa..0000000000 --- a/node/hack/query/test/query_test.go +++ /dev/null @@ -1,303 +0,0 @@ -package query_test - -import ( - "bytes" - "context" - "encoding/hex" - "fmt" - "os" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/wormhole-foundation/wormhole/sdk/vaa" - - "github.com/certusone/wormhole/node/hack/query/utils" - "github.com/certusone/wormhole/node/pkg/common" - "github.com/certusone/wormhole/node/pkg/p2p" - gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1" - "github.com/certusone/wormhole/node/pkg/query" - "github.com/ethereum/go-ethereum/accounts/abi" - ethCommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - ethCrypto "github.com/ethereum/go-ethereum/crypto" - pubsub "github.com/libp2p/go-libp2p-pubsub" - "github.com/libp2p/go-libp2p/core/crypto" - "go.uber.org/zap" - "google.golang.org/protobuf/proto" -) - -func TestCrossChainQuery(t *testing.T) { - if os.Getenv("INTEGRATION") == "" { - t.Skip("Skipping integration test, set environment variable INTEGRATION") - } - - p2pNetworkID := "/wormhole/dev" - var p2pPort uint = 8997 - p2pBootstrap := "/dns4/guardian-0.guardian/udp/8996/quic/p2p/12D3KooWL3XJ9EMCyZvmmGXL2LMiVBtrVa2BuESsJiXkSj7333Jw" - nodeKeyPath := "../querier.key" - - ctx := context.Background() - logger, _ := zap.NewDevelopment() - - if bootstrapPeers := os.Getenv("BOOTSTRAP_PEERS"); bootstrapPeers != "" { - logger.Info("Overriding bootstrap peers", zap.String("old", p2pBootstrap), zap.String("new", bootstrapPeers)) - p2pBootstrap = bootstrapPeers - } - - signingKeyPath := string("../dev.guardian.key") - - logger.Info("Loading signing key", zap.String("signingKeyPath", signingKeyPath)) - sk, err := common.LoadGuardianKey(signingKeyPath, true) - if err != nil { - logger.Fatal("failed to load guardian key", zap.Error(err)) - } - logger.Info("Signing key loaded", zap.String("publicKey", ethCrypto.PubkeyToAddress(sk.PublicKey).Hex())) - - // Fetch the current guardian set - idx, sgs, err := utils.FetchCurrentGuardianSet(common.GoTest) - if err != nil { - logger.Fatal("Failed to fetch current guardian set", zap.Error(err)) - } - logger.Info("Fetched guardian set", zap.Any("keys", sgs.Keys)) - gs := common.GuardianSet{ - Keys: sgs.Keys, - Index: idx, - } - - // Fetch the latest block number - blockNum, err := utils.FetchLatestBlockNumber(ctx, common.GoTest) - if err != nil { - logger.Fatal("Failed to fetch latest block number", zap.Error(err)) - } - - // Load p2p private key - var priv crypto.PrivKey - priv, err = common.GetOrCreateNodeKey(logger, nodeKeyPath) - if err != nil { - logger.Fatal("Failed to load node key", zap.Error(err)) - } - - // Manual p2p setup - components := p2p.DefaultComponents() - components.Port = p2pPort - bootstrapPeers := p2pBootstrap - networkID := p2pNetworkID + "/ccq" - - h, err := p2p.NewHost(logger, ctx, networkID, bootstrapPeers, components, priv) - if err != nil { - panic(err) - } - - topic_req := fmt.Sprintf("%s/%s", networkID, "ccq_req") - topic_resp := fmt.Sprintf("%s/%s", networkID, "ccq_resp") - - logger.Info("Subscribing pubsub topic", zap.String("topic_req", topic_req), zap.String("topic_resp", topic_resp)) - ps, err := pubsub.NewGossipSub(ctx, h) - if err != nil { - panic(err) - } - - th_req, err := ps.Join(topic_req) - if err != nil { - logger.Panic("failed to join request topic", zap.String("topic_req", topic_req), zap.Error(err)) - } - - th_resp, err := ps.Join(topic_resp) - if err != nil { - logger.Panic("failed to join response topic", zap.String("topic_resp", topic_resp), zap.Error(err)) - } - - sub, err := th_resp.Subscribe() - if err != nil { - logger.Panic("failed to subscribe to response topic", zap.Error(err)) - } - - logger.Info("Node has been started", zap.String("peer_id", h.ID().String()), - zap.String("addrs", fmt.Sprintf("%v", h.Addrs()))) - - // Wait for peers - for len(th_req.ListPeers()) < 1 { - time.Sleep(time.Millisecond * 100) - } - - logger.Info("Detected peers") - - wethAbi, err := abi.JSON(strings.NewReader("[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]")) - if err != nil { - panic(err) - } - - methodName := "name" - data, err := wethAbi.Pack(methodName) - if err != nil { - panic(err) - } - to, _ := hex.DecodeString("DDb64fE46a91D46ee29420539FC25FD07c5FEa3E") // WETH - - callData := []*query.EthCallData{ - { - To: to, - Data: data, - }, - } - - callRequest := &query.EthCallQueryRequest{ - BlockId: hexutil.EncodeBig(blockNum), - CallData: callData, - } - - queryRequest := &query.QueryRequest{ - Nonce: 1, - PerChainQueries: []*query.PerChainQueryRequest{ - { - ChainId: 2, - Query: callRequest, - }, - }, - } - - queryRequestBytes, err := queryRequest.Marshal() - if err != nil { - panic(err) - } - - // Sign the query request using our private key. - digest := query.QueryRequestDigest(common.UnsafeDevNet, queryRequestBytes) - sig, err := ethCrypto.Sign(digest.Bytes(), sk) - if err != nil { - panic(err) - } - - signedQueryRequest := &gossipv1.SignedQueryRequest{ - QueryRequest: queryRequestBytes, - Signature: sig, - } - - msg := gossipv1.GossipMessage{ - Message: &gossipv1.GossipMessage_SignedQueryRequest{ - SignedQueryRequest: signedQueryRequest, - }, - } - - b, err := proto.Marshal(&msg) - if err != nil { - panic(err) - } - - err = th_req.Publish(ctx, b) - if err != nil { - panic(err) - } - - logger.Info("Waiting for message...") - var success bool - signers := map[int]bool{} - // The guardians can retry for up to a minute so we have to wait longer than that. - subCtx, cancel := context.WithTimeout(ctx, 75*time.Second) - defer cancel() - for { - envelope, err := sub.Next(subCtx) - if err != nil { - break - } - var msg gossipv1.GossipMessage - err = proto.Unmarshal(envelope.Data, &msg) - if err != nil { - logger.Fatal("received invalid message", - zap.Binary("data", envelope.Data), - zap.String("from", envelope.GetFrom().String())) - } - switch m := msg.Message.(type) { - case *gossipv1.GossipMessage_SignedQueryResponse: - var response query.QueryResponsePublication - err := response.Unmarshal(m.SignedQueryResponse.QueryResponse) - if err != nil { - logger.Fatal("failed to unmarshal response", zap.Error(err), zap.Any("response", m.SignedQueryResponse)) - } - logger.Info("query response received", zap.Any("response", response)) - if bytes.Equal(response.Request.QueryRequest, queryRequestBytes) && bytes.Equal(response.Request.Signature, sig) { - digest := query.GetQueryResponseDigestFromBytes(m.SignedQueryResponse.QueryResponse) - signerBytes, err := ethCrypto.Ecrecover(digest.Bytes(), m.SignedQueryResponse.Signature) - if err != nil { - logger.Fatal("failed to verify signature on response", - zap.String("digest", digest.Hex()), - zap.String("signature", hex.EncodeToString(m.SignedQueryResponse.Signature)), - zap.Error(err)) - } - signerAddress := ethCommon.BytesToAddress(ethCrypto.Keccak256(signerBytes[1:])[12:]) - if keyIdx, ok := gs.KeyIndex(signerAddress); !ok { - logger.Fatal("received observation by unknown guardian - is our guardian set outdated?", - zap.String("digest", digest.Hex()), - zap.String("address", signerAddress.Hex()), - zap.Uint32("index", gs.Index), - zap.Any("keys", gs.KeysAsHexStrings()), - ) - } else { - signers[keyIdx] = true - } - quorum := vaa.CalculateQuorum(len(gs.Keys)) - if len(signers) < quorum { - logger.Sugar().Infof("not enough signers, have %d need %d", len(signers), quorum) - continue - } - - if len(response.PerChainResponses) != 1 { - logger.Warn("unexpected number of per chain query responses", zap.Int("expectedNum", 1), zap.Int("actualNum", len(response.PerChainResponses))) - break - } - - var pcq *query.EthCallQueryResponse - switch ecq := response.PerChainResponses[0].Response.(type) { - case *query.EthCallQueryResponse: - pcq = ecq - default: - panic("unsupported query type") - } - - if len(pcq.Results) == 0 { - logger.Warn("response did not contain any results", zap.Error(err)) - break - } - - for idx, resp := range pcq.Results { - result, err := wethAbi.Methods[methodName].Outputs.Unpack(resp) - if err != nil { - logger.Warn("failed to unpack result", zap.Error(err)) - break - } - - resultStr := hexutil.Encode(resp) - logger.Info("found matching response", zap.Int("idx", idx), zap.Uint64("number", pcq.BlockNumber), zap.String("hash", pcq.Hash.String()), zap.String("time", pcq.Time.String()), zap.Any("resultDecoded", result), zap.String("resultStr", resultStr)) - } - - success = true - } - default: - continue - } - if success { - break - } - } - - assert.True(t, success) - - // Cleanly shutdown - // Without this the same host won't properly discover peers until some timeout - sub.Cancel() - if err := th_req.Close(); err != nil { - logger.Fatal("Error closing the request topic", zap.Error(err)) - } - if err := th_resp.Close(); err != nil { - logger.Fatal("Error closing the response topic", zap.Error(err)) - } - if err := h.Close(); err != nil { - logger.Error("Error closing the host", zap.Error(err)) - } -} - -const ( - GuardianKeyArmoredBlock = "WORMHOLE GUARDIAN PRIVATE KEY" -) diff --git a/node/hack/query/test/test_query.sh b/node/hack/query/test/test_query.sh deleted file mode 100644 index 658cd31235..0000000000 --- a/node/hack/query/test/test_query.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -set -e -num=${NUM_GUARDIANS:-1} # default value for NUM_GUARDIANS = 1 -for ((i=0; i { const solAccountResp2 = SolanaAccountQueryResponse.from(serialized); expect(solAccountResp2).toEqual(solAccountResp); }); - test("successful sol_account query", async () => { + // Skipping this test because queries without min context slot may not reach quorum in CI. + test.skip("successful sol_account query without min context slot", async () => { const solAccountReq = new SolanaAccountQueryRequest("finalized", ACCOUNTS); const nonce = 42; const query = new PerChainQueryRequest(1, solAccountReq); @@ -196,12 +197,14 @@ describe("solana", () => { const sar = queryResponse.responses[0] .response as SolanaAccountQueryResponse; - expect(Number(sar.slotNumber)).not.toEqual(0); - expect(Number(sar.blockTime)).not.toEqual(0); + expect(sar.slotNumber.toString()).not.toEqual(BigInt(0).toString()); + expect(sar.blockTime.toString()).not.toEqual(BigInt(0).toString()); expect(sar.results.length).toEqual(2); - expect(Number(sar.results[0].lamports)).toEqual(1461600); - expect(Number(sar.results[0].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).toEqual( + BigInt(1461600).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[0].executable).toEqual(false); expect(base58.encode(Buffer.from(sar.results[0].owner))).toEqual( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" @@ -210,8 +213,10 @@ describe("solana", () => { "01000000574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d0000e8890423c78a0901000000000000000000000000000000000000000000000000000000000000000000000000" ); - expect(Number(sar.results[1].lamports)).toEqual(1461600); - expect(Number(sar.results[1].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).toEqual( + BigInt(1461600).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[1].executable).toEqual(false); expect(base58.encode(Buffer.from(sar.results[1].owner))).toEqual( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" @@ -256,12 +261,14 @@ describe("solana", () => { const sar = queryResponse.responses[0] .response as SolanaAccountQueryResponse; - expect(sar.slotNumber).toEqual(minContextSlot); - expect(Number(sar.blockTime)).not.toEqual(0); + expect(sar.slotNumber.toString()).toEqual(minContextSlot.toString()); + expect(sar.blockTime.toString()).not.toEqual(BigInt(0).toString()); expect(sar.results.length).toEqual(2); - expect(Number(sar.results[0].lamports)).toEqual(1461600); - expect(Number(sar.results[0].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).toEqual( + BigInt(1461600).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[0].executable).toEqual(false); expect(base58.encode(Buffer.from(sar.results[0].owner))).toEqual( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" @@ -270,8 +277,10 @@ describe("solana", () => { "01000000574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d0000e8890423c78a0901000000000000000000000000000000000000000000000000000000000000000000000000" ); - expect(Number(sar.results[1].lamports)).toEqual(1461600); - expect(Number(sar.results[1].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).toEqual( + BigInt(1461600).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[1].executable).toEqual(false); expect(base58.encode(Buffer.from(sar.results[1].owner))).toEqual( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" @@ -288,9 +297,11 @@ describe("solana", () => { BigInt(12), BigInt(20) ); - expect(Number(solPdaReq.minContextSlot)).toEqual(123456); - expect(Number(solPdaReq.dataSliceOffset)).toEqual(12); - expect(Number(solPdaReq.dataSliceLength)).toEqual(20); + expect(solPdaReq.minContextSlot.toString()).toEqual( + BigInt(123456).toString() + ); + expect(solPdaReq.dataSliceOffset.toString()).toEqual(BigInt(12).toString()); + expect(solPdaReq.dataSliceLength.toString()).toEqual(BigInt(20).toString()); const serialized = solPdaReq.serialize(); expect(Buffer.from(serialized).toString("hex")).toEqual( "0000000966696e616c697a6564000000000001e240000000000000000c00000000000000140102c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa020000000b477561726469616e5365740000000400000000" @@ -316,16 +327,20 @@ describe("solana", () => { const sar = queryResponse.responses[0].response as SolanaPdaQueryResponse; - expect(Number(sar.slotNumber)).toEqual(2303); - expect(Number(sar.blockTime)).toEqual(0x0006115e3f6d7540); + expect(sar.slotNumber.toString()).toEqual(BigInt(2303).toString()); + expect(sar.blockTime.toString()).toEqual( + BigInt(0x0006115e3f6d7540).toString() + ); expect(sar.results.length).toEqual(1); expect(Buffer.from(sar.results[0].account).toString("hex")).toEqual( "4fa9188b339cfd573a0778c5deaeeee94d4bcfb12b345bf8e417e5119dae773e" ); expect(sar.results[0].bump).toEqual(253); - expect(Number(sar.results[0].lamports)).not.toEqual(0); - expect(Number(sar.results[0].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).not.toEqual( + BigInt(0).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[0].executable).toEqual(false); expect(Buffer.from(sar.results[0].owner).toString("hex")).toEqual( "02c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa" @@ -335,10 +350,12 @@ describe("solana", () => { ); }); test("successful sol_pda query", async () => { + const currSlot = await getSolanaSlot("finalized"); + const minContextSlot = BigInt(currSlot) + BigInt(10); const solPdaReq = new SolanaPdaQueryRequest( "finalized", PDAS, - BigInt(0), + minContextSlot, BigInt(12), BigInt(16) // After this, things can change. ); @@ -370,17 +387,18 @@ describe("solana", () => { const sar = queryResponse.responses[0].response as SolanaPdaQueryResponse; - expect(Number(sar.slotNumber)).not.toEqual(0); - expect(Number(sar.blockTime)).not.toEqual(0); + expect(sar.slotNumber.toString()).not.toEqual(BigInt(0).toString()); + expect(sar.blockTime.toString()).not.toEqual(BigInt(0).toString()); expect(sar.results.length).toEqual(1); expect(Buffer.from(sar.results[0].account).toString("hex")).toEqual( "4fa9188b339cfd573a0778c5deaeeee94d4bcfb12b345bf8e417e5119dae773e" ); expect(sar.results[0].bump).toEqual(253); - expect(Number(sar.results[0].lamports)).not.toEqual(0); - - expect(Number(sar.results[0].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).not.toEqual( + BigInt(0).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[0].executable).toEqual(false); expect(Buffer.from(sar.results[0].owner).toString("hex")).toEqual( "02c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa" @@ -426,16 +444,18 @@ describe("solana", () => { ); const sar = queryResponse.responses[0].response as SolanaPdaQueryResponse; - expect(sar.slotNumber).toEqual(minContextSlot); - expect(Number(sar.blockTime)).not.toEqual(0); + expect(sar.slotNumber.toString()).toEqual(minContextSlot.toString()); + expect(sar.blockTime.toString()).not.toEqual(BigInt(0).toString()); expect(sar.results.length).toEqual(1); expect(Buffer.from(sar.results[0].account).toString("hex")).toEqual( "4fa9188b339cfd573a0778c5deaeeee94d4bcfb12b345bf8e417e5119dae773e" ); expect(sar.results[0].bump).toEqual(253); - expect(Number(sar.results[0].lamports)).not.toEqual(0); - expect(Number(sar.results[0].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).not.toEqual( + BigInt(0).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[0].executable).toEqual(false); expect(Buffer.from(sar.results[0].owner).toString("hex")).toEqual( "02c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa" @@ -445,11 +465,18 @@ describe("solana", () => { ); }); test("concurrent queries", async () => { - const solAccountReq = new SolanaAccountQueryRequest("finalized", ACCOUNTS); + const currSlot = await getSolanaSlot("finalized"); + const minContextSlot = BigInt(currSlot) + BigInt(10); + const solAccountReq = new SolanaAccountQueryRequest( + "finalized", + ACCOUNTS, + minContextSlot + ); const query = new PerChainQueryRequest(1, solAccountReq); let nonce = 42; let promises: Promise>[] = []; - for (let count = 0; count < 20; count++) { + // The count should be no more than the number of workers defined for Solana in `node/pkg/query/query.go`. + for (let count = 0; count < 10; count++) { nonce += 1; const request = new QueryRequest(nonce, [query]); const serialized = request.serialize(); @@ -485,12 +512,14 @@ describe("solana", () => { const sar = queryResponse.responses[0] .response as SolanaAccountQueryResponse; - expect(Number(sar.slotNumber)).not.toEqual(0); - expect(Number(sar.blockTime)).not.toEqual(0); + expect(sar.slotNumber.toString()).not.toEqual(BigInt(0).toString()); + expect(sar.blockTime.toString()).not.toEqual(BigInt(0).toString()); expect(sar.results.length).toEqual(2); - expect(Number(sar.results[0].lamports)).toEqual(1461600); - expect(Number(sar.results[0].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).toEqual( + BigInt(1461600).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[0].executable).toEqual(false); expect(base58.encode(Buffer.from(sar.results[0].owner))).toEqual( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" @@ -499,8 +528,10 @@ describe("solana", () => { "01000000574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d0000e8890423c78a0901000000000000000000000000000000000000000000000000000000000000000000000000" ); - expect(Number(sar.results[1].lamports)).toEqual(1461600); - expect(Number(sar.results[1].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).toEqual( + BigInt(1461600).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[1].executable).toEqual(false); expect(base58.encode(Buffer.from(sar.results[1].owner))).toEqual( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" @@ -511,7 +542,13 @@ describe("solana", () => { } }); test("sol_account query with allow anything", async () => { - const solAccountReq = new SolanaAccountQueryRequest("finalized", ACCOUNTS); + const currSlot = await getSolanaSlot("finalized"); + const minContextSlot = BigInt(currSlot) + BigInt(10); + const solAccountReq = new SolanaAccountQueryRequest( + "finalized", + ACCOUNTS, + minContextSlot + ); const nonce = 42; const query = new PerChainQueryRequest(1, solAccountReq); const request = new QueryRequest(nonce, [query]); @@ -540,12 +577,14 @@ describe("solana", () => { const sar = queryResponse.responses[0] .response as SolanaAccountQueryResponse; - expect(Number(sar.slotNumber)).not.toEqual(0); - expect(Number(sar.blockTime)).not.toEqual(0); + expect(sar.slotNumber.toString()).not.toEqual(BigInt(0).toString()); + expect(sar.blockTime.toString()).not.toEqual(BigInt(0).toString()); expect(sar.results.length).toEqual(2); - expect(Number(sar.results[0].lamports)).toEqual(1461600); - expect(Number(sar.results[0].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).toEqual( + BigInt(1461600).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[0].executable).toEqual(false); expect(base58.encode(Buffer.from(sar.results[0].owner))).toEqual( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" @@ -554,8 +593,10 @@ describe("solana", () => { "01000000574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d0000e8890423c78a0901000000000000000000000000000000000000000000000000000000000000000000000000" ); - expect(Number(sar.results[1].lamports)).toEqual(1461600); - expect(Number(sar.results[1].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).toEqual( + BigInt(1461600).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[1].executable).toEqual(false); expect(base58.encode(Buffer.from(sar.results[1].owner))).toEqual( "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" @@ -565,10 +606,12 @@ describe("solana", () => { ); }); test("sol_pda query with allow anything", async () => { + const currSlot = await getSolanaSlot("finalized"); + const minContextSlot = BigInt(currSlot) + BigInt(10); const solPdaReq = new SolanaPdaQueryRequest( "finalized", PDAS, - BigInt(0), + minContextSlot, BigInt(12), BigInt(16) // After this, things can change. ); @@ -600,17 +643,18 @@ describe("solana", () => { const sar = queryResponse.responses[0].response as SolanaPdaQueryResponse; - expect(Number(sar.slotNumber)).not.toEqual(0); - expect(Number(sar.blockTime)).not.toEqual(0); + expect(sar.slotNumber.toString()).not.toEqual(BigInt(0).toString()); + expect(sar.blockTime.toString()).not.toEqual(BigInt(0).toString()); expect(sar.results.length).toEqual(1); expect(Buffer.from(sar.results[0].account).toString("hex")).toEqual( "4fa9188b339cfd573a0778c5deaeeee94d4bcfb12b345bf8e417e5119dae773e" ); expect(sar.results[0].bump).toEqual(253); - expect(Number(sar.results[0].lamports)).not.toEqual(0); - - expect(Number(sar.results[0].rentEpoch)).toEqual(0); + expect(sar.results[0].lamports.toString()).not.toEqual( + BigInt(0).toString() + ); + expect(sar.results[0].rentEpoch.toString()).toEqual(BigInt(0).toString()); expect(sar.results[0].executable).toEqual(false); expect(Buffer.from(sar.results[0].owner).toString("hex")).toEqual( "02c806312cbe5b79ef8aa6c17e3f423d8fdfe1d46909fb1f6cdf65ee8e2e6faa" diff --git a/wormchain/contracts/tools/deploy_wormchain.ts b/wormchain/contracts/tools/deploy_wormchain.ts index 3ab8b962e5..cc1273be93 100644 --- a/wormchain/contracts/tools/deploy_wormchain.ts +++ b/wormchain/contracts/tools/deploy_wormchain.ts @@ -393,6 +393,16 @@ async function main() { address: "wormhole18s5lynnmx37hq4wlrw9gdn68sg2uxp5rwf5k3u", name: "nttAccountantTest", }), + client.core.msgCreateAllowlistEntryRequest({ + signer: signer, + address: "wormhole1h6v7cku5w803pf563czepx5s32vrzz5cntj9k4", + name: "guardianAccountant0", + }), + client.core.msgCreateAllowlistEntryRequest({ + signer: signer, + address: "wormhole1g25zz7gyuyh6chuejc3ppfemgfla4xpsm69lzq", + name: "guardianAccountant1", + }), ], { ...ZERO_FEE, diff --git a/wormchain/devnet/base/config/genesis.json b/wormchain/devnet/base/config/genesis.json index 9c07f339c9..4e4413dda3 100644 --- a/wormchain/devnet/base/config/genesis.json +++ b/wormchain/devnet/base/config/genesis.json @@ -84,6 +84,20 @@ "pub_key": null, "account_number": "0", "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "wormhole1h6v7cku5w803pf563czepx5s32vrzz5cntj9k4", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "wormhole1g25zz7gyuyh6chuejc3ppfemgfla4xpsm69lzq", + "pub_key": null, + "account_number": "0", + "sequence": "0" } ] }, @@ -196,6 +210,32 @@ "amount": "200000000" } ] + }, + { + "address": "wormhole1h6v7cku5w803pf563czepx5s32vrzz5cntj9k4", + "coins": [ + { + "denom": "utest", + "amount": "100000000000" + }, + { + "denom": "uworm", + "amount": "200000000" + } + ] + }, + { + "address": "wormhole1g25zz7gyuyh6chuejc3ppfemgfla4xpsm69lzq", + "coins": [ + { + "denom": "utest", + "amount": "100000000000" + }, + { + "denom": "uworm", + "amount": "200000000" + } + ] } ], "supply": [],