spacemeshos / svm

SVM - Spacemesh Virtual Machine
https://spacemesh.io
MIT License
85 stars 14 forks source link

Add `Transaction Parts` offsets to `FuncEnv` #456

Open YaronWittenstein opened 2 years ago

YaronWittenstein commented 2 years ago

Depends on: #457

Wo so we've got the svm_codec::tx_offsets API returning us HashMap<TxPart, (usize, usize)> when given the binary Transaction.

Now we need to keep this data in the FuncEnv https://github.com/spacemeshos/svm/blob/master/crates/runtime/src/func_env.rs

First, we'll need the FuncEnv to have access to the transaction in its binary format. One option is to make sure that FuncEnv::new will receive tx: Arc<[u8]> as a parameter (or other Smart-Pointer).

Maybe we could also get rid of the Envelope parameter and only rely on the tx (I'm not sure about it, anyhow it's an implementation detail internal to SVM).

The Transaction Offsets will primarily be used in the context of verify (or authorize if we'll end up having that as well). It means we could make it a lazy field.

So this issue can extend Inner here: https://github.com/spacemeshos/svm/blob/6edb73de199fafce0953f82af061ca1090ff911c/crates/runtime/src/func_env.rs#L101

to have:

use std::sync::Once;

pub struct Inner {
  tx: Arc<[u8]>,
  tx_offsets_init: Once,
  tx_offsets: HashMap<TxPart, (usize, usize)>,
}

impl Inner {
  fn tx_offsets(&mut self, env: &FuncEnv) -> &HashMap<TxPart, (usize, usize)> {
    if self.tx_offsets_init.is_completed() {
       return &self.tx_offsets;
    }

    self.tx_offsets = self.tx_offsets_init.call_once(|| {
       svm_codec::tx_offsets(&*self.tx);
    });   
    &self.tx_offsets
  }
}

And each relevant host function interested in these tx_offsets will have something similar to this code:

fn host_func(env: &FuncEnv, ...) {
   let tx_offsets = env.borrow_mut().tx_offsets();
  // ...
}