[protocol] # Protocol version. version = '2.2.2' # Whether we need to clear latest blocks back to the switch block just before the activation point or not. hard_reset = true # This protocol version becomes active at this point. # # If it is a timestamp string, it represents the timestamp for the genesis block. This is the beginning of era 0. By # this time, a sufficient majority (> 50% + F/2 — see finality_threshold_fraction below) of validator nodes must be up # and running to start the blockchain. This timestamp is also used in seeding the pseudo-random number generator used # in contract-runtime for computing genesis post-state hash. # # If it is an integer, it represents an era ID, meaning the protocol version becomes active at the start of this era. activation_point = 22931 [network] # Human readable name for convenience; the genesis_hash is the true identifier. The name influences the genesis hash by # contributing to the seeding of the pseudo-random number generator used in contract-runtime for computing genesis # post-state hash. name = 'casper' # The maximum size of an acceptable networking message in bytes. Any message larger than this will # be rejected at the networking level. maximum_net_message_size = 25_165_824 [core] # Era duration. era_duration = '120 minutes' # Minimum number of blocks per era. An era will take longer than `era_duration` if that is necessary to reach the # minimum height. minimum_era_height = 100 # Minimum difference between a block's and its child's timestamp. minimum_block_time = '8000 ms' # Number of slots available in validator auction. validator_slots = 100 # A number between 0 and 1 representing the fault tolerance threshold as a fraction, used by the internal finalizer. # It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as # finalized: A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize # blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly. finality_threshold_fraction = [1, 3] # Protocol version from which nodes are required to hold strict finality signatures. start_protocol_version_with_strict_finality_signatures_required = '1.5.0' # Which finality is required for legacy blocks. Options are 'Strict', 'Weak' and 'Any'. # Used to determine finality sufficiency for new joiners syncing blocks created # in a protocol version before # `start_protocol_version_with_strict_finality_signatures_required`. legacy_required_finality = 'Any' # Number of eras before an auction actually defines the set of validators. If you bond with a sufficient bid in era N, # you will be a validator in era N + auction_delay + 1. auction_delay = 1 # The period after genesis during which a genesis validator's bid is locked. locked_funds_period = '0 days' # The period in which genesis validator's bid is released over time after it's unlocked. vesting_schedule_period = '0 weeks' # Default number of eras that need to pass to be able to withdraw unbonded funds. unbonding_delay = 7 # Round seigniorage rate represented as a fraction of the total supply. # # Annual issuance: 8% # Minimum block time: 8000 milliseconds # Ticks per year: 31536000000 # # (1+0.08)^((8000)/31536000000)-1 is expressed as a fractional number below # Python: # from fractions import Fraction # Fraction((1 + 0.08)**((8000)/31536000000) - 1).limit_denominator(1000000000) round_seigniorage_rate = [11, 563427926] # Maximum number of associated keys for a single account. max_associated_keys = 100 # Maximum height of contract runtime call stack. max_runtime_call_stack_height = 12 # Minimum allowed delegation amount in motes minimum_delegation_amount = 500_000_000_000 # Maximum allowed delegation amount in motes maximum_delegation_amount = 1_000_000_000_000_000_000 # Minimum bid amount allowed in motes. Withdrawing one's bid to an amount strictly less than # the value specified will be treated as a full unbond of a validator and their associated delegators minimum_bid_amount = 500_000_000_000 # Global state prune batch size (0 = this feature is off) prune_batch_size = 0 # Enables strict arguments checking when calling a contract; i.e. that all non-optional args are provided and of the correct `CLType`. strict_argument_checking = false # Number of simultaneous peer requests. simultaneous_peer_requests = 5 # The consensus protocol to use. Options are "Zug" and "Highway". consensus_protocol = 'Zug' # The maximum amount of delegators per validator. max_delegators_per_validator = 1200 # Minimum delegation rate validators can specify (0-100). minimum_delegation_rate = 0 # The split in finality signature rewards between block producer and participating signers. finders_fee = [1, 5] # The proportion of baseline rewards going to reward finality signatures specifically. finality_signature_proportion = [95, 100] # Lookback interval indicating which past block we are looking at to reward. signature_rewards_max_delay = 6 # Allows transfers between accounts in the blockchain network. # # Setting this to false restricts normal accounts from sending tokens to other accounts, allowing transfers only to administrators. # Changing this option makes sense only on private chains. allow_unrestricted_transfers = true # Enables the auction entry points 'delegate' and 'add_bid'. # # Setting this to false makes sense only for private chains which don't need to auction new validator slots. These # auction entry points will return an error if called when this option is set to false. allow_auction_bids = true # If set to false, then consensus doesn't compute rewards and always uses 0. compute_rewards = true # Defines how refunds of the unused portion of payment amounts are calculated and handled. # # Valid options are: # 'refund': a ratio of the unspent token is returned to the spender. # 'burn': a ratio of the unspent token is burned. # 'no_refund': no refunds are paid out; this is functionally equivalent to refund with 0% ratio. # This causes excess payment amounts to be sent to either a # pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount # minus the execution costs. refund_handling = { type = 'refund', refund_ratio = [75, 100] } # Defines how fees are handled. # # Valid options are: # 'no_fee': fees are eliminated. # 'pay_to_proposer': fees are paid to the block proposer # 'accumulate': fees are accumulated in a special purse and distributed at the end of each era evenly among all # administrator accounts # 'burn': fees are burned fee_handling = { type = 'burn' } # If a validator would recieve a validator credit, it cannot exceed this percentage of their total stake. validator_credit_cap = [1, 5] # Defines how pricing is handled. # # Valid options are: # 'payment_limited': senders of transaction self-specify how much they pay. # 'fixed': costs are fixed, per the cost table # 'prepaid': prepaid transaction (currently not supported) pricing_handling = { type = 'payment_limited' } # Does the network allow pre-payment for future # execution? Currently not supported. # allow_prepaid = false # Defines how gas holds affect available balance calculations. # # Valid options are: # 'accrued': sum of full value of all non-expired holds. # 'amortized': sum of each hold is amortized over the time remaining until expiry. # # For instance, if 12 hours remained on a gas hold with a 24-hour `gas_hold_interval`, # with accrued, the full hold amount would be applied # with amortized, half the hold amount would be applied gas_hold_balance_handling = { type = 'accrued' } # Defines how long gas holds last. # # If fee_handling is set to 'no_fee', the system places a balance hold on the payer # equal to the value the fee would have been. Such balance holds expire after a time # interval has elapsed. This setting controls how long that interval is. The available # balance of a purse equals its total balance minus the held amount(s) of non-expired # holds (see gas_hold_balance_handling setting for details of how that is calculated). # # For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse, # a hold for 100 is placed on that purse and is considered when calculating total balance # for 24 hours starting from the block_time when the hold was placed. gas_hold_interval = '24 hours' # List of public keys of administrator accounts. Setting this option makes only on private chains which require # administrator accounts for regulatory reasons. administrators = [] # Flag that triggers a migration of all userland accounts and contracts present in global state to the addressable # entity in lazy manner. # If the flag is set to false then no accounts and contracts are migrated during a protocol upgrade; # i.e. all Account records will be present under Key::Account and Contracts and their associated ContractPackage # will be written underneath Key::Hash. # If the flag is set to true then accounts and contracts are migrated lazily; i.e on first use of the Account # and/or Contract as part of the execution of a Transaction. This means the Accounts/Contracts will be migrated # to their corresponding AddressableEntity and the NamedKeys for previous record and sepeareted and wrriten # as discrete top level records. For Contracts specifically the entrypoints are also written as discrete top # level records # Note: Enabling of the AddressableEntity feature is one-way; i.e once enabled as part of a protocol upgrade # the flag cannot be disabled in a future protocol upgrade. enable_addressable_entity = false # This value is used as the penalty payment amount, the lowest cost, and the minimum balance amount. baseline_motes_amount = 2_500_000_000 # Flag on whether ambiguous entity versions returns an execution error. trap_on_ambiguous_entity_version = false # purse uref-5bd5c35f2897844b307b9efbb2d7f01f4d51a2ecea8d8b88abd4e3c3a4594693-007 belongs to # CA Ecosystem Sustainability account 020245b32289d807f3fcd5f9dbec94ff51ee57857f4b39a3b9d6fb99305317d18a32 rewards_handling = { type = 'sustain', ratio = [2,8], purse_address = "uref-5bd5c35f2897844b307b9efbb2d7f01f4d51a2ecea8d8b88abd4e3c3a4594693-007" } [highway] # Highway dynamically chooses its round length, between minimum_block_time and maximum_round_length. maximum_round_length = '66 seconds' [transactions] # The duration after the transaction timestamp that it can be included in a block. max_ttl = '2 hours' # The maximum number of approvals permitted in a single block. block_max_approval_count = 2600 # Maximum block size in bytes including transactions contained by the block. 0 means unlimited. max_block_size = 2_621_400 # The upper limit of total gas of all transactions in a block. block_gas_limit = 812_500_000_000 # The minimum amount in motes for a valid native transfer. native_transfer_minimum_motes = 2_500_000_000 # The maximum value to which `transaction_acceptor.timestamp_leeway` can be set in the config.toml file. max_timestamp_leeway = '5 seconds' # Configuration of the transaction runtime. [transactions.enabled_runtime] vm_casper_v1 = true vm_casper_v2 = false [transactions.v1] # The configuration settings for the lanes of transactions including both native and Wasm based interactions. # Currently the node supports two native interactions the mint and auction and have the reserved identifiers of 0 and 1 # respectively # The remaining wasm based lanes specify the range of configuration settings for a given Wasm based transaction # within a given lane. # The maximum length in bytes of runtime args per V1 transaction. # [0] -> Transaction lane label (apart from the reserved native identifiers these are simply labels) # Note: For the given mainnet implementation we specially reserve the label 2 for install and upgrades and # the lane must be present and defined. # Different casper networks may not impose such a restriction. # [1] -> Max serialized length of the entire transaction in bytes for a given transaction in a certain lane # [2] -> Max args length size in bytes for a given transaction in a certain lane # [3] -> Transaction gas limit for a given transaction in a certain lane # [4] -> The maximum number of transactions the lane can contain native_mint_lane = [0, 2048, 1024, 100_000_000, 325] native_auction_lane = [1, 3096, 2048, 2_500_000_000, 325] install_upgrade_lane = [2, 750_000, 2048, 1_000_000_000_000, 1] wasm_lanes = [ [3, 750_000, 2048, 1_000_000_000_000, 1], [4, 131_072, 1024, 100_000_000_000, 2], [5, 65_536, 512, 5_000_000_000, 40] ] [transactions.deploy] # The maximum number of Motes allowed to be spent during payment. 0 means unlimited. max_payment_cost = '0' # The limit of length of serialized payment code arguments. payment_args_max_length = 1024 # The limit of length of serialized session code arguments. session_args_max_length = 1024 [wasm.v1] # Amount of free memory (in 64kB pages) each contract can use for stack. max_memory = 64 # Max stack height (native WebAssembly stack limiter). max_stack_height = 500 [storage_costs] # Gas charged per byte stored in the global state. gas_per_byte = 1_117_587 # For each opcode cost below there exists a static cost and a dynamic cost. # The static cost is a fixed cost for each opcode that is hardcoded and validated by benchmarks. [wasm.v1.opcode_costs] # Bit operations multiplier. bit = 105 # Arithmetic add operations multiplier. add = 105 # Mul operations multiplier. mul = 105 # Div operations multiplier. div = 105 # Memory load operation multiplier. load = 105 # Memory store operation multiplier. store = 105 # Const store operation multiplier. const = 105 # Local operations multiplier. local = 105 # Global operations multiplier. global = 105 # Integer operations multiplier. integer_comparison = 105 # Conversion operations multiplier. conversion = 105 # Unreachable operation multiplier. unreachable = 105 # Nop operation multiplier. nop = 105 # Get current memory operation multiplier. current_memory = 105 # Grow memory cost, per page (64kb). grow_memory = 900 # Sign extension operations cost sign = 105 # Control flow operations multiplier. [wasm.v1.opcode_costs.control_flow] block = 255 loop = 255 if = 105 else = 105 end = 105 br = 1665 br_if = 510 return = 105 select = 105 call = 225 call_indirect = 270 drop = 105 [wasm.v1.opcode_costs.control_flow.br_table] # Fixed cost per `br_table` opcode cost = 150 # Size of target labels in the `br_table` opcode will be multiplied by `size_multiplier` size_multiplier = 100 # Host function declarations are located in smart_contracts/contract/src/ext_ffi.rs [wasm.v1.host_function_costs] add = { cost = 5_800, arguments = [0, 0, 0, 0] } add_associated_key = { cost = 1_200_000, arguments = [0, 0, 0] } add_contract_version = { cost = 200, arguments = [0, 0, 0, 0, 120_000, 0, 0, 0, 0, 0] } add_contract_version_with_message_topics = { cost = 200, arguments = [0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0] } add_package_version_with_message_topics = { cost = 200, arguments = [0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0] } blake2b = { cost = 1_200_000, arguments = [0, 120_000, 0, 0] } call_contract = { cost = 300_000_000, arguments = [0, 0, 0, 120_000, 0, 120_000, 0] } call_versioned_contract = { cost = 300_000_000, arguments = [0, 0, 0, 0, 0, 120_000, 0, 120_000, 0] } create_contract_package_at_hash = { cost = 200, arguments = [0, 0] } create_contract_user_group = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0] } create_purse = { cost = 2_500_000_000, arguments = [0, 0] } disable_contract_version = { cost = 200, arguments = [0, 0, 0, 0] } get_balance = { cost = 3_000_000, arguments = [0, 0, 0] } get_blocktime = { cost = 330, arguments = [0] } get_caller = { cost = 380, arguments = [0] } get_key = { cost = 2_000, arguments = [0, 440, 0, 0, 0] } get_main_purse = { cost = 1_300, arguments = [0] } get_named_arg = { cost = 200, arguments = [0, 120_000, 0, 120_000] } get_named_arg_size = { cost = 200, arguments = [0, 0, 0] } get_phase = { cost = 710, arguments = [0] } get_system_contract = { cost = 1_100, arguments = [0, 0, 0] } has_key = { cost = 1_500, arguments = [0, 840] } is_valid_uref = { cost = 760, arguments = [0, 0] } load_named_keys = { cost = 42_000, arguments = [0, 0] } new_uref = { cost = 17_000, arguments = [0, 0, 590] } random_bytes = { cost = 200, arguments = [0, 0] } print = { cost = 20_000, arguments = [0, 4_600] } provision_contract_user_group_uref = { cost = 200, arguments = [0, 0, 0, 0, 0] } put_key = { cost = 100_000_000, arguments = [0, 120_000, 0, 120_000] } read_host_buffer = { cost = 3_500, arguments = [0, 310, 0] } read_value = { cost = 60_000, arguments = [0, 120_000, 0] } dictionary_get = { cost = 5_500, arguments = [0, 590, 0] } remove_associated_key = { cost = 4_200, arguments = [0, 0] } remove_contract_user_group = { cost = 200, arguments = [0, 0, 0, 0] } remove_contract_user_group_urefs = { cost = 200, arguments = [0, 0, 0, 0, 0, 120_000] } remove_key = { cost = 61_000, arguments = [0, 3_200] } ret = { cost = 23_000, arguments = [0, 420_000] } revert = { cost = 500, arguments = [0] } set_action_threshold = { cost = 74_000, arguments = [0, 0] } transfer_from_purse_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0] } transfer_from_purse_to_purse = { cost = 82_000_000, arguments = [0, 0, 0, 0, 0, 0, 0, 0] } transfer_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0] } update_associated_key = { cost = 4_200, arguments = [0, 0, 0] } write = { cost = 14_000, arguments = [0, 0, 0, 980] } dictionary_put = { cost = 9_500, arguments = [0, 1_800, 0, 520] } enable_contract_version = { cost = 200, arguments = [0, 0, 0, 0] } manage_message_topic = { cost = 200, arguments = [0, 30_000, 0, 0] } emit_message = { cost = 200, arguments = [0, 30_000, 0, 120_000] } generic_hash = { cost = 1_200_000, arguments = [0, 120_000, 0, 0, 0] } cost_increase_per_message = 50 get_block_info = { cost = 330, arguments = [0, 0] } recover_secp256k1 = { cost = 1_300_000, arguments = [0, 120_000, 0, 0, 0, 0] } verify_signature = { cost = 1_300_000, arguments = [0, 120_000, 0, 0, 0, 0] } call_package_version = { cost = 300_000_000, arguments = [0, 0, 0, 0, 0, 0, 0, 120_000, 0, 120_000, 0] } [wasm.v2] # Amount of free memory each contract can use for stack. max_memory = 64 [wasm.v2.opcode_costs] # Bit operations multiplier. bit = 105 # Arithmetic add operations multiplier. add = 105 # Mul operations multiplier. mul = 105 # Div operations multiplier. div = 105 # Memory load operation multiplier. load = 105 # Memory store operation multiplier. store = 105 # Const store operation multiplier. const = 105 # Local operations multiplier. local = 105 # Global operations multiplier. global = 105 # Integer operations multiplier. integer_comparison = 105 # Conversion operations multiplier. conversion = 105 # Unreachable operation multiplier. unreachable = 105 # Nop operation multiplier. nop = 105 # Get current memory operation multiplier. current_memory = 105 # Grow memory cost, per page (64kb). grow_memory = 900 # Sign extension operations cost sign = 105 # Control flow operations multiplier. [wasm.v2.opcode_costs.control_flow] block = 255 loop = 255 if = 105 else = 105 end = 105 br = 1665 br_if = 510 return = 105 select = 105 call = 225 call_indirect = 270 drop = 105 [wasm.v2.opcode_costs.control_flow.br_table] # Fixed cost per `br_table` opcode cost = 150 # Size of target labels in the `br_table` opcode will be multiplied by `size_multiplier` size_multiplier = 100 [wasm.v2.host_function_costs] read = { cost = 0, arguments = [0, 0, 0, 0, 0, 0] } write = { cost = 0, arguments = [0, 0, 0, 0, 0] } remove = { cost = 0, arguments = [0, 0, 0] } copy_input = { cost = 0, arguments = [0, 0] } ret = { cost = 0, arguments = [0, 0] } create = { cost = 0, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] } transfer = { cost = 0, arguments = [0, 0, 0] } env_balance = { cost = 0, arguments = [0, 0, 0, 0] } upgrade = { cost = 0, arguments = [0, 0, 0, 0, 0, 0] } call = { cost = 0, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0] } print = { cost = 0, arguments = [0, 0] } emit = { cost = 0, arguments = [0, 0, 0, 0] } env_info = { cost = 0, arguments = [0, 0] } [wasm.messages_limits] max_topic_name_size = 256 max_topics_per_contract = 128 max_message_size = 1_024 [system_costs] # Penalty charge for calling invalid entry point in a system contract. no_such_entrypoint = 2_500_000_000 [system_costs.auction_costs] get_era_validators = 2_500_000_000 read_seigniorage_recipients = 5_000_000_000 add_bid = 2_500_000_000 withdraw_bid = 2_500_000_000 delegate = 2_500_000_000 undelegate = 2_500_000_000 run_auction = 2_500_000_000 slash = 2_500_000_000 distribute = 2_500_000_000 withdraw_delegator_reward = 5_000_000_000 withdraw_validator_reward = 5_000_000_000 read_era_id = 2_500_000_000 activate_bid = 2_500_000_000 redelegate = 2_500_000_000 change_bid_public_key = 5_000_000_000 add_reservations = 2_500_000_000 cancel_reservations = 2_500_000_000 [system_costs.mint_costs] mint = 2_500_000_000 reduce_total_supply = 2_500_000_000 create = 2_500_000_000 balance = 100_000_000 burn = 100_000_000 transfer = 100_000_000 read_base_round_reward = 2_500_000_000 mint_into_existing_purse = 2_500_000_000 [system_costs.handle_payment_costs] get_payment_purse = 10_000 set_refund_purse = 10_000 get_refund_purse = 10_000 finalize_payment = 2_500_000_000 [system_costs.standard_payment_costs] pay = 10_000 [vacancy] # The cost of a transaction is based on a multiplier. This allows for economic disincentives for misuse of the network. # # The network starts with a current_gas_price of min_gas_price. # # Each block has multiple limits (bytes, transactions, transfers, gas, etc.) # The utilization for a block is determined by the highest percentage utilization of each these limits. # # Ex: transfers limit is 650 and transactions limit is 20 (assume other limits are not a factor here) # 19 transactons -> 19/20 or 95% # 600 transfers -> 600/650 or 92.3% # resulting block utilization is 95 # # The utilization for an era is the average of all block utilizations. At the switch block, the dynamic gas_price is # adjusted with the following: # # If utilization was below the lower_threshold, current_gas_price is decremented by one if higher than min_gas_price. # If utilization falls between the thresholds, current_gas_price is not changed. # If utilization was above the upper_threshold, current_gas_price is incremented by one if lower than max_gas_price. # # The cost charged for the transaction is simply the gas_used * current_gas_price. upper_threshold = 90 lower_threshold = 50 max_gas_price = 1 min_gas_price = 1