-
Notifications
You must be signed in to change notification settings - Fork 707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove gas price #3141
Remove gas price #3141
Conversation
@massalabs/core-team @damip Still have to fix a few tests that are failing(see those currently ignored), sorry I still cannot access discord... |
81988b1
to
1542258
Compare
@@ -546,7 +546,7 @@ impl Interface for InterfaceImpl { | |||
validity_start: (u64, u8), | |||
validity_end: (u64, u8), | |||
max_gas: u64, | |||
gas_price: u64, | |||
_gas_price: u64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adrien-zinger I think removing this would change the public api for the running byte code correct? Is there a specific way to deal with such breaking changes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aoudiamoncef can you synchronize with @gterzian on that ? (through github)
@@ -16,33 +16,32 @@ | |||
//! | |||
//! ```json | |||
//! { | |||
//! "sender": "xxxx", // address that sent the message and spent max_gas*gas_price+coins on emission | |||
//! "sender": "xxxx", // address that sent the message and spent max_gas+coins on emission |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
max_gas
is not an amount of coins, but a quantity of gas.
=> address that sent the message and spent fee+coins
on emission
//! "slot": {"period": 123455, "thread": 11}, // slot at which the message was emitted | ||
//! "emission_index": 212, // index of the message emitted in this slot | ||
//! "destination": "xxxx", // target address | ||
//! "handler": "handle_message", // name of the handler function to call in the target SC | ||
//! "validity_start": {"period": 123456, "thread": 12}, // the message can be handled starting from the validity_start slot (included) | ||
//! "validity_end": {"period": 123457, "thread": 16}, // the message can be handled until the validity_end slot (excluded) | ||
//! "max_gas": 12334, // max gas available when the handler is called | ||
//! "gas_price": "124.23", // gas price for the handler call |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs to be replaced by a fee: Amount
property
//! "coins": "1111.11", // amount of coins to transfer to the destination address when calling its handler | ||
//! "data": { ... any object ... } // data payload of the message, passed as the sole parameter of the destination handler when called | ||
//! } | ||
//! ``` | ||
//! | ||
//! ## How to send a message during bytecode execution | ||
//! | ||
//! * messages are sent using an ABI: `send_message(target_address, target_handler, validity_start, validity_end, max_gas, gas_price, coins, data: JSON string) -> Result<(), ABIReturnError>`. Note that data has a configuration defined `max_async_message_data_size`. | ||
//! * messages are sent using an ABI: `send_message(target_address, target_handler, validity_start, validity_end, max_gas, coins, data: JSON string) -> Result<(), ABIReturnError>`. Note that data has a configuration defined `max_async_message_data_size`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gas_price
needs to be replaced by a fee
property
//! * when called, this ABI does this: | ||
//! * it consumes `compute_gas_cost_of_message_storage(context.current_slot, validity_end_slot)` of gas in the current execution. This allows making the message emission more gas-consuming when it requires storing the message in queue for longer | ||
//! * it consumes `max_gas * gas_price + coins` coins from the sender | ||
//! * it consumes `max_gas + coins` coins from the sender |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it consumes fee + coins
//! * it generates an `AsyncMessage` and stores it in an asynchronous pool | ||
//! | ||
//! Note that `max_gas*gas_price` coins are burned when sending the message. | ||
//! Note that `max_gas` coins are burned when sending the message. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gas and coins are fundamentally different resources.
fee
coins are burned when sending the message
//! | ||
//! ## How is the `AsyncPool` handled | ||
//! ```md | ||
//! * In the AsyncPool, Messages are kept sorted by `priority = AsyncMessageId(msg.max_gas * msg.gas_price, rev(msg.slot), rev(msg.emission_index))` | ||
//! * In the AsyncPool, Messages are kept sorted by `priority = AsyncMessageId(msg.max_gas, rev(msg.slot), rev(msg.emission_index))` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main sorting criterion should be message.fee
.
Sort by decreasing:
AsyncMessageId = (std::cmp::Reverse<Amount>, Slot, u64);
@@ -55,7 +54,6 @@ | |||
//! * credit target_address with M.coins | |||
//! * run the target handler function with M.payload as parameter and the context: | |||
//! * max_gas = M.max_gas | |||
//! * gas_price = M.gas_price |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fee = M.fee
/// `(rev(max_gas), emission_slot, emission_index)` | ||
pub type AsyncMessageId = (std::cmp::Reverse<u64>, Slot, u64); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's change it according to the comment above
|
||
pub struct AsyncMessageIdSerializer { | ||
amount_serializer: AmountSerializer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there should be an AmountSerializer for the fee
slot_serializer: SlotSerializer, | ||
u64_serializer: U64VarIntSerializer, | ||
} | ||
|
||
impl AsyncMessageIdSerializer { | ||
pub fn new() -> Self { | ||
Self { | ||
amount_serializer: AmountSerializer::new(), | ||
max_gas_serializer: U64VarIntSerializer::new(), | ||
slot_serializer: SlotSerializer::new(), | ||
u64_serializer: U64VarIntSerializer::new(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's rename this one emission_index_serializer
match gas_price | ||
.checked_mul_u64(max_gas) | ||
.and_then(|x| x.checked_add(fee)) | ||
match Amount::from_str(&max_gas.to_string()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gas is not an amount of coins. This check should be done on fee
property only
match gas_price | ||
.checked_mul_u64(max_gas) | ||
.and_then(|x| x.checked_add(fee)) | ||
match Amount::from_str(&max_gas.to_string()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here as well, just use coins.checked_add(fee)
@@ -231,7 +231,7 @@ impl ExecutionState { | |||
// get operation ID | |||
let operation_id = operation.id; | |||
|
|||
// compute fee from (op.max_gas * op.gas_price + op.fee) | |||
// compute fee from (op.max_gas + op.fee) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
total fee should just be op.fee
and nothing else
@@ -571,7 +571,6 @@ impl Interface for InterfaceImpl { | |||
validity_start: Slot::new(validity_start.0, validity_start.1), | |||
validity_end: Slot::new(validity_end.0, validity_end.1), | |||
max_gas, | |||
gas_price: Amount::from_raw(gas_price), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- this should be replaced by
fee: Amount
- massa-sc-runtime should also be updated
@@ -74,7 +74,6 @@ impl Serializer<StateChanges> for StateChangesSerializer { | |||
/// destination: Address::from_str("A12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(), | |||
/// handler: String::from("test"), | |||
/// max_gas: 10000000, | |||
/// gas_price: Amount::from_str("1").unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fee
@@ -168,7 +167,6 @@ impl Deserializer<StateChanges> for StateChangesDeserializer { | |||
/// destination: Address::from_str("A12htxRWiEm8jDJpJptr6cwEhWNcCSFWstN1MLSa96DDkVM9Y42G").unwrap(), | |||
/// handler: String::from("test"), | |||
/// max_gas: 10000000, | |||
/// gas_price: Amount::from_str("1").unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fee
self.get_gas_price() | ||
.saturating_mul_u64(self.get_gas_usage()) | ||
} | ||
|
||
/// Get the total fee paid by the creator | ||
pub fn get_total_fee(&self) -> Amount { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function is now useless. use op.fee directly
} => gas_price | ||
.saturating_mul_u64(*max_gas) | ||
OperationType::ExecuteSC { max_gas, .. } => { | ||
Amount::from_str(&max_gas.to_string()).unwrap_or(Amount::default()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here we should return just the coins
property of executesc
also, going through strings is inefficient
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems OperationType::ExecuteSC does not have coins
, would returning zero be appropriate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true, let's return Amount::zero() like in the case of RollSell
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
continuing over at #3173
so this PR is abandoned and you continue on 3173 ?
OperationType::ExecuteSC { max_gas, .. } => { | ||
Amount::from_str(&max_gas.to_string()).unwrap_or(Amount::default()) | ||
} | ||
OperationType::CallSC { max_gas, coins, .. } => Amount::from_str(&max_gas.to_string()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here we should return just the coins
property of CallSC
also, going through strings is inefficient
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a few misunderstandings that can be cleared by adding some documentation maybe:
- Only the
fee
parameter represents coins spent as fees, only themax_gas
parameter represents the amount of gas (computing power) expected to be spent during the execution, and only the size of the operation represents the amount of block space used by the operation - Coins, gas and block space are three different dimensions (see https://en.wikipedia.org/wiki/Dimensional_analysis )
- The Amount structure encodes Coins and nothing else (already documented for the Amount structure)
- gas is encoded as u64
- block space is encoded as u64
- quotes from https://en.wikipedia.org/wiki/Dimensional_analysis#Dimensional_homogeneity :
- One may take ratios of quantities with different dimensions, and multiply or divide them. However, only quantities having the same dimension may be compared, equated, added, or subtracted.
- this means that
max_gas + fee
is illegal butmax_gas / fee
is legal
- this means that
- One may take ratios of quantities with different dimensions, and multiply or divide them. However, only quantities having the same dimension may be compared, equated, added, or subtracted.
I've added the checklist to perform in order to consider this PR ready.
Let's make sure the PR is ready and reviewed by the end of the week.
@damip Thanks for the clarification! So the |
Yes exactly |
@gterzian I made a mistake in one of my comments above: the first criterion of the async pool sorting should not be msg.fee but rev(Ratio(msg.fee, max(msg.max_gas,1))) |
continuing over at #3173 |
Amount::from_str(&max_gas.to_string()).unwrap_or(Amount::default()) | ||
} | ||
OperationType::CallSC { max_gas, coins, .. } => Amount::from_str(&max_gas.to_string()) | ||
.unwrap_or(Amount::default()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clippy warn
} => gas_price | ||
.saturating_mul_u64(*max_gas) | ||
OperationType::ExecuteSC { max_gas, .. } => { | ||
Amount::from_str(&max_gas.to_string()).unwrap_or(Amount::default()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clippy warn
/// Get the total fee paid by the creator | ||
pub fn get_total_fee(&self) -> Amount { | ||
self.get_gas_coins().saturating_add(self.content.fee) | ||
self.content.fee.saturating_add( | ||
Amount::from_str(&self.get_gas_usage().to_string()).unwrap_or(Amount::default()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is a design problem here as well (see other remarks)
Closing in favor of #3173 |
FIX #3140