-
Notifications
You must be signed in to change notification settings - Fork 20
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
dispatch incoming messages #832
base: main
Are you sure you want to change the base?
Conversation
Codecov Report
@@ Coverage Diff @@
## main #832 +/- ##
===========================================
- Coverage 68.17% 28.18% -40.00%
===========================================
Files 128 26 -102
Lines 11101 1902 -9199
===========================================
- Hits 7568 536 -7032
+ Misses 3501 1334 -2167
Partials 32 32 Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
new systems, similar to what we have for transactions.
|
An idea came up in our internal discussion: maybe we could re-use a lot of existing systems by having the payload be (contain, imo) a transaction in the format we already have. I'm going to try coding that up. |
b913b1c
to
5c16442
Compare
turns out a lot of handler methods I previously declared as Result<_, core::Error> should really be using RuntimeError as the error type |
5c16442
to
b5b3ba5
Compare
) -> Result<ExecuteBatchResult, RuntimeError> { | ||
let cfg = R::SCHEDULE_CONTROL.unwrap(); // Must succeed otherwise we wouldn't be here. | ||
let mut tx_reject_hashes = Vec::new(); | ||
|
||
let mut result = self.execute_batch_common( | ||
rt_ctx, | ||
|ctx| -> Result<Vec<ExecuteTxResult>, RuntimeError> { | ||
// Execute incoming messages. | ||
for in_msg in in_msgs { |
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 a certain per-block gas limit reserved for incoming messages and we should only include so many. Additionally we could also include a per-msg gas limit.
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.
added a per-block gas limit
117ded0
to
524cfcc
Compare
52e2e08
to
2877907
Compare
added doc comments. fixed mint_into_fee_accumulator not adjusting total supply |
2877907
to
f83c2a8
Compare
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.
Hm so one thing I noticed is that this makes it quite hard to see what was actually processed and what was the result as all results are just dropped. Should we figure out a better way for handling these?
A simple way would be to emit events that contain the message ID and result of processing the message.
@@ -250,6 +250,12 @@ impl From<Address> for ConsensusAddress { | |||
} | |||
} | |||
|
|||
impl From<&ConsensusAddress> for Address { | |||
fn from(addr: &ConsensusAddress) -> Address { | |||
Address::from_bytes(addr.as_ref()).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.
Let's add a unit test.
runtime-sdk/src/types/in_msg.rs
Outdated
pub version: u16, | ||
/// An embedded transaction (UnverifiedTransaction). | ||
/// The transaction doesn't need to be from the same account that sent the message. | ||
pub ut: Option<Vec<u8>>, |
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.
I see, so transactions are optional and you can also have messages that don't include transactions. I assume that if you want to just do a deposit, you don't need a transaction?
runtime-sdk/src/dispatcher.rs
Outdated
warn!(ctx.get_logger("dispatcher"), "incoming message data malformed"; "id" => in_msg.id, "err" => ?err); | ||
IncomingMessageData::noop() | ||
}); | ||
let tx = match data.ut.as_ref() { |
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.
Hm so this implementation is not synced with just execute
which may cause discrepancies (e.g. the proposer runs schedule_and_execute
while workers only run execute
). Should probably have a unified implementation if possible (could this go to execute_batch_common
instead?).
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 should be synced up, other than the logic to determine how many messages fit within the incoming messages gas limit. unification runs into the same concerns as the transaction processing: during non-scheduling execution, we've thus far preferred to parse all txes first; during scheduling execution, we parse and execute one by one.
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.
oh although one thing about this: enforcing the incoming messages gas limit is not done under consensus. only the scheduler chooses
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.
other than the logic to determine how many messages fit within the incoming messages gas limit
But the proposer does not communicate how many messages were chosen to executors. So if executors don't use the same logic for choosing messages, there will be discrepancies.
This would be different if we go with the design that emits incoming messages as transactions as then the proposer would decide how many to process (and executors would just need to verify that the messages are actually correct and in order as determined by the consensus layer).
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.
oh okay then
data: &IncomingMessageData, | ||
tx: &Option<Transaction>, | ||
) -> Result<(), RuntimeError> { | ||
R::Modules::execute_in_msg(ctx, in_msg, data, tx)?; |
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.
Note that returning an error here will cause a batch abort.
} | ||
|
||
/// Execute an incoming message, except for the embedded transaction. The dispatcher will | ||
/// invoke the transaction and method handlers for the embedded transaction separately. |
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.
We should probably explicitly mention that returning an error here will cause a batch abort (and possibly stall the whole runtime as any future batch will also include this same message). So returning errors here must be considered carefully.
Also it should be noted that this executes in the batch-wide context and so any effects will not be rolled back even if the inner transaction fails.
discussed this morning: we'd like to take some more time to think about how to make the transactions delivered this way and the results of those transactions more easily available |
43b19fb
to
b9fee1e
Compare
another issue: we discard the transaction results, which includes the tags. that's too weird. I'm converting this PR to a draft. |
b9fee1e
to
c85b000
Compare
c85b000
to
06b2df5
Compare
cross reference oasisprotocol/oasis-core#4681 |
rebasing, but we'll need to redo major parts of this now that we'll be relying on oasis-core to replicate the incoming messages' data as transactions |
06b2df5
to
5c2f73c
Compare
for #821