From 790edc48b8b6dbc81de39ab60442e37479e484e4 Mon Sep 17 00:00:00 2001 From: Warren He Date: Wed, 16 Oct 2024 20:46:37 -0700 Subject: [PATCH] add callformat interop test --- client-sdk/go/callformat/callformat_test.go | 51 +++++++++++++++++++++ runtime-sdk/src/callformat.rs | 49 ++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 client-sdk/go/callformat/callformat_test.go diff --git a/client-sdk/go/callformat/callformat_test.go b/client-sdk/go/callformat/callformat_test.go new file mode 100644 index 0000000000..7700a064c0 --- /dev/null +++ b/client-sdk/go/callformat/callformat_test.go @@ -0,0 +1,51 @@ +package callformat + +import ( + "crypto/sha512" + "encoding/hex" + "testing" + + "github.com/oasisprotocol/curve25519-voi/primitives/x25519" + "github.com/oasisprotocol/deoxysii" + "github.com/oasisprotocol/oasis-core/go/common/cbor" + "github.com/stretchr/testify/require" + + "github.com/oasisprotocol/oasis-sdk/client-sdk/go/types" +) + +func TestInterop(t *testing.T) { + clientSK := (x25519.PrivateKey)(sha512.Sum512_256([]byte("callformat test client"))) + clientPK := clientSK.Public() + runtimeSK := (x25519.PrivateKey)(sha512.Sum512_256([]byte("callformat test runtime"))) + runtimePK := runtimeSK.Public() + + call := types.Call{ + Method: "mock", + Body: nil, + } + var nonce [deoxysii.NonceSize]byte + cfg := EncodeConfig{ + PublicKey: &types.SignedPublicKey{PublicKey: *runtimePK}, + Epoch: 1, + } + callEnc, metadata := encodeCallEncryptedX25519DeoxysII(&call, clientPK, &clientSK, nonce, &cfg) + + // If these change, update runtime-sdk/src/callformat.rs too. + require.Equal(t, "a264626f6479f6666d6574686f64646d6f636b", hex.EncodeToString(cbor.Marshal(call))) + require.Equal(t, "a264626f6479a462706b5820eedc75d3c500fc1b2d321757c383e276ab705c5a02013b3f1966e9caf73cdb0264646174615823c4635f2f9496a033a578e3f1e007be5d6cfa9631fb2fe2c8c76d26b322b6afb2fa5cdf6565706f636801656e6f6e63654f00000000000000000000000000000066666f726d617401", hex.EncodeToString(cbor.Marshal(callEnc))) + + resultCBOR, err := hex.DecodeString("a1626f6bf6") + require.NoError(t, err) + var result types.CallResult + err = cbor.Unmarshal(resultCBOR, &result) + require.NoError(t, err) + resultEncCBOR, err := hex.DecodeString("a167756e6b6e6f776ea264646174615528d1c5eedc5e54e1ef140ba905e84e0bea8daf60af656e6f6e63654f000000000000000000000000000000") + require.NoError(t, err) + var resultEnc types.CallResult + err = cbor.Unmarshal(resultEncCBOR, &resultEnc) + require.NoError(t, err) + + resultOurs, err := DecodeResult(&resultEnc, metadata) + require.NoError(t, err) + require.Equal(t, &result, resultOurs) +} diff --git a/runtime-sdk/src/callformat.rs b/runtime-sdk/src/callformat.rs index ebad3110f8..351f9f278c 100644 --- a/runtime-sdk/src/callformat.rs +++ b/runtime-sdk/src/callformat.rs @@ -347,3 +347,52 @@ pub fn decode_result( } } } + +#[cfg(test)] +mod test { + use digest::Digest; + use oasis_core_keymanager::crypto::{InputKeyPair, KeyPair}; + use oasis_core_runtime::common::crypto::x25519; + use crate::{callformat, crypto, module, testing, types}; + + #[test] + fn test_interop() { + let _guard = crypto::signature::context::test_using_chain_context(); + crypto::signature::context::set_chain_context(Default::default(), "test"); + + let runtime_sk = x25519::PrivateKey::from(<[u8; x25519::PRIVATE_KEY_LENGTH]>::from(sha2::Sha512_256::digest("callformat test runtime"))); + let runtime_pk = runtime_sk.public_key(); + + let mut mock = testing::mock::Mock::default(); + let our_key_pair_id = callformat::get_key_pair_id(mock.epoch); + let our_key_pair = KeyPair { + input_keypair: InputKeyPair { + pk: runtime_pk, + sk: runtime_sk, + }, + ..Default::default() + }; + let ephemeral_keys = std::collections::HashMap::from([ + (our_key_pair_id, our_key_pair), + ]); + let key_manager = testing::keymanager::MockKeyManagerClient { + ephemeral_keys: ephemeral_keys.into(), + ..Default::default() + }; + let ctx = mock.create_ctx_with_key_manager(Box::new(key_manager)); + + let call = cbor::from_slice::(hex::decode("a264626f6479f6666d6574686f64646d6f636b").unwrap().as_slice()).unwrap(); + let call_enc = cbor::from_slice::(hex::decode("a264626f6479a462706b5820eedc75d3c500fc1b2d321757c383e276ab705c5a02013b3f1966e9caf73cdb0264646174615823c4635f2f9496a033a578e3f1e007be5d6cfa9631fb2fe2c8c76d26b322b6afb2fa5cdf6565706f636801656e6f6e63654f00000000000000000000000000000066666f726d617401").unwrap().as_slice()).unwrap(); + + let (call_ours, metadata) = callformat::decode_call(&ctx, call_enc, 0).unwrap().unwrap(); + assert_eq!(cbor::to_vec(call_ours), cbor::to_vec(call)); + + let result_m_g = || module::CallResult::Ok(cbor::Value::Simple(cbor::SimpleValue::NullValue)); + let result = types::transaction::CallResult::from(result_m_g()); + let result_enc = callformat::encode_result(&ctx, result_m_g(), metadata); + + // If these change, update client-sdk/go/callformat/callformat_test.go too. + assert_eq!(hex::encode(cbor::to_vec(result)), "a1626f6bf6"); + assert_eq!(hex::encode(cbor::to_vec(result_enc)), "a167756e6b6e6f776ea264646174615528d1c5eedc5e54e1ef140ba905e84e0bea8daf60af656e6f6e63654f000000000000000000000000000000"); + } +}