From 0d4b6a26f7ddfa117c3ad4d6518564220be9066b Mon Sep 17 00:00:00 2001 From: Jernej Kos Date: Thu, 2 Jun 2022 14:28:33 +0200 Subject: [PATCH] runtime: Bump oasis-cbor to 0.3.0 --- .changelog/4784.internal.md | 1 + Cargo.lock | 12 +-- client/Cargo.toml | 2 +- go/common/node/node_test.go | 40 ++++++- go/staking/api/address_test.go | 13 +++ keymanager-api-common/Cargo.toml | 2 +- keymanager-api-common/src/api.rs | 24 ++--- keymanager-client/Cargo.toml | 2 +- keymanager-lib/Cargo.toml | 2 +- runtime/Cargo.toml | 2 +- runtime/src/common/bytes.rs | 13 +++ runtime/src/common/quantity.rs | 8 ++ runtime/src/common/sgx/avr.rs | 11 +- runtime/src/common/version.rs | 6 -- runtime/src/consensus/address.rs | 13 +++ runtime/src/consensus/mod.rs | 2 +- runtime/src/consensus/registry.rs | 113 ++++++++++++-------- runtime/src/consensus/roothash.rs | 28 ++--- runtime/src/consensus/staking.rs | 36 ++----- runtime/src/enclave_rpc/session.rs | 2 +- runtime/src/enclave_rpc/types.rs | 12 ++- runtime/src/storage/mkvs/interop/rpc.rs | 2 +- runtime/src/storage/mkvs/mod.rs | 2 +- runtime/src/storage/mkvs/sync/mod.rs | 1 - runtime/src/transaction/tree.rs | 4 +- runtime/src/types.rs | 46 ++++---- tests/runtimes/simple-keyvalue/Cargo.toml | 2 +- tests/runtimes/simple-keyvalue/src/types.rs | 15 +-- 28 files changed, 251 insertions(+), 165 deletions(-) create mode 100644 .changelog/4784.internal.md diff --git a/.changelog/4784.internal.md b/.changelog/4784.internal.md new file mode 100644 index 00000000000..e56a2514414 --- /dev/null +++ b/.changelog/4784.internal.md @@ -0,0 +1 @@ +runtime: Bump oasis-cbor to 0.3.0 diff --git a/Cargo.lock b/Cargo.lock index 5f88ac5419f..1976b62b104 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1594,9 +1594,9 @@ dependencies = [ [[package]] name = "oasis-cbor" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38035ab5ba813379234cc722327cc66f45b09316f109f69b54c589cc0e9e5f03" +checksum = "a4fb4c15ae11fe511d3570a8b4f0e311e91a8c8a41f446ecd0e09bdf04abf395" dependencies = [ "impl-trait-for-tuples", "oasis-cbor-derive", @@ -1606,9 +1606,9 @@ dependencies = [ [[package]] name = "oasis-cbor-derive" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329dfab5a691b5059ca211567f795876ad49ebd2cd14ab8680e18c17f4f1a805" +checksum = "6a4bb643d88ebb5e0adf586dfdfab57a4248d51e6ec943ee70c6dd7e3323f825" dependencies = [ "darling", "proc-macro-crate", @@ -2312,9 +2312,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f972498cf015f7c0746cac89ebe1d6ef10c293b94175a243a2d9442c163d9944" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ "itoa", "ryu", diff --git a/client/Cargo.toml b/client/Cargo.toml index 3cfac75355c..b3dc79f492c 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] oasis-core-runtime = { path = "../runtime" } -cbor = { version = "0.2.1", package = "oasis-cbor" } +cbor = { version = "0.3.0", package = "oasis-cbor" } # Third party. anyhow = "1.0" diff --git a/go/common/node/node_test.go b/go/common/node/node_test.go index 042e9acc01e..4502de1929f 100644 --- a/go/common/node/node_test.go +++ b/go/common/node/node_test.go @@ -2,7 +2,6 @@ package node import ( "encoding/base64" - "fmt" "net" "testing" @@ -271,6 +270,43 @@ func TestNodeForTestSerialization(t *testing.T) { var t map[string]interface{} err = cbor.Unmarshal(enc, &t) require.NoError(err, "Unamarshal inter") - fmt.Println(t) + } +} + +func TestNodeDeserialization(t *testing.T) { + require := require.New(t) + + var runtimeID common.Namespace + require.NoError(runtimeID.UnmarshalHex("8000000000000000000000000000000000000000000000000000000000000010"), "runtime id") + + // NOTE: These cases should be synced with tests in runtime/src/consensus/registry.rs. + for _, tc := range []struct { + rawBase64 string + expectedNode Node + }{ + { + "qmF2AmJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjcDJwomJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpYWRkcmVzc2Vz9mN0bHOjZ3B1Yl9rZXlYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWFkZHJlc3Nlc/ZsbmV4dF9wdWJfa2V5WCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVyb2xlcwBocnVudGltZXP2aWNvbnNlbnN1c6JiaWRYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWFkZHJlc3Nlc/ZpZW50aXR5X2lkWCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpleHBpcmF0aW9uAHBzb2Z0d2FyZV92ZXJzaW9u9g==", + Node{Versioned: cbor.NewVersioned(LatestNodeDescriptorVersion)}, + }, + { + "qWF2AmJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjcDJwomJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpYWRkcmVzc2Vz9mN0bHOjZ3B1Yl9rZXlYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWFkZHJlc3Nlc/ZsbmV4dF9wdWJfa2V5WCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVyb2xlcwBocnVudGltZXOBomJpZFgggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBndmVyc2lvbvZpY29uc2Vuc3VzomJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpYWRkcmVzc2Vz9mllbnRpdHlfaWRYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAamV4cGlyYXRpb24A", + Node{ + Versioned: cbor.NewVersioned(LatestNodeDescriptorVersion), + Runtimes: []*Runtime{ + { + ID: runtimeID, + Version: version.FromU64(0), + }, + }, + }, + }, + } { + raw, err := base64.StdEncoding.DecodeString(tc.rawBase64) + require.NoError(err, "DecodeString") + + var dec Node + err = cbor.Unmarshal(raw, &dec) + require.NoError(err, "Unmarshal") + require.EqualValues(tc.expectedNode, dec, "Node serialization should round-trip") } } diff --git a/go/staking/api/address_test.go b/go/staking/api/address_test.go index ec55b997570..7bd1da22cae 100644 --- a/go/staking/api/address_test.go +++ b/go/staking/api/address_test.go @@ -6,9 +6,22 @@ import ( "github.com/stretchr/testify/require" "github.com/oasisprotocol/oasis-core/go/common" + "github.com/oasisprotocol/oasis-core/go/common/cbor" "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" ) +func TestAddressDeserialization(t *testing.T) { + require := require.New(t) + + var addr Address + err := cbor.Unmarshal([]byte{0xF6}, &addr) + require.NoError(err, "cbor.Unmarshal") + require.EqualValues("oasis1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0ltrq9", addr.String()) + + raw, _ := addr.MarshalBinary() + require.EqualValues([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, raw) +} + func TestReserved(t *testing.T) { require := require.New(t) diff --git a/keymanager-api-common/Cargo.toml b/keymanager-api-common/Cargo.toml index 5fcc261204d..c05085528e9 100644 --- a/keymanager-api-common/Cargo.toml +++ b/keymanager-api-common/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] oasis-core-runtime = { path = "../runtime" } -cbor = { version = "0.2.1", package = "oasis-cbor" } +cbor = { version = "0.3.0", package = "oasis-cbor" } base64 = "0.13.0" rustc-hex = "2.0.1" diff --git a/keymanager-api-common/src/api.rs b/keymanager-api-common/src/api.rs index 79d083f1110..aa74522c36f 100644 --- a/keymanager-api-common/src/api.rs +++ b/keymanager-api-common/src/api.rs @@ -51,7 +51,7 @@ impl AsRef<[u8]> for MasterSecret { } /// Key manager initialization request. -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] pub struct InitRequest { /// Checksum for validating replication. pub checksum: Vec, @@ -62,7 +62,7 @@ pub struct InitRequest { } /// Key manager initialization response. -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] pub struct InitResponse { /// True iff the key manager thinks it's running in a secure mode. pub is_secure: bool, @@ -76,7 +76,7 @@ pub struct InitResponse { pub const INIT_RESPONSE_CONTEXT: &[u8] = b"oasis-core/keymanager: init response"; /// Signed InitResponse. -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] pub struct SignedInitResponse { /// InitResponse. pub init_response: InitResponse, @@ -85,19 +85,19 @@ pub struct SignedInitResponse { } /// Key manager replication request. -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] pub struct ReplicateRequest { // Empty. } /// Key manager replication response. -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] pub struct ReplicateResponse { pub master_secret: MasterSecret, } /// Request runtime/key pair id tuple. -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] pub struct RequestIds { /// Runtime ID. pub runtime_id: Namespace, @@ -121,7 +121,7 @@ impl RequestIds { } /// A key pair managed by the key manager. -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] pub struct KeyPair { /// Input key pair (pk, sk) pub input_keypair: InputKeyPair, @@ -171,7 +171,7 @@ impl KeyPair { } } -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] pub struct InputKeyPair { /// Public key. pub pk: PublicKey, @@ -183,7 +183,7 @@ pub struct InputKeyPair { pub const PUBLIC_KEY_CONTEXT: [u8; 8] = *b"EkKmPubK"; /// Signed public key. -#[derive(Clone, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)] pub struct SignedPublicKey { /// Public key. pub key: PublicKey, @@ -221,7 +221,7 @@ pub enum KeyManagerError { } /// Key manager access control policy. -#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct PolicySGX { pub serial: u32, pub id: Namespace, @@ -229,14 +229,14 @@ pub struct PolicySGX { } /// Per enclave key manager access control policy. -#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct EnclavePolicySGX { pub may_query: HashMap>, pub may_replicate: Vec, } /// Signed key manager access control policy. -#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct SignedPolicySGX { pub policy: PolicySGX, pub signatures: Vec, diff --git a/keymanager-client/Cargo.toml b/keymanager-client/Cargo.toml index e565ad85483..8d451d10df3 100644 --- a/keymanager-client/Cargo.toml +++ b/keymanager-client/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" oasis-core-client = { path = "../client" } oasis-core-runtime = { path = "../runtime" } oasis-core-keymanager-api-common = { path = "../keymanager-api-common" } -cbor = { version = "0.2.1", package = "oasis-cbor" } +cbor = { version = "0.3.0", package = "oasis-cbor" } # Third party. futures = "0.3.17" diff --git a/keymanager-lib/Cargo.toml b/keymanager-lib/Cargo.toml index 7f77e1badb1..94c7f1e84e7 100644 --- a/keymanager-lib/Cargo.toml +++ b/keymanager-lib/Cargo.toml @@ -8,7 +8,7 @@ edition = "2018" oasis-core-runtime = { path = "../runtime" } oasis-core-keymanager-api-common = { path = "../keymanager-api-common" } oasis-core-keymanager-client = { path = "../keymanager-client" } -cbor = { version = "0.2.1", package = "oasis-cbor" } +cbor = { version = "0.3.0", package = "oasis-cbor" } # Third party. anyhow = "1.0" diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 95e9736d87e..c67916318f1 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Oasis Protocol Foundation "] edition = "2018" [dependencies] -cbor = { version = "0.2.1", package = "oasis-cbor" } +cbor = { version = "0.3.0", package = "oasis-cbor" } # Third party. log = "0.4" diff --git a/runtime/src/common/bytes.rs b/runtime/src/common/bytes.rs index bbf1dec48c7..98737ccafb2 100644 --- a/runtime/src/common/bytes.rs +++ b/runtime/src/common/bytes.rs @@ -153,6 +153,10 @@ macro_rules! impl_bytes { // Deserialization. impl $crate::cbor::Decode for $name { + fn try_default() -> Result { + Ok(Default::default()) + } + fn try_from_cbor_value( value: $crate::cbor::Value, ) -> Result { @@ -201,4 +205,13 @@ mod tests { let new_test_key: TestKey = cbor::from_slice(&test_key_vec).unwrap(); assert_eq!(new_test_key, test_key); } + + #[test] + fn test_cbor_null() { + let test_key: TestKey = cbor::from_slice(&[0xF6]).unwrap(); + assert_eq!( + test_key, + "0000000000000000000000000000000000000000000000000000000000000000".into() + ); + } } diff --git a/runtime/src/common/quantity.rs b/runtime/src/common/quantity.rs index efa98009d9f..fe923a72f25 100644 --- a/runtime/src/common/quantity.rs +++ b/runtime/src/common/quantity.rs @@ -201,6 +201,10 @@ impl fmt::Display for Quantity { } impl cbor::Encode for Quantity { + fn is_empty(&self) -> bool { + self.0.is_zero() + } + fn into_cbor_value(self) -> cbor::Value { if self.0.is_zero() { cbor::Value::ByteString(vec![]) @@ -211,6 +215,10 @@ impl cbor::Encode for Quantity { } impl cbor::Decode for Quantity { + fn try_default() -> Result { + Ok(Default::default()) + } + fn try_from_cbor_value(value: cbor::Value) -> Result { match value { cbor::Value::ByteString(data) => Ok(Quantity(BigUint::from_bytes_be(&data))), diff --git a/runtime/src/common/sgx/avr.rs b/runtime/src/common/sgx/avr.rs index 82bfda36966..971a63de02b 100644 --- a/runtime/src/common/sgx/avr.rs +++ b/runtime/src/common/sgx/avr.rs @@ -158,7 +158,7 @@ impl QuoteBody { } /// Attestation verification report. -#[derive(Debug, Clone, cbor::Encode, cbor::Decode)] +#[derive(Debug, Default, Clone, cbor::Encode, cbor::Decode)] pub struct AVR { pub body: Vec, pub signature: Vec, @@ -481,20 +481,13 @@ pub(crate) fn timestamp_is_fresh(now: i64, timestamp: i64) -> bool { } /// Enclave identity. -#[derive(Debug, Clone, Hash, Eq, PartialEq, cbor::Encode, cbor::Decode)] +#[derive(Debug, Default, Clone, Hash, Eq, PartialEq, cbor::Encode, cbor::Decode)] pub struct EnclaveIdentity { pub mr_enclave: MrEnclave, pub mr_signer: MrSigner, } impl EnclaveIdentity { - pub fn default() -> Self { - Self { - mr_enclave: MrEnclave::default(), - mr_signer: MrSigner::default(), - } - } - pub fn current() -> Option { #[cfg(target_env = "sgx")] { diff --git a/runtime/src/common/version.rs b/runtime/src/common/version.rs index 85a0b68c1a1..4c243b59726 100644 --- a/runtime/src/common/version.rs +++ b/runtime/src/common/version.rs @@ -5,18 +5,12 @@ #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)] pub struct Version { #[cbor(optional)] - #[cbor(default)] - #[cbor(skip_serializing_if = "num_traits::Zero::is_zero")] pub major: u16, #[cbor(optional)] - #[cbor(default)] - #[cbor(skip_serializing_if = "num_traits::Zero::is_zero")] pub minor: u16, #[cbor(optional)] - #[cbor(default)] - #[cbor(skip_serializing_if = "num_traits::Zero::is_zero")] pub patch: u16, } diff --git a/runtime/src/consensus/address.rs b/runtime/src/consensus/address.rs index bbee9380646..ade1c21fa33 100644 --- a/runtime/src/consensus/address.rs +++ b/runtime/src/consensus/address.rs @@ -137,6 +137,10 @@ impl cbor::Encode for Address { } impl cbor::Decode for Address { + fn try_default() -> Result { + Ok(Default::default()) + } + fn try_from_cbor_value(value: cbor::Value) -> Result { match value { cbor::Value::ByteString(data) => Ok(Address( @@ -196,4 +200,13 @@ mod test { "oasis1qpllh99nhwzrd56px4txvl26atzgg4f3a58jzzad" ); } + + #[test] + fn test_deserialization() { + let addr: Address = cbor::from_slice(&[0xF6]).unwrap(); + assert_eq!( + addr.to_bech32(), + "oasis1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0ltrq9" + ); + } } diff --git a/runtime/src/consensus/mod.rs b/runtime/src/consensus/mod.rs index 9bc764cbabc..baccb7a589d 100644 --- a/runtime/src/consensus/mod.rs +++ b/runtime/src/consensus/mod.rs @@ -14,7 +14,7 @@ pub mod verifier; pub const HEIGHT_LATEST: u64 = 0; /// Light consensus block. -#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Default, Debug, cbor::Encode, cbor::Decode)] pub struct LightBlock { pub height: u64, pub meta: Vec, diff --git a/runtime/src/consensus/registry.rs b/runtime/src/consensus/registry.rs index da0d528858d..a469d2aed22 100644 --- a/runtime/src/consensus/registry.rs +++ b/runtime/src/consensus/registry.rs @@ -112,7 +112,7 @@ pub struct CapabilityTEE { #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)] pub struct Capabilities { /// Is the capability of a node executing batches in a TEE. - #[cbor(optional, default)] + #[cbor(optional)] pub tee: Option, } @@ -204,12 +204,12 @@ pub struct Node { pub consensus: ConsensusInfo, /// Information for this node's participation in VRF based elections. - #[cbor(optional, default)] + #[cbor(optional)] pub vrf: Option, /// Information for this node's participation in the old PVSS based random beacon protocol. /// Deprecated. - #[cbor(optional, default)] + #[cbor(optional)] pub beacon: Option, /// Node's runtimes. @@ -219,7 +219,7 @@ pub struct Node { pub roles: RolesMask, /// Node's oasis-node software version. - #[cbor(optional, default)] + #[cbor(optional)] pub software_version: Option, } @@ -279,15 +279,15 @@ pub struct ExecutorParameters { pub max_messages: u32, /// Minimum percentage of rounds in an epoch that a node must participate in positively in order /// to be considered live. Nodes not satisfying this may be penalized. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub min_live_rounds_percent: u8, /// Minimum number of live rounds in an epoch for the liveness calculations to be considered for /// evaluation. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub min_live_rounds_eval: u64, /// Maximum number of liveness failures that are tolerated before suspending and/or slashing the /// node. Zero means unlimited. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub max_liveness_fails: u8, } @@ -302,7 +302,7 @@ pub struct TxnSchedulerParameters { /// Maximum size of a scheduled batch in bytes. pub max_batch_size_bytes: u64, /// Maximum size of the incoming message queue. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub max_in_messages: u32, /// Timeout (in consensus blocks) for the scheduler to propose a batch. pub propose_batch_timeout: i64, @@ -360,25 +360,25 @@ pub struct RuntimeStakingParameters { /// In case a node is registered for multiple runtimes, it will need to /// satisfy the maximum threshold of all the runtimes. #[cbor(optional)] - pub thresholds: Option>, + pub thresholds: BTreeMap, /// Per-runtime misbehavior slashing parameters. #[cbor(optional)] - pub slashing: Option>, + pub slashing: BTreeMap, /// The percentage of the reward obtained when slashing for equivocation that is transferred to /// the runtime's account. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub reward_equivocation: u8, /// The percentage of the reward obtained when slashing for incorrect results that is /// transferred to the runtime's account. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub reward_bad_results: u8, /// Specifies the minimum fee that the incoming message must include for the /// message to be queued. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub min_in_message_fee: quantity::Quantity, } @@ -387,7 +387,7 @@ pub struct RuntimeStakingParameters { pub struct EntityWhitelistRuntimeAdmissionPolicy { /// Entity whitelist configuration for each whitelisted entity. #[cbor(optional)] - pub entities: Option>, + pub entities: BTreeMap, } /// Entity whitelist configuration. @@ -399,7 +399,7 @@ pub struct EntityWhitelistConfig { /// of nodes is restricted to the specified maximum (where zero /// means no nodes allowed), any missing roles imply zero nodes. #[cbor(optional)] - pub max_nodes: Option>, + pub max_nodes: BTreeMap, } /// Specification of which nodes are allowed to register for a runtime. @@ -448,7 +448,7 @@ pub struct VersionInfo { pub valid_from: EpochTime, /// Enclave version information, in an enclave provided specific format (if any). #[cbor(optional)] - pub tee: Option>, + pub tee: Vec, } /// TEE hardware implementation. @@ -487,37 +487,36 @@ pub struct Runtime { /// Runtime's TEE hardware requirements. pub tee_hardware: TEEHardware, /// Runtime deployment information. - #[cbor(optional, default, skip_serializing_if = "Vec::is_empty")] + #[cbor(optional)] pub deployments: Vec, /// Key manager runtime ID for this runtime. #[cbor(optional)] pub key_manager: Option, /// Parameters of the executor committee. - #[cbor(optional, default)] + #[cbor(optional)] pub executor: ExecutorParameters, /// Transaction scheduling parameters of the executor committee. - #[cbor(optional, default)] + #[cbor(optional)] pub txn_scheduler: TxnSchedulerParameters, /// Parameters of the storage committee. - #[cbor(optional, default)] + #[cbor(optional)] pub storage: StorageParameters, /// Which nodes are allowed to register for this runtime. pub admission_policy: RuntimeAdmissionPolicy, /// Node scheduling constraints. #[cbor(optional)] - pub constraints: Option< + pub constraints: BTreeMap>, - >, /// Runtime's staking-related parameters. - #[cbor(optional, default, skip_serializing_if = "staking_params_are_empty")] + #[cbor(optional, skip_serializing_if = "staking_params_are_empty")] pub staking: RuntimeStakingParameters, /// Runtime governance model. pub governance_model: RuntimeGovernanceModel, } fn staking_params_are_empty(p: &RuntimeStakingParameters) -> bool { - p.thresholds.is_none() - && p.slashing.is_none() + p.thresholds.is_empty() + && p.slashing.is_empty() && p.reward_equivocation == 0 && p.reward_bad_results == 0 && p.min_in_message_fee.is_zero() @@ -533,6 +532,7 @@ pub struct RuntimeGenesis { /// Runtime round in the genesis. pub round: u64, } + #[cfg(test)] mod tests { use std::net::Ipv4Addr; @@ -562,8 +562,8 @@ mod tests { ("q2F2AGJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABka2luZABnZ2VuZXNpc6Jlcm91bmQAanN0YXRlX3Jvb3RYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ3N0b3JhZ2Wjc2NoZWNrcG9pbnRfaW50ZXJ2YWwAc2NoZWNrcG9pbnRfbnVtX2tlcHQAdWNoZWNrcG9pbnRfY2h1bmtfc2l6ZQBoZXhlY3V0b3Klamdyb3VwX3NpemUAbG1heF9tZXNzYWdlcwBtcm91bmRfdGltZW91dABxZ3JvdXBfYmFja3VwX3NpemUAcmFsbG93ZWRfc3RyYWdnbGVycwBpZW50aXR5X2lkWCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGx0ZWVfaGFyZHdhcmUAbXR4bl9zY2hlZHVsZXKkbm1heF9iYXRjaF9zaXplAHNiYXRjaF9mbHVzaF90aW1lb3V0AHRtYXhfYmF0Y2hfc2l6ZV9ieXRlcwB1cHJvcG9zZV9iYXRjaF90aW1lb3V0AHBhZG1pc3Npb25fcG9saWN5oWhhbnlfbm9kZaBwZ292ZXJuYW5jZV9tb2RlbAA=", Runtime { staking: RuntimeStakingParameters { - thresholds: None, - slashing: None, + thresholds: BTreeMap::new(), + slashing: BTreeMap::new(), reward_equivocation: 0, reward_bad_results: 0, min_in_message_fee: Quantity::from(0u32), @@ -573,8 +573,8 @@ mod tests { ("rGF2AGJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABka2luZABnZ2VuZXNpc6Jlcm91bmQAanN0YXRlX3Jvb3RYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ3N0YWtpbmehcnJld2FyZF9iYWRfcmVzdWx0cwpnc3RvcmFnZaNzY2hlY2twb2ludF9pbnRlcnZhbABzY2hlY2twb2ludF9udW1fa2VwdAB1Y2hlY2twb2ludF9jaHVua19zaXplAGhleGVjdXRvcqVqZ3JvdXBfc2l6ZQBsbWF4X21lc3NhZ2VzAG1yb3VuZF90aW1lb3V0AHFncm91cF9iYWNrdXBfc2l6ZQByYWxsb3dlZF9zdHJhZ2dsZXJzAGllbnRpdHlfaWRYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbHRlZV9oYXJkd2FyZQBtdHhuX3NjaGVkdWxlcqRubWF4X2JhdGNoX3NpemUAc2JhdGNoX2ZsdXNoX3RpbWVvdXQAdG1heF9iYXRjaF9zaXplX2J5dGVzAHVwcm9wb3NlX2JhdGNoX3RpbWVvdXQAcGFkbWlzc2lvbl9wb2xpY3mhaGFueV9ub2RloHBnb3Zlcm5hbmNlX21vZGVsAA==", Runtime { staking: RuntimeStakingParameters { - thresholds: None, - slashing: None, + thresholds: BTreeMap::new(), + slashing: BTreeMap::new(), reward_equivocation: 0, reward_bad_results: 10, min_in_message_fee: Quantity::from(0u32), @@ -596,7 +596,7 @@ mod tests { VersionInfo{ version: Version { major: 44, minor: 0, patch: 1 }, valid_from: 0, - tee: Some(b"version tee".to_vec()), + tee: b"version tee".to_vec(), }, ], key_manager: Some( @@ -625,18 +625,17 @@ mod tests { checkpoint_chunk_size: 101, }, admission_policy: RuntimeAdmissionPolicy::EntityWhitelist(EntityWhitelistRuntimeAdmissionPolicy{ - entities: Some( + entities: btreemap! { PublicKey::from("1234567890000000000000000000000000000000000000000000000000000000") => EntityWhitelistConfig { - max_nodes: Some(btreemap! { + max_nodes: btreemap! { RolesMask::ROLE_COMPUTE_WORKER => 3, RolesMask::ROLE_KEY_MANAGER => 1, - }) + } } } - ) }), - constraints: Some( + constraints: btreemap! { scheduler::CommitteeKind::ComputeExecutor => btreemap! { scheduler::Role::Worker => SchedulingConstraints{ @@ -653,11 +652,10 @@ mod tests { validator_set: Some(ValidatorSetConstraint{}), }, } - } - ), + }, staking: RuntimeStakingParameters { - thresholds: None, - slashing: None, + thresholds: BTreeMap::new(), + slashing: BTreeMap::new(), reward_equivocation: 0, reward_bad_results: 10, min_in_message_fee: Quantity::from(0u32), @@ -678,7 +676,11 @@ mod tests { fn test_consistent_node() { // NOTE: These tests MUST be synced with go/common/node/node_test.go. let tcs = vec![ - ("qWF2AmJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjcDJwomJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpYWRkcmVzc2Vz9mN0bHOjZ3B1Yl9rZXlYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWFkZHJlc3Nlc/ZsbmV4dF9wdWJfa2V5WCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVyb2xlcwBocnVudGltZXP2aWNvbnNlbnN1c6JiaWRYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWFkZHJlc3Nlc/ZpZW50aXR5X2lkWCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpleHBpcmF0aW9uAA==", Node{v: 2, ..Default::default()}), + ( + "qWF2AmJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjcDJwomJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpYWRkcmVzc2Vz9mN0bHOjZ3B1Yl9rZXlYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWFkZHJlc3Nlc/ZsbmV4dF9wdWJfa2V5WCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVyb2xlcwBocnVudGltZXP2aWNvbnNlbnN1c6JiaWRYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWFkZHJlc3Nlc/ZpZW50aXR5X2lkWCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpleHBpcmF0aW9uAA==", + Node{v: 2, ..Default::default()}, + true, + ), ( "qmF2AmJpZFgg//////////////////////////////////////////BjcDJwomJpZFgg//////////////////////////////////////////VpYWRkcmVzc2Vz9mN0bHOjZ3B1Yl9rZXlYIP/////////////////////////////////////////yaWFkZHJlc3Nlc4GiZ2FkZHJlc3OjYklQUAAAAAAAAAAAAAD//38AAAFkUG9ydBkEV2Rab25lYGdwdWJfa2V5WCD/////////////////////////////////////////9GxuZXh0X3B1Yl9rZXlYIP/////////////////////////////////////////zY3ZyZqFiaWRYIP/////////////////////////////////////////3ZXJvbGVzAGhydW50aW1lc4KkYmlkWCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEGd2ZXJzaW9uoWVwYXRjaBkBQWpleHRyYV9pbmZv9mxjYXBhYmlsaXRpZXOgpGJpZFgggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABFndmVyc2lvbqFlcGF0Y2gYe2pleHRyYV9pbmZvRAUDAgFsY2FwYWJpbGl0aWVzoWN0ZWWjY3Jha1gg//////////////////////////////////////////hoaGFyZHdhcmUBa2F0dGVzdGF0aW9uRgABAgMEBWljb25zZW5zdXOiYmlkWCD/////////////////////////////////////////9mlhZGRyZXNzZXOAaWVudGl0eV9pZFgg//////////////////////////////////////////FqZXhwaXJhdGlvbhgg", Node{ @@ -732,14 +734,39 @@ mod tests { ]), ..Default::default() }, + true, + ), + ( + "qmF2AmJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjcDJwomJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpYWRkcmVzc2Vz9mN0bHOjZ3B1Yl9rZXlYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWFkZHJlc3Nlc/ZsbmV4dF9wdWJfa2V5WCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVyb2xlcwBocnVudGltZXP2aWNvbnNlbnN1c6JiaWRYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWFkZHJlc3Nlc/ZpZW50aXR5X2lkWCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGpleHBpcmF0aW9uAHBzb2Z0d2FyZV92ZXJzaW9u9g==", + Node{v: 2, ..Default::default()}, + false, + ), + ( + "qWF2AmJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABjcDJwomJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpYWRkcmVzc2Vz9mN0bHOjZ3B1Yl9rZXlYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaWFkZHJlc3Nlc/ZsbmV4dF9wdWJfa2V5WCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVyb2xlcwBocnVudGltZXOBomJpZFgggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBndmVyc2lvbvZpY29uc2Vuc3VzomJpZFggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpYWRkcmVzc2Vz9mllbnRpdHlfaWRYIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAamV4cGlyYXRpb24A", + Node{ + v: 2, + runtimes: Some(vec![ + NodeRuntime{ + id: Namespace::from("8000000000000000000000000000000000000000000000000000000000000010"), + version: Version::from(0u64), + ..Default::default() + }, + ]), + ..Default::default() + }, + false, ), ]; - for (encoded_base64, node) in tcs { + for (encoded_base64, node, round_trip) in tcs { + println!("{:?}", node); let dec: Node = cbor::from_slice(&base64::decode(encoded_base64).unwrap()) .expect("node should deserialize correctly"); assert_eq!(dec, node, "decoded node should match the expected value"); - let ser = base64::encode(cbor::to_vec(dec)); - assert_eq!(ser, encoded_base64, "node should serialize correctly"); + + if round_trip { + let ser = base64::encode(cbor::to_vec(dec)); + assert_eq!(ser, encoded_base64, "node should serialize correctly"); + } } } } diff --git a/runtime/src/consensus/roothash.rs b/runtime/src/consensus/roothash.rs index a52c1ceec7e..5d1d11224b3 100644 --- a/runtime/src/consensus/roothash.rs +++ b/runtime/src/consensus/roothash.rs @@ -109,19 +109,15 @@ pub enum RegistryMessage { #[derive(Clone, Debug, Default, PartialEq, Eq, cbor::Encode, cbor::Decode)] pub struct MessageEvent { #[cbor(optional)] - #[cbor(default)] pub module: String, #[cbor(optional)] - #[cbor(default)] pub code: u32, #[cbor(optional)] - #[cbor(default)] pub index: u32, #[cbor(optional)] - #[cbor(default)] pub result: Option, } @@ -141,18 +137,18 @@ pub struct IncomingMessage { pub caller: Address, /// An optional tag provided by the caller which is ignored and can be used to match processed /// incoming message events later. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub tag: u64, /// Fee sent into the runtime as part of the message being sent. The fee is transferred before /// the message is processed by the runtime. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub fee: Quantity, /// Tokens sent into the runtime as part of the message being sent. The tokens are transferred /// before the message is processed by the runtime. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub tokens: Quantity, /// Arbitrary runtime-dependent data. - #[cbor(optional, default, skip_serializing_if = "Vec::is_empty")] + #[cbor(optional)] pub data: Vec, } @@ -172,18 +168,15 @@ impl IncomingMessage { pub struct RoundResults { /// Results of executing emitted runtime messages. #[cbor(optional)] - #[cbor(default)] pub messages: Vec, /// Public keys of compute nodes' controlling entities that positively contributed to the round /// by replicating the computation correctly. #[cbor(optional)] - #[cbor(default)] pub good_compute_entities: Vec, /// Public keys of compute nodes' controlling entities that negatively contributed to the round /// by causing discrepancies. #[cbor(optional)] - #[cbor(default)] pub bad_compute_entities: Vec, } @@ -247,7 +240,7 @@ pub struct ComputeResultsHeader { #[cbor(optional)] pub in_msgs_hash: Option, /// The number of processed incoming messages. - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub in_msgs_count: u32, } @@ -333,9 +326,7 @@ mod tests { let mut wl = BTreeMap::new(); wl.insert( test_ent_id, - registry::EntityWhitelistConfig { - max_nodes: Some(wlc), - }, + registry::EntityWhitelistConfig { max_nodes: wlc }, ); let rt = registry::Runtime { @@ -371,7 +362,7 @@ mod tests { checkpoint_chunk_size: 0, }, admission_policy: registry::RuntimeAdmissionPolicy::EntityWhitelist( - registry::EntityWhitelistRuntimeAdmissionPolicy { entities: Some(wl) }, + registry::EntityWhitelistRuntimeAdmissionPolicy { entities: wl }, ), constraints: { let mut cs = BTreeMap::new(); @@ -395,10 +386,10 @@ mod tests { ce }); - Some(cs) + cs }, staking: registry::RuntimeStakingParameters { - thresholds: Some(st), + thresholds: st, ..Default::default() }, governance_model: registry::RuntimeGovernanceModel::GovernanceEntity, @@ -454,6 +445,7 @@ mod tests { ), ]; for (msgs, expected_hash) in tcs { + println!("{:?}", cbor::to_vec(msgs.clone())); assert_eq!(Message::messages_hash(&msgs), Hash::from(expected_hash)); } } diff --git a/runtime/src/consensus/staking.rs b/runtime/src/consensus/staking.rs index bd6e69a545f..d377c5897e8 100644 --- a/runtime/src/consensus/staking.rs +++ b/runtime/src/consensus/staking.rs @@ -61,11 +61,9 @@ pub enum ThresholdKind { #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)] pub struct Account { #[cbor(optional)] - #[cbor(default)] pub general: GeneralAccount, #[cbor(optional)] - #[cbor(default)] pub escrow: EscrowAccount, } @@ -73,34 +71,28 @@ pub struct Account { #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)] pub struct GeneralAccount { #[cbor(optional)] - #[cbor(default)] pub balance: Quantity, #[cbor(optional)] - #[cbor(default)] pub nonce: u64, #[cbor(optional)] - pub allowances: Option>, + pub allowances: BTreeMap, } /// Escrow account. #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)] pub struct EscrowAccount { #[cbor(optional)] - #[cbor(default)] pub active: SharePool, #[cbor(optional)] - #[cbor(default)] pub debonding: SharePool, #[cbor(optional)] - #[cbor(default)] pub commission_schedule: CommissionSchedule, #[cbor(optional)] - #[cbor(default)] pub stake_accumulator: StakeAccumulator, } @@ -108,11 +100,9 @@ pub struct EscrowAccount { #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)] pub struct SharePool { #[cbor(optional)] - #[cbor(default)] pub balance: Quantity, #[cbor(optional)] - #[cbor(default)] pub total_shares: Quantity, } @@ -120,10 +110,10 @@ pub struct SharePool { #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)] pub struct CommissionSchedule { #[cbor(optional)] - pub rates: Option>, + pub rates: Vec, #[cbor(optional)] - pub bounds: Option>, + pub bounds: Vec, } /// Commission rate and its starting time. @@ -137,15 +127,12 @@ pub struct CommissionRateStep { #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)] pub struct CommissionRateBoundStep { #[cbor(optional)] - #[cbor(default)] pub start: EpochTime, #[cbor(optional)] - #[cbor(default)] pub rate_min: Quantity, #[cbor(optional)] - #[cbor(default)] pub rate_max: Quantity, } @@ -153,7 +140,7 @@ pub struct CommissionRateBoundStep { #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, cbor::Encode, cbor::Decode)] pub struct StakeAccumulator { #[cbor(optional)] - pub claims: Option>>, + pub claims: BTreeMap>, } /// Unique stake claim identifier. @@ -165,8 +152,7 @@ pub struct StakeThreshold { #[cbor(optional)] pub global: Option, - #[cbor(rename = "const")] - #[cbor(optional)] + #[cbor(optional, rename = "const")] pub constant: Option, } @@ -270,10 +256,10 @@ mod tests { { Account { general: GeneralAccount { - allowances: Some([ + allowances: [ (COMMON_POOL_ADDRESS.clone(), Quantity::from(100u32)), (GOVERNANCE_DEPOSITS_ADDRESS.clone(), Quantity::from(33u32)) - ].iter().cloned().collect()), + ].iter().cloned().collect(), ..Default::default() }, ..Default::default() @@ -290,15 +276,15 @@ mod tests { }, debonding: SharePool::default(), commission_schedule: CommissionSchedule { - bounds: Some(vec![CommissionRateBoundStep{ + bounds: vec![CommissionRateBoundStep{ start: 33, rate_min: Quantity::from(10u32), rate_max: Quantity::from(1000u32), - }]), + }], ..Default::default() }, stake_accumulator: StakeAccumulator { - claims: Some([ + claims: [ ( "entity".to_string(), vec![ @@ -312,7 +298,7 @@ mod tests { }, ] ) - ].iter().cloned().collect()) + ].iter().cloned().collect() } }, ..Default::default() diff --git a/runtime/src/enclave_rpc/session.rs b/runtime/src/enclave_rpc/session.rs index 270c98f93e5..3b5e54a5aff 100644 --- a/runtime/src/enclave_rpc/session.rs +++ b/runtime/src/enclave_rpc/session.rs @@ -260,7 +260,7 @@ impl Session { /// * `rak_pub` contains the public part of RAK. /// * `binding` is signed by `rak_pub` and binds the session's static /// public key to RAK. -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Default, cbor::Encode, cbor::Decode)] pub struct RAKBinding { pub avr: avr::AVR, pub rak_pub: PublicKey, diff --git a/runtime/src/enclave_rpc/types.rs b/runtime/src/enclave_rpc/types.rs index fd2669ba432..3c208b4c21b 100644 --- a/runtime/src/enclave_rpc/types.rs +++ b/runtime/src/enclave_rpc/types.rs @@ -20,7 +20,7 @@ impl SessionID { } /// Frame. -#[derive(Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct Frame { pub session: SessionID, // The `untrusted_plaintext` field is only a temporary workaround until @@ -33,29 +33,31 @@ pub struct Frame { } #[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[cbor(no_default)] pub struct Request { pub method: String, pub args: cbor::Value, } -#[derive(Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct Error { pub message: String, } -#[derive(Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] pub enum Body { Success(cbor::Value), Error(String), } -#[derive(Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[cbor(no_default)] pub struct Response { pub body: Body, } /// Protocol message. -#[derive(Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] pub enum Message { Request(Request), Response(Response), diff --git a/runtime/src/storage/mkvs/interop/rpc.rs b/runtime/src/storage/mkvs/interop/rpc.rs index be384f8008a..d566a1eab28 100644 --- a/runtime/src/storage/mkvs/interop/rpc.rs +++ b/runtime/src/storage/mkvs/interop/rpc.rs @@ -13,7 +13,7 @@ use crate::{ // Calls should still have a timeout to handle the case where the interop server exits prematurely. const CALL_TIMEOUT: Duration = Duration::from_secs(30); -#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct ApplyRequest { pub namespace: Namespace, pub root_type: RootType, diff --git a/runtime/src/storage/mkvs/mod.rs b/runtime/src/storage/mkvs/mod.rs index cb39cc16509..31d10a2dcda 100644 --- a/runtime/src/storage/mkvs/mod.rs +++ b/runtime/src/storage/mkvs/mod.rs @@ -29,7 +29,7 @@ pub enum LogEntryKind { } /// An entry in the write log, describing a single update. -#[derive(Clone, Debug, Eq, PartialEq, Hash, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, cbor::Encode, cbor::Decode)] #[cbor(as_array)] pub struct LogEntry { /// The key that was inserted or deleted. diff --git a/runtime/src/storage/mkvs/sync/mod.rs b/runtime/src/storage/mkvs/sync/mod.rs index f445e011497..1fe6b1b0c80 100644 --- a/runtime/src/storage/mkvs/sync/mod.rs +++ b/runtime/src/storage/mkvs/sync/mod.rs @@ -39,7 +39,6 @@ pub struct GetRequest { pub tree: TreeID, pub key: Vec, #[cbor(optional)] - #[cbor(default)] pub include_siblings: bool, } diff --git a/runtime/src/transaction/tree.rs b/runtime/src/transaction/tree.rs index c3c098305be..f5933cb933d 100644 --- a/runtime/src/transaction/tree.rs +++ b/runtime/src/transaction/tree.rs @@ -101,7 +101,7 @@ impl KeyFormat for TagKeyFormat { /// The input transaction artifacts. /// /// These are the artifacts that are stored CBOR-serialized in the Merkle tree. -#[derive(Clone, Debug, PartialEq, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, PartialEq, cbor::Encode, cbor::Decode)] #[cbor(as_array)] struct InputArtifacts { /// Transaction input. @@ -117,7 +117,7 @@ struct InputArtifacts { /// The output transaction artifacts. /// /// These are the artifacts that are stored CBOR-serialized in the Merkle tree. -#[derive(Clone, Debug, PartialEq, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, PartialEq, cbor::Encode, cbor::Decode)] #[cbor(as_array)] struct OutputArtifacts { /// Transaction output. diff --git a/runtime/src/types.rs b/runtime/src/types.rs index fa59d3b1766..bee10a55254 100644 --- a/runtime/src/types.rs +++ b/runtime/src/types.rs @@ -24,7 +24,7 @@ use crate::{ }; /// Computed batch. -#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct ComputedBatch { /// Compute results header. pub header: ComputeResultsHeader, @@ -153,14 +153,14 @@ pub enum Body { results: Vec, }, RuntimeExecuteTxBatchRequest { - #[cbor(optional, default)] + #[cbor(optional)] mode: ExecutionMode, consensus_block: LightBlock, round_results: roothash::RoundResults, io_root: Hash, #[cbor(optional)] inputs: Option, - #[cbor(optional, default)] + #[cbor(optional)] in_msgs: Vec, block: Block, epoch: EpochTime, @@ -184,11 +184,11 @@ pub enum Body { epoch: EpochTime, max_messages: u32, method: String, - #[cbor(optional, default)] + #[cbor(optional)] args: Vec, }, RuntimeQueryResponse { - #[cbor(optional, default)] + #[cbor(optional)] data: Vec, }, RuntimeConsensusSyncRequest { @@ -236,20 +236,23 @@ pub enum Body { }, } +impl Default for Body { + fn default() -> Self { + Self::Empty {} + } +} + /// A serializable error. #[derive(Clone, Debug, Default, Error, cbor::Encode, cbor::Decode)] #[error("module: {module} code: {code} message: {message}")] pub struct Error { #[cbor(optional)] - #[cbor(default)] pub module: String, #[cbor(optional)] - #[cbor(default)] pub code: u32, #[cbor(optional)] - #[cbor(default)] pub message: String, } @@ -275,7 +278,7 @@ impl From for Error { } /// Runtime information request. -#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct RuntimeInfoRequest { pub runtime_id: Namespace, pub consensus_backend: String, @@ -283,8 +286,6 @@ pub struct RuntimeInfoRequest { pub consensus_chain_context: String, #[cbor(optional)] - #[cbor(default)] - #[cbor(skip_serializing_if = "BTreeMap::is_empty")] pub local_config: BTreeMap, } @@ -292,21 +293,21 @@ pub struct RuntimeInfoRequest { #[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct Features { /// Schedule control feature. - #[cbor(optional, default)] + #[cbor(optional)] pub schedule_control: Option, } /// A feature specifying that the runtime supports controlling the scheduling of batches. This means /// that the scheduler should only take priority into account and ignore weights, leaving it up to /// the runtime to decide which transactions to include. -#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct FeatureScheduleControl { /// Size of the initial batch of transactions. pub initial_batch_size: u32, } /// Runtime information response. -#[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct RuntimeInfoResponse { /// The runtime protocol version supported by the runtime. pub protocol_version: Version, @@ -315,12 +316,13 @@ pub struct RuntimeInfoResponse { pub runtime_version: Version, /// Describes the features supported by the runtime. - #[cbor(optional, default)] + #[cbor(optional)] pub features: Option, } /// Batch execution mode. #[derive(Clone, Debug, PartialEq, Eq, cbor::Encode, cbor::Decode)] +#[cbor(with_default)] pub enum ExecutionMode { /// Execution mode where the batch of transactions is executed as-is without the ability to /// perform and modifications to the batch. @@ -350,12 +352,12 @@ pub struct CheckTxResult { /// CheckTx transaction metadata. #[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct CheckTxMetadata { - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub priority: u64, - #[cbor(optional, default, skip_serializing_if = "Vec::is_empty")] + #[cbor(optional)] pub sender: Vec, - #[cbor(optional, default, skip_serializing_if = "num_traits::Zero::is_zero")] + #[cbor(optional)] pub sender_seq: u64, } @@ -370,8 +372,14 @@ pub enum MessageType { Response = 2, } +impl Default for MessageType { + fn default() -> Self { + Self::Invalid + } +} + /// Runtime protocol message. -#[derive(Debug, cbor::Encode, cbor::Decode)] +#[derive(Debug, Default, cbor::Encode, cbor::Decode)] pub struct Message { /// Unique request identifier. pub id: u64, diff --git a/tests/runtimes/simple-keyvalue/Cargo.toml b/tests/runtimes/simple-keyvalue/Cargo.toml index 9bfc6208dd4..329c4f2dfad 100644 --- a/tests/runtimes/simple-keyvalue/Cargo.toml +++ b/tests/runtimes/simple-keyvalue/Cargo.toml @@ -20,7 +20,7 @@ stack-size = 2097152 threads = 6 [dependencies] -cbor = { version = "0.2.0", package = "oasis-cbor" } +cbor = { version = "0.3.0", package = "oasis-cbor" } oasis-core-runtime = { path = "../../../runtime" } oasis-core-client = { path = "../../../client" } oasis-core-keymanager-client = { path = "../../../keymanager-client" } diff --git a/tests/runtimes/simple-keyvalue/src/types.rs b/tests/runtimes/simple-keyvalue/src/types.rs index 2b4ae5521c2..d6bf6dd2704 100644 --- a/tests/runtimes/simple-keyvalue/src/types.rs +++ b/tests/runtimes/simple-keyvalue/src/types.rs @@ -10,6 +10,7 @@ use oasis_core_runtime::{ /// Test transaction call. #[derive(Clone, Debug, cbor::Encode, cbor::Decode)] +#[cbor(no_default)] pub struct Call { /// Nonce. pub nonce: u64, @@ -28,38 +29,38 @@ pub enum CallOutput { Error(String), } -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct Key { pub key: String, } -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct KeyValue { pub key: String, pub value: String, } -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct Withdraw { pub withdraw: staking::Withdraw, } -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct Transfer { pub transfer: staking::Transfer, } -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct AddEscrow { pub escrow: staking::Escrow, } -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct ReclaimEscrow { pub reclaim_escrow: staking::ReclaimEscrow, } -#[derive(Clone, cbor::Encode, cbor::Decode)] +#[derive(Clone, Debug, Default, cbor::Encode, cbor::Decode)] pub struct UpdateRuntime { pub update_runtime: registry::Runtime, }