From 620a8095c514ee84c8b3ee7d08d42cf1247461aa Mon Sep 17 00:00:00 2001 From: runtianz Date: Wed, 16 Nov 2022 13:41:55 -0800 Subject: [PATCH] [release-tooling] Implement a parser from yaml (#5562) * [release-builder] Implement a parser for the framework release config * [release-builder] Add consensus config to release config * [release-tooling] Refactor the common logic for generating proposal. --- Cargo.lock | 18 +- aptos-move/aptos-release-builder/Cargo.toml | 2 + .../aptos-release-builder/data/example.yaml | 472 ++++++++++++++++++ .../src/components/consensus_config.rs | 40 ++ .../src/components/feature_flags.rs | 65 ++- .../src/components/gas.rs | 35 +- .../src/components/mod.rs | 82 ++- .../src/components/version.rs | 21 +- aptos-move/aptos-release-builder/src/main.rs | 38 +- aptos-move/aptos-release-builder/src/utils.rs | 18 + testsuite/smoke-test/src/upgrade.rs | 10 +- 11 files changed, 719 insertions(+), 82 deletions(-) create mode 100644 aptos-move/aptos-release-builder/data/example.yaml create mode 100644 aptos-move/aptos-release-builder/src/components/consensus_config.rs diff --git a/Cargo.lock b/Cargo.lock index aefcea18de6fc..2e5b77aceffd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1085,6 +1085,8 @@ dependencies = [ "clap 3.2.17", "move-core-types", "move-model", + "serde 1.0.144", + "serde_yaml 0.8.26", "tempfile", ] @@ -3392,9 +3394,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" dependencies = [ "block-buffer 0.10.2", "crypto-common", @@ -4537,7 +4539,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.3", + "digest 0.10.5", ] [[package]] @@ -8064,11 +8066,11 @@ dependencies = [ [[package]] name = "ripemd" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1facec54cb5e0dc08553501fa740091086d0259ad0067e0d4103448e4cb22ed3" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest 0.10.3", + "digest 0.10.5", ] [[package]] @@ -8594,7 +8596,7 @@ checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.3", + "digest 0.10.5", ] [[package]] @@ -8618,7 +8620,7 @@ checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.3", + "digest 0.10.5", ] [[package]] diff --git a/aptos-move/aptos-release-builder/Cargo.toml b/aptos-move/aptos-release-builder/Cargo.toml index d3a277a5c4829..c104f22574010 100644 --- a/aptos-move/aptos-release-builder/Cargo.toml +++ b/aptos-move/aptos-release-builder/Cargo.toml @@ -19,6 +19,8 @@ bcs = { git = "https://github.com/aptos-labs/bcs", rev = "2cde3e8446c460cb17b0c1 clap = { version = "3.1.17", features = ["derive"] } move-core-types = { workspace = true } move-model = { workspace = true } +serde = { version = "1.0.137", features = ["derive"], default-features = false } +serde_yaml = "0.8.24" tempfile = "3.3.0" aptos-temppath = { path = "../../crates/aptos-temppath" } diff --git a/aptos-move/aptos-release-builder/data/example.yaml b/aptos-move/aptos-release-builder/data/example.yaml new file mode 100644 index 0000000000000..3d686a4557fae --- /dev/null +++ b/aptos-move/aptos-release-builder/data/example.yaml @@ -0,0 +1,472 @@ +--- +testnet: true +framework_release: true +gas_schedule: + feature_version: 4 + entries: + - - instr.nop + - 200 + - - instr.ret + - 1200 + - - instr.abort + - 1200 + - - instr.br_true + - 2400 + - - instr.br_false + - 2400 + - - instr.branch + - 1600 + - - instr.pop + - 800 + - - instr.ld_u8 + - 1200 + - - instr.ld_u64 + - 1200 + - - instr.ld_u128 + - 1600 + - - instr.ld_true + - 1200 + - - instr.ld_false + - 1200 + - - instr.ld_const.base + - 13000 + - - instr.ld_const.per_byte + - 700 + - - instr.imm_borrow_loc + - 1200 + - - instr.mut_borrow_loc + - 1200 + - - instr.imm_borrow_field + - 4000 + - - instr.mut_borrow_field + - 4000 + - - instr.imm_borrow_field_generic + - 4000 + - - instr.mut_borrow_field_generic + - 4000 + - - instr.copy_loc.base + - 1600 + - - instr.copy_loc.per_abs_val_unit + - 80 + - - instr.move_loc.base + - 2400 + - - instr.st_loc.base + - 2400 + - - instr.call.base + - 20000 + - - instr.call.per_arg + - 2000 + - - instr.call.per_local + - 2000 + - - instr.call_generic.base + - 20000 + - - instr.call_generic.per_ty_arg + - 2000 + - - instr.call_generic.per_arg + - 2000 + - - instr.call_generic.per_local + - 2000 + - - instr.pack.base + - 4400 + - - instr.pack.per_field + - 800 + - - instr.pack_generic.base + - 4400 + - - instr.pack_generic.per_field + - 800 + - - instr.unpack.base + - 4400 + - - instr.unpack.per_field + - 800 + - - instr.unpack_generic.base + - 4400 + - - instr.unpack_generic.per_field + - 800 + - - instr.read_ref.base + - 4000 + - - instr.read_ref.per_abs_val_unit + - 80 + - - instr.write_ref.base + - 4000 + - - instr.freeze_ref + - 200 + - - instr.cast_u8 + - 2400 + - - instr.cast_u64 + - 2400 + - - instr.cast_u128 + - 2400 + - - instr.add + - 3200 + - - instr.sub + - 3200 + - - instr.mul + - 3200 + - - instr.mod + - 3200 + - - instr.div + - 3200 + - - instr.bit_or + - 3200 + - - instr.bit_and + - 3200 + - - instr.bit_xor + - 3200 + - - instr.bit_shl + - 3200 + - - instr.bit_shr + - 3200 + - - instr.or + - 3200 + - - instr.and + - 3200 + - - instr.not + - 3200 + - - instr.lt + - 3200 + - - instr.gt + - 3200 + - - instr.le + - 3200 + - - instr.ge + - 3200 + - - instr.eq.base + - 2000 + - - instr.eq.per_abs_val_unit + - 80 + - - instr.neq.base + - 2000 + - - instr.neq.per_abs_val_unit + - 80 + - - instr.imm_borrow_global.base + - 10000 + - - instr.imm_borrow_global_generic.base + - 10000 + - - instr.mut_borrow_global.base + - 10000 + - - instr.mut_borrow_global_generic.base + - 10000 + - - instr.exists.base + - 5000 + - - instr.exists_generic.base + - 5000 + - - instr.move_from.base + - 7000 + - - instr.move_from_generic.base + - 7000 + - - instr.move_to.base + - 10000 + - - instr.move_to_generic.base + - 10000 + - - instr.vec_len.base + - 4400 + - - instr.vec_imm_borrow.base + - 6600 + - - instr.vec_mut_borrow.base + - 6600 + - - instr.vec_push_back.base + - 7600 + - - instr.vec_pop_back.base + - 5200 + - - instr.vec_swap.base + - 6000 + - - instr.vec_pack.base + - 12000 + - - instr.vec_pack.per_elem + - 800 + - - instr.vec_unpack.base + - 10000 + - - instr.vec_unpack.per_expected_elem + - 800 + - - txn.min_transaction_gas_units + - 1500000 + - - txn.large_transaction_cutoff + - 600 + - - txn.intrinsic_gas_per_byte + - 2000 + - - txn.maximum_number_of_gas_units + - 2000000 + - - txn.min_price_per_gas_unit + - 100 + - - txn.max_price_per_gas_unit + - 10000000000 + - - txn.max_transaction_size_in_bytes + - 65536 + - - txn.gas_unit_scaling_factor + - 10000 + - - txn.load_data.base + - 16000 + - - txn.load_data.per_byte + - 1000 + - - txn.load_data.failure + - 0 + - - txn.write_data.per_op + - 160000 + - - txn.write_data.new_item + - 1280000 + - - txn.write_data.per_byte_in_key + - 10000 + - - txn.write_data.per_byte_in_val + - 10000 + - - txn.memory_quota + - 10000000 + - - move_stdlib.bcs.to_bytes.per_byte_serialized + - 200 + - - move_stdlib.bcs.to_bytes.failure + - 20000 + - - move_stdlib.hash.sha2_256.base + - 60000 + - - move_stdlib.hash.sha2_256.per_byte + - 1000 + - - move_stdlib.hash.sha3_256.base + - 80000 + - - move_stdlib.hash.sha3_256.per_byte + - 900 + - - move_stdlib.signer.borrow_address.base + - 4000 + - - move_stdlib.string.check_utf8.base + - 6000 + - - move_stdlib.string.check_utf8.per_byte + - 160 + - - move_stdlib.string.is_char_boundary.base + - 6000 + - - move_stdlib.string.sub_string.base + - 8000 + - - move_stdlib.string.sub_string.per_byte + - 60 + - - move_stdlib.string.index_of.base + - 8000 + - - move_stdlib.string.index_of.per_byte_pattern + - 400 + - - move_stdlib.string.index_of.per_byte_searched + - 200 + - - aptos_framework.account.create_address.base + - 6000 + - - aptos_framework.account.create_signer.base + - 6000 + - - aptos_framework.bls12381.base + - 3000 + - - aptos_framework.bls12381.per_pubkey_deserialize + - 2180000 + - - aptos_framework.bls12381.per_pubkey_aggregate + - 84000 + - - aptos_framework.bls12381.per_pubkey_subgroup_check + - 7400000 + - - aptos_framework.bls12381.per_sig_deserialize + - 4440000 + - - aptos_framework.bls12381.per_sig_aggregate + - 233000 + - - aptos_framework.bls12381.per_sig_subgroup_check + - 9210000 + - - aptos_framework.bls12381.per_sig_verify + - 169700000 + - - aptos_framework.bls12381.per_pop_verify + - 206000000 + - - aptos_framework.bls12381.per_pairing + - 80260000 + - - aptos_framework.bls12381.per_msg_hashing + - 30800000 + - - aptos_framework.bls12381.per_byte_hashing + - 1000 + - - aptos_framework.signature.base + - 3000 + - - aptos_framework.signature.per_pubkey_deserialize + - 760000 + - - aptos_framework.signature.per_pubkey_small_order_check + - 127000 + - - aptos_framework.signature.per_sig_deserialize + - 7500 + - - aptos_framework.signature.per_sig_strict_verify + - 5340000 + - - aptos_framework.signature.per_msg_hashing_base + - 64800 + - - aptos_framework.signature.per_msg_byte_hashing + - 1200 + - - aptos_framework.secp256k1.base + - 3000 + - - aptos_framework.secp256k1.ecdsa_recover + - 32200000 + - - aptos_framework.ristretto255.basepoint_mul + - 2560000 + - - aptos_framework.ristretto255.basepoint_double_mul + - 8800000 + - - aptos_framework.ristretto255.point_add + - 42700 + - - aptos_framework.ristretto255.point_compress + - 800000 + - - aptos_framework.ristretto255.point_decompress + - 810000 + - - aptos_framework.ristretto255.point_equals + - 46000 + - - aptos_framework.ristretto255.point_from_64_uniform_bytes + - 1630000 + - - aptos_framework.ristretto255.point_identity + - 3000 + - - aptos_framework.ristretto255.point_mul + - 9420000 + - - aptos_framework.ristretto255.point_neg + - 7200 + - - aptos_framework.ristretto255.point_sub + - 42600 + - - aptos_framework.ristretto255.point_parse_arg + - 3000 + - - aptos_framework.ristretto255.scalar_sha512_per_byte + - 1200 + - - aptos_framework.ristretto255.scalar_sha512_per_hash + - 64800 + - - aptos_framework.ristretto255.scalar_add + - 15400 + - - aptos_framework.ristretto255.scalar_reduced_from_32_bytes + - 14200 + - - aptos_framework.ristretto255.scalar_uniform_from_64_bytes + - 24900 + - - aptos_framework.ristretto255.scalar_from_u128 + - 3500 + - - aptos_framework.ristretto255.scalar_from_u64 + - 3500 + - - aptos_framework.ristretto255.scalar_invert + - 2200000 + - - aptos_framework.ristretto255.scalar_is_canonical + - 23000 + - - aptos_framework.ristretto255.scalar_mul + - 21300 + - - aptos_framework.ristretto255.scalar_neg + - 14500 + - - aptos_framework.ristretto255.scalar_sub + - 21200 + - - aptos_framework.ristretto255.scalar_parse_arg + - 3000 + - - aptos_framework.hash.sip_hash.base + - 20000 + - - aptos_framework.hash.sip_hash.per_byte + - 400 + - - aptos_framework.hash.keccak256.base + - 80000 + - - aptos_framework.hash.keccak256.per_byte + - 900 + - - aptos_framework.type_info.type_of.base + - 6000 + - - aptos_framework.type_info.type_of.per_abstract_memory_unit + - 100 + - - aptos_framework.type_info.type_name.base + - 6000 + - - aptos_framework.type_info.type_name.per_abstract_memory_unit + - 100 + - - aptos_framework.type_info.chain_id.base + - 3000 + - - aptos_framework.hash.sha2_512.base + - 3240 + - - aptos_framework.hash.sha2_512.per_byte + - 60 + - - aptos_framework.hash.sha3_512.base + - 4500 + - - aptos_framework.hash.sha3_512.per_byte + - 50 + - - aptos_framework.hash.ripemd160.base + - 3000 + - - aptos_framework.hash.ripemd160.per_byte + - 50 + - - aptos_framework.util.from_bytes.base + - 6000 + - - aptos_framework.util.from_bytes.per_byte + - 100 + - - aptos_framework.transaction_context.get_script_hash.base + - 4000 + - - aptos_framework.code.request_publish.base + - 10000 + - - aptos_framework.code.request_publish.per_byte + - 40 + - - aptos_framework.event.write_to_event_store.base + - 500000 + - - aptos_framework.event.write_to_event_store.per_abstract_memory_unit + - 5000 + - - aptos_framework.state_storage.get_usage.base + - 10000 + - - aptos_framework.aggregator.add.base + - 6000 + - - aptos_framework.aggregator.read.base + - 6000 + - - aptos_framework.aggregator.sub.base + - 6000 + - - aptos_framework.aggregator.destroy.base + - 10000 + - - aptos_framework.aggregator_factory.new_aggregator.base + - 10000 + - - table.common.load.base + - 8000 + - - table.common.load.per_byte + - 1000 + - - table.common.load.failure + - 0 + - - table.new_table_handle.base + - 20000 + - - table.add_box.base + - 24000 + - - table.add_box.per_byte_serialized + - 200 + - - table.borrow_box.base + - 24000 + - - table.borrow_box.per_byte_serialized + - 200 + - - table.contains_box.base + - 24000 + - - table.contains_box.per_byte_serialized + - 200 + - - table.remove_box.base + - 24000 + - - table.remove_box.per_byte_serialized + - 200 + - - table.destroy_empty_box.base + - 24000 + - - table.drop_unchecked_box.base + - 2000 + - - misc.abs_val.u8 + - 40 + - - misc.abs_val.u64 + - 40 + - - misc.abs_val.u128 + - 40 + - - misc.abs_val.bool + - 40 + - - misc.abs_val.address + - 40 + - - misc.abs_val.struct + - 40 + - - misc.abs_val.vector + - 40 + - - misc.abs_val.reference + - 40 + - - misc.abs_val.per_u8_packed + - 1 + - - misc.abs_val.per_u64_packed + - 8 + - - misc.abs_val.per_u128_packed + - 16 + - - misc.abs_val.per_bool_packed + - 1 + - - misc.abs_val.per_address_packed + - 32 +version: + major: 4 +feature_flags: + enabled: + - code_dependency_check + - treat_friend_as_private + disabled: [] +consensus_config: + V1: + decoupled_execution: true + back_pressure_limit: 10 + exclude_round: 20 + proposer_election_type: + leader_reputation: + proposer_and_voter_v2: + active_weight: 1000 + inactive_weight: 10 + failed_weight: 1 + failure_threshold_percent: 10 + proposer_window_num_validators_multiplier: 10 + voter_window_num_validators_multiplier: 1 + weight_by_voting_power: true + use_history_from_previous_epoch_max_count: 5 + max_failed_authors_to_store: 10 \ No newline at end of file diff --git a/aptos-move/aptos-release-builder/src/components/consensus_config.rs b/aptos-move/aptos-release-builder/src/components/consensus_config.rs new file mode 100644 index 0000000000000..284279a0b8898 --- /dev/null +++ b/aptos-move/aptos-release-builder/src/components/consensus_config.rs @@ -0,0 +1,40 @@ +// Copyright (c) Aptos +// SPDX-License-Identifier: Apache-2.0 + +use crate::utils::*; +use anyhow::Result; +use aptos_types::on_chain_config::OnChainConsensusConfig; +use move_model::{code_writer::CodeWriter, emit, emitln, model::Loc}; + +pub fn generate_consensus_upgrade_proposal( + consensus_config: &OnChainConsensusConfig, + is_testnet: bool, +) -> Result> { + let mut result = vec![]; + + let writer = CodeWriter::new(Loc::default()); + + emitln!(writer, "// Consensus config upgrade proposal\n"); + + let proposal = generate_governance_proposal( + &writer, + is_testnet, + "aptos_framework::consensus_config", + |writer| { + let consensus_config_blob = bcs::to_bytes(consensus_config).unwrap(); + assert!(consensus_config_blob.len() < 65536); + + emit!(writer, "let consensus_blob: vector = "); + generate_blob(writer, &consensus_config_blob); + emitln!(writer, ";\n"); + + emitln!( + writer, + "consensus_config::set(framework_signer, consensus_blob);" + ); + }, + ); + + result.push(("consensus-config".to_string(), proposal)); + Ok(result) +} diff --git a/aptos-move/aptos-release-builder/src/components/feature_flags.rs b/aptos-move/aptos-release-builder/src/components/feature_flags.rs index e0339e2eb2570..a890fc48d622c 100644 --- a/aptos-move/aptos-release-builder/src/components/feature_flags.rs +++ b/aptos-move/aptos-release-builder/src/components/feature_flags.rs @@ -3,14 +3,24 @@ use crate::utils::*; use anyhow::Result; -use aptos_types::on_chain_config::FeatureFlag; +use aptos_types::on_chain_config::FeatureFlag as AFeatureFlag; use move_model::{code_writer::CodeWriter, emit, emitln, model::Loc}; +use serde::{Deserialize, Serialize}; +#[derive(Clone, Deserialize, PartialEq, Eq, Serialize)] pub struct Features { pub enabled: Vec, pub disabled: Vec, } +#[derive(Clone, Deserialize, PartialEq, Eq, Serialize)] +#[allow(non_camel_case_types)] +#[serde(rename_all = "snake_case")] +pub enum FeatureFlag { + CodeDependencyCheck, + TreatFriendAsPrivate, +} + fn generate_features_blob(writer: &CodeWriter, data: &[u64]) { emitln!(writer, "vector["); writer.indent(); @@ -38,12 +48,12 @@ pub fn generate_feature_upgrade_proposal( let enabled = features .enabled .iter() - .map(|f| *f as u64) + .map(|f| AFeatureFlag::from(f.clone()) as u64) .collect::>(); let disabled = features .disabled .iter() - .map(|f| *f as u64) + .map(|f| AFeatureFlag::from(f.clone()) as u64) .collect::>(); assert!(enabled.len() < u16::MAX as usize); @@ -51,25 +61,40 @@ pub fn generate_feature_upgrade_proposal( let writer = CodeWriter::new(Loc::default()); - if is_testnet { - generate_testnet_header(&writer, "std::features"); - } else { - generate_governance_proposal_header(&writer, "std::features"); - } - - emit!(writer, "let enabled_blob: vector = "); - generate_features_blob(&writer, &enabled); - emitln!(writer, ";\n"); + let proposal = generate_governance_proposal(&writer, is_testnet, "std::features", |writer| { + emit!(writer, "let enabled_blob: vector = "); + generate_features_blob(writer, &enabled); + emitln!(writer, ";\n"); - emit!(writer, "let disabled_blob: vector = "); - generate_features_blob(&writer, &disabled); - emitln!(writer, ";\n"); + emit!(writer, "let disabled_blob: vector = "); + generate_features_blob(writer, &disabled); + emitln!(writer, ";\n"); - emitln!( - writer, - "features::change_feature_flags(framework_signer, enabled_blob, disabled_blob);" - ); + emitln!( + writer, + "features::change_feature_flags(framework_signer, enabled_blob, disabled_blob);" + ); + }); - result.push(("features".to_string(), finish_with_footer(&writer))); + result.push(("features".to_string(), proposal)); Ok(result) } + +impl From for AFeatureFlag { + fn from(f: FeatureFlag) -> Self { + match f { + FeatureFlag::CodeDependencyCheck => AFeatureFlag::CODE_DEPENDENCY_CHECK, + FeatureFlag::TreatFriendAsPrivate => AFeatureFlag::TREAT_FRIEND_AS_PRIVATE, + } + } +} + +// We don't need this implementation. Just to make sure we have an exhaustive 1-1 mapping between the two structs. +impl From for FeatureFlag { + fn from(f: AFeatureFlag) -> Self { + match f { + AFeatureFlag::CODE_DEPENDENCY_CHECK => FeatureFlag::CodeDependencyCheck, + AFeatureFlag::TREAT_FRIEND_AS_PRIVATE => FeatureFlag::TreatFriendAsPrivate, + } + } +} diff --git a/aptos-move/aptos-release-builder/src/components/gas.rs b/aptos-move/aptos-release-builder/src/components/gas.rs index 7f27fabfaea1f..0af5bea37be43 100644 --- a/aptos-move/aptos-release-builder/src/components/gas.rs +++ b/aptos-move/aptos-release-builder/src/components/gas.rs @@ -12,10 +12,6 @@ pub fn generate_gas_upgrade_proposal( ) -> Result> { let mut result = vec![]; - let gas_schedule_blob = bcs::to_bytes(gas_schedule).unwrap(); - - assert!(gas_schedule_blob.len() < 65536); - let writer = CodeWriter::new(Loc::default()); emitln!(writer, "// Gas schedule upgrade proposal\n"); @@ -37,21 +33,24 @@ pub fn generate_gas_upgrade_proposal( } emitln!(writer); - if is_testnet { - generate_testnet_header(&writer, "aptos_framework::gas_schedule"); - } else { - generate_governance_proposal_header(&writer, "aptos_framework::gas_schedule"); - } - - emit!(writer, "let gas_schedule_blob: vector = "); - generate_blob(&writer, &gas_schedule_blob); - emitln!(writer, ";\n"); - - emitln!( - writer, - "gas_schedule::set_gas_schedule(framework_signer, gas_schedule_blob);" + let proposal = generate_governance_proposal( + &writer, + is_testnet, + "aptos_framework::gas_schedule", + |writer| { + let gas_schedule_blob = bcs::to_bytes(gas_schedule).unwrap(); + assert!(gas_schedule_blob.len() < 65536); + emit!(writer, "let gas_schedule_blob: vector = "); + generate_blob(writer, &gas_schedule_blob); + emitln!(writer, ";\n"); + + emitln!( + writer, + "gas_schedule::set_gas_schedule(framework_signer, gas_schedule_blob);" + ); + }, ); - result.push(("gas-schedule".to_string(), finish_with_footer(&writer))); + result.push(("gas-schedule".to_string(), proposal)); Ok(result) } diff --git a/aptos-move/aptos-release-builder/src/components/mod.rs b/aptos-move/aptos-release-builder/src/components/mod.rs index 08003c13ae70c..672e29e4e5df2 100644 --- a/aptos-move/aptos-release-builder/src/components/mod.rs +++ b/aptos-move/aptos-release-builder/src/components/mod.rs @@ -3,48 +3,68 @@ use crate::components::feature_flags::Features; use anyhow::{anyhow, Result}; -use aptos_types::on_chain_config::{GasScheduleV2, Version}; -use std::path::Path; +use aptos_types::on_chain_config::{GasScheduleV2, OnChainConsensusConfig, Version}; +use serde::{Deserialize, Serialize}; +use std::{ + fs::File, + io::{Read, Write}, + path::Path, +}; +pub mod consensus_config; pub mod feature_flags; pub mod framework; pub mod gas; pub mod version; +#[derive(Serialize, Deserialize, Clone, Eq, PartialEq)] pub struct ReleaseConfig { + pub testnet: bool, + pub framework_release: bool, + #[serde(default, skip_serializing_if = "Option::is_none")] pub gas_schedule: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] pub version: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] pub feature_flags: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub consensus_config: Option, } impl ReleaseConfig { - pub fn generate_release_proposal_scripts( - &self, - base_path: &Path, - is_testnet: bool, - ) -> Result<()> { + pub fn generate_release_proposal_scripts(&self, base_path: &Path) -> Result<()> { let mut result = vec![]; // First create framework releases - result.append(&mut framework::generate_upgrade_proposals(is_testnet)?); + if self.framework_release { + result.append(&mut framework::generate_upgrade_proposals(self.testnet)?); + } if let Some(gas_schedule) = &self.gas_schedule { result.append(&mut gas::generate_gas_upgrade_proposal( gas_schedule, - is_testnet, + self.testnet, )?); } if let Some(version) = &self.version { result.append(&mut version::generate_version_upgrade_proposal( - version, is_testnet, + version, + self.testnet, )?); } if let Some(feature_flags) = &self.feature_flags { result.append(&mut feature_flags::generate_feature_upgrade_proposal( feature_flags, - is_testnet, + self.testnet, + )?); + } + + if let Some(consensus_config) = &self.consensus_config { + result.append(&mut consensus_config::generate_consensus_upgrade_proposal( + consensus_config, + self.testnet, )?); } @@ -59,14 +79,54 @@ impl ReleaseConfig { } Ok(()) } + + pub fn load_config>(path: P) -> Result { + // Open the file and read it into a string + let config_path_string = path.as_ref().to_str().unwrap().to_string(); + let mut file = File::open(&path).map_err(|error| { + anyhow!( + "Failed to open config file: {:?}. Error: {:?}", + config_path_string, + error + ) + })?; + let mut contents = String::new(); + file.read_to_string(&mut contents).map_err(|error| { + anyhow!( + "Failed to read the config file into a string: {:?}. Error: {:?}", + config_path_string, + error + ) + })?; + + // Parse the file string + Self::parse(&contents) + } + + pub fn save_config>(&self, output_file: P) -> Result<()> { + let contents = + serde_yaml::to_vec(&self).map_err(|e| anyhow!("failed to generate config: {:?}", e))?; + let mut file = File::create(output_file.as_ref()) + .map_err(|e| anyhow!("failed to create file: {:?}", e))?; + file.write_all(&contents) + .map_err(|e| anyhow!("failed to write file: {:?}", e))?; + Ok(()) + } + + pub fn parse(serialized: &str) -> Result { + serde_yaml::from_str(serialized).map_err(|e| anyhow!("Failed to parse the config: {:?}", e)) + } } impl Default for ReleaseConfig { fn default() -> Self { ReleaseConfig { + testnet: true, + framework_release: true, gas_schedule: Some(aptos_gas::gen::current_gas_schedule()), version: None, feature_flags: None, + consensus_config: Some(OnChainConsensusConfig::default()), } } } diff --git a/aptos-move/aptos-release-builder/src/components/version.rs b/aptos-move/aptos-release-builder/src/components/version.rs index ad97b76f4efaf..218e0dfef8495 100644 --- a/aptos-move/aptos-release-builder/src/components/version.rs +++ b/aptos-move/aptos-release-builder/src/components/version.rs @@ -14,18 +14,15 @@ pub fn generate_version_upgrade_proposal( let writer = CodeWriter::new(Loc::default()); - if is_testnet { - generate_testnet_header(&writer, "aptos_framework::version"); - } else { - generate_governance_proposal_header(&writer, "aptos_framework::version"); - } + let proposal = + generate_governance_proposal(&writer, is_testnet, "aptos_framework::version", |writer| { + emitln!( + writer, + "version::set_version(framework_signer, {});", + version.major, + ); + }); - emitln!( - writer, - "version::set_version(framework_signer, {});", - version.major, - ); - - result.push(("version".to_string(), finish_with_footer(&writer))); + result.push(("version".to_string(), proposal)); Ok(result) } diff --git a/aptos-move/aptos-release-builder/src/main.rs b/aptos-move/aptos-release-builder/src/main.rs index 21c9603da2a1d..92f1e33074e9c 100644 --- a/aptos-move/aptos-release-builder/src/main.rs +++ b/aptos-move/aptos-release-builder/src/main.rs @@ -2,19 +2,41 @@ // SPDX-License-Identifier: Apache-2.0 use anyhow::Result; -use clap::Parser; +use clap::{Parser, Subcommand}; use std::path::PathBuf; -#[derive(Debug, Parser)] -pub struct GenArgs { - #[clap(short, long)] - pub output: Option, +#[derive(Parser)] +pub struct Argument { + #[clap(subcommand)] + cmd: Commands, +} + +#[derive(Subcommand, Debug)] +pub enum Commands { + GenerateProposals { + #[clap(short, long)] + release_config: PathBuf, + #[clap(short, long)] + output_dir: PathBuf, + }, + WriteDefault { + #[clap(short, long)] + output_path: PathBuf, + }, } fn main() -> Result<()> { - let args = GenArgs::parse(); + let args = Argument::parse(); // TODO: Being able to parse the release config from a TOML file to generate the proposals. - aptos_release_builder::ReleaseConfig::default() - .generate_release_proposal_scripts(args.output.as_ref().unwrap(), true) + match args.cmd { + Commands::GenerateProposals { + release_config, + output_dir, + } => aptos_release_builder::ReleaseConfig::load_config(release_config.as_path())? + .generate_release_proposal_scripts(output_dir.as_path()), + Commands::WriteDefault { output_path } => { + aptos_release_builder::ReleaseConfig::default().save_config(output_path.as_path()) + } + } } diff --git a/aptos-move/aptos-release-builder/src/utils.rs b/aptos-move/aptos-release-builder/src/utils.rs index c3bf06ebd57ee..06897b7539a6c 100644 --- a/aptos-move/aptos-release-builder/src/utils.rs +++ b/aptos-move/aptos-release-builder/src/utils.rs @@ -68,3 +68,21 @@ pub(crate) fn finish_with_footer(writer: &CodeWriter) -> String { writer.process_result(|s| s.to_string()) } + +pub(crate) fn generate_governance_proposal( + writer: &CodeWriter, + is_testnet: bool, + deps_name: &str, + body: F, +) -> String +where + F: FnOnce(&CodeWriter), +{ + if is_testnet { + generate_testnet_header(writer, deps_name); + } else { + generate_governance_proposal_header(writer, deps_name); + } + body(writer); + finish_with_footer(writer) +} diff --git a/testsuite/smoke-test/src/upgrade.rs b/testsuite/smoke-test/src/upgrade.rs index 8d9027d99efec..52a0d741a58ce 100644 --- a/testsuite/smoke-test/src/upgrade.rs +++ b/testsuite/smoke-test/src/upgrade.rs @@ -8,10 +8,10 @@ use crate::{ use aptos_crypto::ValidCryptoMaterialStringExt; use aptos_gas::{AptosGasParameters, GasQuantity, InitialGasSchedule, ToOnChainGasSchedule}; use aptos_release_builder::components::{ - feature_flags::Features, gas::generate_gas_upgrade_proposal, + feature_flags::{FeatureFlag, Features}, + gas::generate_gas_upgrade_proposal, }; use aptos_temppath::TempPath; -use aptos_types::on_chain_config::FeatureFlag; use forge::Swarm; use std::fs; use std::process::Command; @@ -84,8 +84,8 @@ async fn test_upgrade_flow() { let config = aptos_release_builder::ReleaseConfig { feature_flags: Some(Features { enabled: vec![ - FeatureFlag::CODE_DEPENDENCY_CHECK, - FeatureFlag::TREAT_FRIEND_AS_PRIVATE, + FeatureFlag::CodeDependencyCheck, + FeatureFlag::TreatFriendAsPrivate, ], disabled: vec![], }), @@ -93,7 +93,7 @@ async fn test_upgrade_flow() { }; config - .generate_release_proposal_scripts(upgrade_scripts_folder.path(), true) + .generate_release_proposal_scripts(upgrade_scripts_folder.path()) .unwrap(); let mut scripts = fs::read_dir(upgrade_scripts_folder.path()) .unwrap()