standarised ContractBuildInformation and added it to all contracts

This commit is contained in:
Jędrzej Stuczyński
2024-06-06 15:53:07 +01:00
parent 5745cb4d7a
commit c50c30ae76
28 changed files with 265 additions and 245 deletions
Generated
+7 -2
View File
@@ -4337,10 +4337,12 @@ dependencies = [
"bs58 0.5.1",
"cosmwasm-schema",
"cosmwasm-std",
"cw-storage-plus",
"schemars",
"serde",
"serde_json",
"thiserror",
"vergen",
]
[[package]]
@@ -9213,11 +9215,14 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vergen"
version = "8.2.6"
version = "8.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1290fd64cc4e7d3c9b07d7f333ce0ce0007253e32870e632624835cc80b83939"
checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525"
dependencies = [
"anyhow",
"cargo_metadata",
"cfg-if",
"regex",
"rustc_version 0.4.0",
"rustversion",
"time",
+1 -1
View File
@@ -289,7 +289,7 @@ tungstenite = { version = "0.20.1", default-features = false }
url = "2.4"
utoipa = "4.2.0"
utoipa-swagger-ui = "6.0.0"
vergen = { version = "=8.2.6", default-features = false }
vergen = { version = "=8.3.1", default-features = false }
walkdir = "2"
wasm-bindgen-test = "0.3.36"
zeroize = "1.6.0"
@@ -70,6 +70,8 @@ use crate::http_client;
use crate::{DirectSigningHttpRpcNyxdClient, QueryHttpRpcNyxdClient};
#[cfg(feature = "http-client")]
use cosmrs::rpc::{HttpClient, HttpClientUrl};
use nym_contracts_common::build_information::CONTRACT_BUILD_INFO_STORAGE_KEY;
use nym_contracts_common::ContractBuildInformation;
pub mod coin;
pub mod contract_traits;
@@ -328,6 +330,31 @@ where
.await
.map(|block| block.block_id.hash)
}
pub async fn get_cw2_contract_version(
&self,
contract_address: &AccountId,
) -> Result<Option<cw2::ContractVersion>, NyxdError> {
let raw_info = self
.query_contract_raw(contract_address, b"contract_info".to_vec())
.await?;
Ok(serde_json::from_slice(&raw_info).ok())
}
pub async fn get_contract_build_information(
&self,
contract_address: &AccountId,
) -> Result<Option<ContractBuildInformation>, NyxdError> {
let raw_info = self
.query_contract_raw(
contract_address,
CONTRACT_BUILD_INFO_STORAGE_KEY.as_bytes().to_vec(),
)
.await?;
Ok(serde_json::from_slice(&raw_info).ok())
}
}
// signing
@@ -11,9 +11,13 @@ repository = { workspace = true }
bs58 = { workspace = true }
cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
cw-storage-plus = { workspace = true }
schemars = { workspace = true }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
[dev-dependencies]
serde_json = { workspace = true }
[build-dependencies]
vergen = { version = "=8.3.1", features = ["build", "git", "gitcl", "rustc", "cargo"] }
@@ -0,0 +1,17 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::EmitBuilder;
fn main() {
EmitBuilder::builder()
.all_build()
.rustc_semver()
.git_branch()
.git_commit_timestamp()
.git_sha(false)
.cargo_debug()
.cargo_opt_level()
.emit()
.expect("failed to extract build metadata");
}
@@ -0,0 +1,85 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::ContractBuildInformation;
use cosmwasm_std::{StdResult, Storage};
use cw_storage_plus::Item;
pub const CONTRACT_BUILD_INFO_STORAGE_KEY: &str = "contract_build_info";
pub const CONTRACT_BUILD_INFO: Item<ContractBuildInformation> =
Item::new(CONTRACT_BUILD_INFO_STORAGE_KEY);
// important note. this MUST BE called inside the contract code itself and not any intermediate crate
// otherwise macro expansions will resolve to incorrect data
#[macro_export]
macro_rules! get_build_information {
() => {
$crate::types::ContractBuildInformation::new(
env!("CARGO_PKG_NAME"),
env!("CARGO_PKG_VERSION"),
)
};
}
pub fn set_state_build_information(
store: &mut dyn Storage,
build_info: ContractBuildInformation,
) -> StdResult<()> {
CONTRACT_BUILD_INFO.save(store, &build_info)
}
pub fn get_contract_build_information(store: &dyn Storage) -> StdResult<ContractBuildInformation> {
CONTRACT_BUILD_INFO.load(store)
}
#[macro_export]
macro_rules! set_build_information {
( $store:expr ) => {
$crate::build_information::set_state_build_information(
$store,
$crate::get_build_information!(),
)
};
}
#[cfg(test)]
mod tests {
use super::*;
use cosmwasm_std::testing::MockStorage;
#[test]
fn get_and_set_work() {
let mut store = MockStorage::new();
// error if not set
assert!(get_contract_build_information(&store).is_err());
// set and get
let contract_name = "nym-mixnet-contract";
let contract_version = "1.2.3";
let build_info = ContractBuildInformation::new(contract_name, contract_version);
set_state_build_information(&mut store, build_info).unwrap();
let loaded = get_contract_build_information(&store).unwrap();
let expected = ContractBuildInformation {
contract_name: contract_name.into(),
build_version: contract_version.into(),
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP").to_string(),
commit_sha: option_env!("VERGEN_GIT_SHA")
.unwrap_or("UNKNOWN")
.to_string(),
commit_timestamp: option_env!("VERGEN_GIT_COMMIT_TIMESTAMP")
.unwrap_or("UNKNOWN")
.to_string(),
commit_branch: option_env!("VERGEN_GIT_BRANCH")
.unwrap_or("UNKNOWN")
.to_string(),
rustc_version: env!("VERGEN_RUSTC_SEMVER").to_string(),
cargo_debug: env!("VERGEN_CARGO_DEBUG").to_string(),
cargo_opt_level: env!("VERGEN_CARGO_OPT_LEVEL").to_string(),
};
assert_eq!(expected, loaded);
}
}
@@ -4,6 +4,7 @@
#![warn(clippy::expect_used)]
#![warn(clippy::unwrap_used)]
pub mod build_information;
pub mod dealings;
pub mod events;
pub mod signing;
@@ -132,10 +132,18 @@ where
}
}
fn default_unknown() -> String {
"unknown".to_string()
}
// TODO: there's no reason this couldn't be used for proper binaries, but in that case
// perhaps the struct should get renamed and moved to a "more" common crate
#[cw_serde]
pub struct ContractBuildInformation {
/// Provides the name of the binary, i.e. the content of `CARGO_PKG_NAME` environmental variable.
#[serde(default = "default_unknown")]
pub contract_name: String,
// VERGEN_BUILD_TIMESTAMP
/// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.
pub build_timestamp: String,
@@ -159,6 +167,38 @@ pub struct ContractBuildInformation {
// VERGEN_RUSTC_SEMVER
/// Provides the rustc version that was used for the build, for example `1.52.0-nightly`.
pub rustc_version: String,
// VERGEN_CARGO_DEBUG
/// Provides the cargo debug mode that was used for the build.
#[serde(default = "default_unknown")]
pub cargo_debug: String,
// VERGEN_CARGO_OPT_LEVEL
/// Provides the opt value set by cargo during the build
#[serde(default = "default_unknown")]
pub cargo_opt_level: String,
}
impl ContractBuildInformation {
pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
ContractBuildInformation {
contract_name: name.into(),
build_version: version.into(),
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP").to_string(),
commit_sha: option_env!("VERGEN_GIT_SHA")
.unwrap_or("UNKNOWN")
.to_string(),
commit_timestamp: option_env!("VERGEN_GIT_COMMIT_TIMESTAMP")
.unwrap_or("UNKNOWN")
.to_string(),
commit_branch: option_env!("VERGEN_GIT_BRANCH")
.unwrap_or("UNKNOWN")
.to_string(),
rustc_version: env!("VERGEN_RUSTC_SEMVER").to_string(),
cargo_debug: env!("VERGEN_CARGO_DEBUG").to_string(),
cargo_opt_level: env!("VERGEN_CARGO_OPT_LEVEL").to_string(),
}
}
}
#[cfg(test)]
@@ -234,12 +234,6 @@ pub enum MixnetContractError {
#[error("the epoch is currently not in the 'epoch advancement' state. (the state is {current_state})")]
EpochNotInAdvancementState { current_state: EpochState },
#[error("failed to parse {value} into a valid SemVer version: {error_message}")]
SemVerFailure {
value: String,
error_message: String,
},
#[error("failed to verify message signature: {source}")]
SignatureVerificationFailure {
#[from]
+1 -1
View File
@@ -14,6 +14,7 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
nym-coconut-dkg-common = { path = "../../common/cosmwasm-smart-contracts/coconut-dkg" }
nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common" }
cosmwasm-schema = { workspace = true, optional = true }
cosmwasm-std = { workspace = true }
@@ -23,7 +24,6 @@ cw-controllers = { workspace = true }
cw2 = { workspace = true }
cw4 = { workspace = true }
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
semver = { workspace = true, default-features = false }
thiserror = { workspace = true }
[dev-dependencies]
+4 -20
View File
@@ -30,7 +30,7 @@ use cosmwasm_std::{
use cw4::Cw4Contract;
use nym_coconut_dkg_common::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
use nym_coconut_dkg_common::types::{Epoch, EpochState, State};
use semver::Version;
use nym_contracts_common::set_build_information;
const CONTRACT_NAME: &str = "crate:nym-coconut-dkg";
const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION");
@@ -77,6 +77,7 @@ pub fn instantiate(
)?;
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
set_build_information!(deps.storage)?;
Ok(Response::default())
}
@@ -213,25 +214,8 @@ pub fn query(deps: Deps<'_>, env: Env, msg: QueryMsg) -> Result<QueryResponse, C
#[entry_point]
pub fn migrate(deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
fn parse_semver(raw: &str) -> Result<Version, ContractError> {
raw.parse()
.map_err(|error: semver::Error| ContractError::SemVerFailure {
value: CONTRACT_VERSION.to_string(),
error_message: error.to_string(),
})
}
// Note: don't remove this particular bit of code as we have to ALWAYS check whether we have to
// update the stored version
let build_version: Version = parse_semver(CONTRACT_VERSION)?;
let stored_version: Version = parse_semver(&cw2::get_contract_version(deps.storage)?.version)?;
if stored_version < build_version {
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
// If state structure changed in any contract version in the way migration is needed, it
// should occur here, for example anything from `crate::queued_migrations::`
}
set_build_information!(deps.storage)?;
cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
Ok(Response::new())
}
-6
View File
@@ -128,12 +128,6 @@ pub enum ContractError {
#[error("No verification key committed for owner {owner}")]
NoCommitForOwner { owner: String },
#[error("failed to parse {value} into a valid SemVer version: {error_message}")]
SemVerFailure {
value: String,
error_message: String,
},
#[error("cannot perform DKG reset during an ongoing exchange")]
CantResetDuringExchange,
+4 -8
View File
@@ -9,10 +9,10 @@ repository = { workspace = true }
readme = "README.md"
exclude = [
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
"contract.wasm",
"hash.txt",
"artifacts",
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
"contract.wasm",
"hash.txt",
"artifacts",
]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -41,15 +41,11 @@ bs58 = { workspace = true }
serde = { workspace = true, default-features = false, features = ["derive"] }
thiserror = { workspace = true }
time = { version = "0.3", features = ["macros"] }
semver = { workspace = true, default-features = false }
[dev-dependencies]
rand_chacha = "0.3"
nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] }
[build-dependencies]
vergen = { version = "=7.4.3", default-features = false, features = ["build", "git", "rustc"] }
[features]
default = []
contract-testing = ["mixnet-contract-common/contract-testing"]
-13
View File
@@ -1,13 +0,0 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::{vergen, Config};
fn main() {
let mut config = Config::default();
if std::env::var("DOCS_RS").is_ok() {
// If we don't have access to git information, such as in a docs.rs build, don't error
*config.git_mut().skip_if_error_mut() = true;
}
vergen(config).expect("failed to extract build metadata");
}
+4 -24
View File
@@ -13,7 +13,7 @@ use mixnet_contract_common::error::MixnetContractError;
use mixnet_contract_common::{
ContractState, ContractStateParams, ExecuteMsg, InstantiateMsg, Interval, MigrateMsg, QueryMsg,
};
use semver::Version;
use nym_contracts_common::set_build_information;
// version info for migration info
const CONTRACT_NAME: &str = "crate:nym-mixnet-contract";
@@ -87,6 +87,7 @@ pub fn instantiate(
mixnode_storage::initialise_storage(deps.storage)?;
rewards_storage::initialise_storage(deps.storage, reward_params)?;
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
set_build_information!(deps.storage)?;
Ok(Response::default())
}
@@ -610,29 +611,8 @@ pub fn migrate(
_env: Env,
msg: MigrateMsg,
) -> Result<Response, MixnetContractError> {
// note: don't remove this particular bit of code as we have to ALWAYS check whether we have to update the stored version
let version: Version = CONTRACT_VERSION.parse().map_err(|error: semver::Error| {
MixnetContractError::SemVerFailure {
value: CONTRACT_VERSION.to_string(),
error_message: error.to_string(),
}
})?;
let storage_version_raw = cw2::get_contract_version(deps.storage)?.version;
let storage_version: Version =
storage_version_raw
.parse()
.map_err(|error: semver::Error| MixnetContractError::SemVerFailure {
value: storage_version_raw,
error_message: error.to_string(),
})?;
if storage_version < version {
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
// If state structure changed in any contract version in the way migration is needed, it
// should occur here, for example anything from `crate::queued_migrations::`
}
set_build_information!(deps.storage)?;
cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
// due to circular dependency on contract addresses (i.e. mixnet contract requiring vesting contract address
// and vesting contract requiring the mixnet contract address), if we ever want to deploy any new fresh
@@ -4,6 +4,7 @@
use super::storage;
use cosmwasm_std::{Deps, StdResult};
use mixnet_contract_common::{ContractBuildInformation, ContractState, ContractStateParams};
use nym_contracts_common::get_build_information;
pub(crate) fn query_contract_state(deps: Deps<'_>) -> StdResult<ContractState> {
storage::CONTRACT_STATE.load(deps.storage)
@@ -22,21 +23,7 @@ pub(crate) fn query_rewarding_validator_address(deps: Deps<'_>) -> StdResult<Str
}
pub(crate) fn query_contract_version() -> ContractBuildInformation {
// as per docs
// env! macro will expand to the value of the named environment variable at
// compile time, yielding an expression of type `&'static str`
ContractBuildInformation {
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP").to_string(),
build_version: env!("VERGEN_BUILD_SEMVER").to_string(),
commit_sha: option_env!("VERGEN_GIT_SHA").unwrap_or("NONE").to_string(),
commit_timestamp: option_env!("VERGEN_GIT_COMMIT_TIMESTAMP")
.unwrap_or("NONE")
.to_string(),
commit_branch: option_env!("VERGEN_GIT_BRANCH")
.unwrap_or("NONE")
.to_string(),
rustc_version: env!("VERGEN_RUSTC_SEMVER").to_string(),
}
get_build_information!()
}
#[cfg(test)]
@@ -34,7 +34,8 @@ cosmwasm-schema = { workspace = true, optional = true }
cosmwasm-std = { workspace = true }
nym-group-contract-common = { path = "../../../common/cosmwasm-smart-contracts/group-contract" }
nym-multisig-contract-common = { path= "../../../common/cosmwasm-smart-contracts/multisig-contract" }
nym-multisig-contract-common = { path = "../../../common/cosmwasm-smart-contracts/multisig-contract" }
nym-contracts-common = { path = "../../../common/cosmwasm-smart-contracts/contracts-common" }
[dev-dependencies]
cw4-group = { path = "../cw4-group", version = "1.0.0" }
@@ -17,6 +17,7 @@ use cw3_fixed_multisig::state::{next_id, BALLOTS, PROPOSALS};
use cw4::{Cw4Contract, MemberChangedHookMsg, MemberDiff};
use cw_storage_plus::Bound;
use cw_utils::{maybe_addr, Expiration, ThresholdResponse};
use nym_contracts_common::set_build_information;
use nym_multisig_contract_common::error::ContractError;
use nym_multisig_contract_common::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg};
@@ -53,6 +54,7 @@ pub fn instantiate(
.transpose()?;
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
set_build_information!(deps.storage)?;
let cfg = Config {
threshold: msg.threshold,
@@ -488,6 +490,9 @@ fn list_voters(
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(deps: DepsMut<'_>, _env: Env, msg: MigrateMsg) -> Result<Response, ContractError> {
set_build_information!(deps.storage)?;
cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
let mut cfg = CONFIG.load(deps.storage)?;
cfg.coconut_bandwidth_addr = deps.api.addr_validate(&msg.coconut_bandwidth_address)?;
cfg.coconut_dkg_addr = deps.api.addr_validate(&msg.coconut_dkg_address)?;
+3 -2
View File
@@ -10,8 +10,8 @@ homepage = "https://cosmwasm.com"
documentation = "https://docs.cosmwasm.com"
exclude = [
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
"artifacts/*",
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
"artifacts/*",
]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -31,6 +31,7 @@ library = []
[dependencies]
nym-group-contract-common = { path = "../../../common/cosmwasm-smart-contracts/group-contract" }
nym-contracts-common = { path = "../../../common/cosmwasm-smart-contracts/contracts-common" }
cw-utils = { workspace = true }
cw2 = { workspace = true }
+7 -1
View File
@@ -11,6 +11,7 @@ use cw4::{
};
use cw_storage_plus::Bound;
use cw_utils::maybe_addr;
use nym_contracts_common::set_build_information;
use crate::error::ContractError;
use crate::helpers::validate_unique_members;
@@ -31,6 +32,8 @@ pub fn instantiate(
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
set_build_information!(deps.storage)?;
create(deps, msg.admin, msg.members, env.block.height)?;
Ok(Response::default())
}
@@ -221,6 +224,9 @@ pub fn query_list_members(
}
#[cfg_attr(not(feature = "library"), entry_point)]
pub fn migrate(_deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
pub fn migrate(deps: DepsMut<'_>, _env: Env, _msg: MigrateMsg) -> Result<Response, ContractError> {
set_build_information!(deps.storage)?;
cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
Ok(Default::default())
}
-4
View File
@@ -20,13 +20,9 @@ cw-utils = { workspace = true }
cw2 = { workspace = true }
nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common", version = "0.5.0" }
nym-name-service-common = { path = "../../common/cosmwasm-smart-contracts/name-service" }
semver = { workspace = true, default-features = false }
serde = { version = "1.0.155", default-features = false, features = ["derive"] }
thiserror = { workspace = true }
[build-dependencies]
vergen = { version = "=7.4.3", default-features = false, features = ["build", "git", "rustc"] }
[dev-dependencies]
anyhow = "1.0.40"
cw-multi-test = { workspace = true }
@@ -20,13 +20,9 @@ cw-utils = { workspace = true }
cw2 = { workspace = true }
nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common", version = "0.5.0" }
nym-service-provider-directory-common = { path = "../../common/cosmwasm-smart-contracts/service-provider-directory" }
semver = { workspace = true, default-features = false }
serde = { version = "1.0.155", default-features = false, features = ["derive"] }
thiserror = { workspace = true }
[build-dependencies]
vergen = { version = "=7.4.3", default-features = false, features = ["build", "git", "rustc"] }
[dev-dependencies]
anyhow = "1.0.40"
cw-multi-test = { workspace = true }
+5 -8
View File
@@ -9,10 +9,10 @@ repository = { workspace = true }
readme = "README.md"
exclude = [
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
"contract.wasm",
"hash.txt",
"artifacts",
# Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication.
"contract.wasm",
"hash.txt",
"artifacts",
]
[[bin]]
@@ -35,8 +35,7 @@ cw2 = { workspace = true }
cw-storage-plus = { workspace = true, features = ["iterator"] }
serde = { version = "1.0", default-features = false, features = ["derive"] }
thiserror ={ workspace = true }
semver = { workspace = true, default-features = false }
thiserror = { workspace = true }
[dev-dependencies]
rand_chacha = "0.3.1"
@@ -45,8 +44,6 @@ hex = "0.4.3"
serde_json = "1.0.66"
cosmwasm-crypto = { workspace = true }
[build-dependencies]
vergen = { version = "=7.4.3", default-features = false, features = ["build", "git", "rustc"] }
[features]
schema-gen = ["vesting-contract-common/schema", "cosmwasm-schema"]
-13
View File
@@ -1,13 +0,0 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::{vergen, Config};
fn main() {
let mut config = Config::default();
if std::env::var("DOCS_RS").is_ok() {
// If we don't have access to git information, such as in a docs.rs build, don't error
*config.git_mut().skip_if_error_mut() = true;
}
vergen(config).expect("failed to extract build metadata")
}
+4 -24
View File
@@ -1,11 +1,11 @@
pub use crate::queries::*;
use crate::storage::{ADMIN, MIXNET_CONTRACT_ADDRESS, MIX_DENOM};
pub use crate::transactions::*;
use contracts_common::set_build_information;
use cosmwasm_std::{
entry_point, to_binary, Addr, Coin, Deps, DepsMut, Env, MessageInfo, QueryResponse, Response,
Uint128,
};
use semver::Version;
use vesting_contract_common::messages::{ExecuteMsg, InitMsg, MigrateMsg, QueryMsg};
use vesting_contract_common::{Account, VestingContractError};
@@ -45,6 +45,7 @@ pub fn instantiate(
MIX_DENOM.save(deps.storage, &msg.mix_denom)?;
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
set_build_information!(deps.storage)?;
Ok(Response::default())
}
@@ -55,29 +56,8 @@ pub fn migrate(
_env: Env,
_msg: MigrateMsg,
) -> Result<Response, VestingContractError> {
// note: don't remove this particular bit of code as we have to ALWAYS check whether we have to update the stored version
let version: Version = CONTRACT_VERSION.parse().map_err(|error: semver::Error| {
VestingContractError::SemVerFailure {
value: CONTRACT_VERSION.to_string(),
error_message: error.to_string(),
}
})?;
let storage_version_raw = cw2::get_contract_version(deps.storage)?.version;
let storage_version: Version =
storage_version_raw
.parse()
.map_err(|error: semver::Error| VestingContractError::SemVerFailure {
value: storage_version_raw,
error_message: error.to_string(),
})?;
if storage_version < version {
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
// If state structure changed in any contract version in the way migration is needed, it
// should occur here, for example anything from `crate::queued_migrations::`
}
set_build_information!(deps.storage)?;
cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
Ok(Response::new())
}
+2 -16
View File
@@ -5,7 +5,7 @@ use crate::storage;
use crate::storage::{account_from_address, BlockTimestampSecs, ACCOUNTS, DELEGATIONS, MIX_DENOM};
use crate::traits::VestingAccount;
use crate::vesting::StorableVestingAccountExt;
use contracts_common::ContractBuildInformation;
use contracts_common::{get_build_information, ContractBuildInformation};
use cosmwasm_std::{Coin, Deps, Env, Order, StdResult, Timestamp, Uint128};
use cw_storage_plus::Bound;
use mixnet_contract_common::MixId;
@@ -49,21 +49,7 @@ pub fn try_get_account(address: &str, deps: Deps<'_>) -> Result<Account, Vesting
/// Gets build information of this contract.
pub fn get_contract_version() -> ContractBuildInformation {
// as per docs
// env! macro will expand to the value of the named environment variable at
// compile time, yielding an expression of type `&'static str`
ContractBuildInformation {
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP").to_string(),
build_version: env!("VERGEN_BUILD_SEMVER").to_string(),
commit_sha: option_env!("VERGEN_GIT_SHA").unwrap_or("NONE").to_string(),
commit_timestamp: option_env!("VERGEN_GIT_COMMIT_TIMESTAMP")
.unwrap_or("NONE")
.to_string(),
commit_branch: option_env!("VERGEN_GIT_BRANCH")
.unwrap_or("NONE")
.to_string(),
rustc_version: env!("VERGEN_RUSTC_SEMVER").to_string(),
}
get_build_information!()
}
pub fn try_get_all_accounts(
+39 -74
View File
@@ -6,13 +6,11 @@ use crate::nym_contract_cache::cache::data::{CachedContractInfo, CachedContracts
use crate::nyxd::Client;
use crate::support::caching::CacheNotification;
use anyhow::Result;
use futures::future::join_all;
use nym_mixnet_contract_common::{MixId, MixNodeDetails, RewardedSetNodeStatus};
use nym_task::TaskClient;
use nym_validator_client::nyxd::contract_traits::{
MixnetQueryClient, NymContractsProvider, VestingQueryClient,
};
use nym_validator_client::nyxd::CosmWasmClient;
use std::{collections::HashMap, sync::atomic::Ordering, time::Duration};
use tokio::sync::watch;
use tokio::time;
@@ -59,81 +57,48 @@ impl NymContractCacheRefresher {
let group = query_guard!(client_guard, group_contract_address());
let multisig = query_guard!(client_guard, multisig_contract_address());
// get cw2 versions
let mixnet_cw2_future = query_guard!(client_guard, get_mixnet_contract_cw2_version());
let vesting_cw2_future = query_guard!(client_guard, get_vesting_contract_cw2_version());
for (address, name) in [
(mixnet, "nym-mixnet-contract"),
(vesting, "nym-vesting-contract"),
(coconut_bandwidth, "nym-coconut-bandwidth-contract"),
(coconut_dkg, "nym-coconut-dkg-contract"),
(group, "nym-cw4-group-contract"),
(multisig, "nym-cw3-multisig-contract"),
] {
let (cw2, build_info) = if let Some(address) = address {
let cw2 = query_guard!(client_guard, get_cw2_contract_version(address).await)?;
let mut build_info =
query_guard!(client_guard, get_contract_build_information(address).await)?;
// group and multisig contract save that information in their storage but don't expose it via queries
// so a temporary workaround...
let multisig_cw2 = if let Some(multisig_contract) = multisig {
query_guard!(
client_guard,
query_contract_raw(multisig_contract, b"contract_info".to_vec())
.await
.map(|r| serde_json::from_slice(&r).ok())
.ok()
.flatten()
)
} else {
None
};
let group_cw2 = if let Some(group_contract) = group {
query_guard!(
client_guard,
query_contract_raw(group_contract, b"contract_info".to_vec())
.await
.map(|r| serde_json::from_slice(&r).ok())
.ok()
.flatten()
)
} else {
None
};
// for backwards compatibility until we migrate the contracts
if build_info.is_none() {
match name {
"nym-mixnet-contract" => {
build_info = Some(query_guard!(
client_guard,
get_mixnet_contract_version().await
)?)
}
"nym-vesting-contract" => {
build_info = Some(query_guard!(
client_guard,
get_vesting_contract_version().await
)?)
}
_ => (),
}
}
let mut cw2_info = join_all(vec![mixnet_cw2_future, vesting_cw2_future]).await;
(cw2, build_info)
} else {
(None, None)
};
// get detailed build info
let mixnet_detailed_future = query_guard!(client_guard, get_mixnet_contract_version());
let vesting_detailed_future = query_guard!(client_guard, get_vesting_contract_version());
let mut build_info = join_all(vec![mixnet_detailed_future, vesting_detailed_future]).await;
// the below unwraps are fine as we definitely have the specified number of entries
// Note to whoever updates this code in the future: `pop` removes **LAST** element,
// so make sure you call them in correct order, depending on what's specified in the `join_all`
updated.insert(
"nym-vesting-contract".to_string(),
CachedContractInfo::new(
vesting,
cw2_info.pop().unwrap().ok(),
build_info.pop().unwrap().ok(),
),
);
updated.insert(
"nym-mixnet-contract".to_string(),
CachedContractInfo::new(
mixnet,
cw2_info.pop().unwrap().ok(),
build_info.pop().unwrap().ok(),
),
);
updated.insert(
"nym-coconut-bandwidth-contract".to_string(),
CachedContractInfo::new(coconut_bandwidth, None, None),
);
updated.insert(
"nym-coconut-dkg-contract".to_string(),
CachedContractInfo::new(coconut_dkg, None, None),
);
updated.insert(
"nym-cw3-multisig-contract".to_string(),
CachedContractInfo::new(multisig, multisig_cw2, None),
);
updated.insert(
"nym-cw4-group-contract".to_string(),
CachedContractInfo::new(group, group_cw2, None),
);
updated.insert(
name.to_string(),
CachedContractInfo::new(address, cw2, build_info),
);
}
Ok(updated)
}
+1 -2
View File
@@ -9,6 +9,7 @@ use async_trait::async_trait;
use cw3::{ProposalResponse, VoteResponse};
use cw4::MemberResponse;
use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse;
use nym_coconut_dkg_common::dealer::RegisteredDealerDetails;
use nym_coconut_dkg_common::dealing::{
DealerDealingsStatusResponse, DealingChunkInfo, DealingMetadata, DealingStatusResponse,
PartialContractDealing,
@@ -21,8 +22,6 @@ use nym_coconut_dkg_common::{
verification_key::{ContractVKShare, VerificationKeyShare},
};
use nym_config::defaults::{ChainDetails, NymNetworkDetails};
use nym_coconut_dkg_common::dealer::RegisteredDealerDetails;
use nym_mixnet_contract_common::families::FamilyHead;
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
use nym_mixnet_contract_common::reward_params::RewardingParams;