|
| 1 | +use revm::{ |
| 2 | + interpreter::{ |
| 3 | + CallInputs, CallOutcome, CreateInputs, CreateOutcome, EOFCreateInputs, Interpreter, |
| 4 | + InterpreterTypes, |
| 5 | + }, |
| 6 | + primitives::{Address, Log, U256}, |
| 7 | + Inspector, |
| 8 | +}; |
| 9 | + |
| 10 | +/// A layer in a stack of inspectors. Contains its own inspector and an |
| 11 | +/// inner inspector. This is used to create a stack of inspectors that can |
| 12 | +/// be used to inspect the execution of a contract. |
| 13 | +/// |
| 14 | +/// Use `Layered` when you need to retain type information about the inner |
| 15 | +/// inspectors. |
| 16 | +/// |
| 17 | +/// The current inspector will be invoked first, then the inner inspector. |
| 18 | +/// For functions that may return values (e.g. [`Inspector::call`]), if the |
| 19 | +/// current inspector returns a value, the inner inspector will not be invoked. |
| 20 | +#[derive(Clone, Debug)] |
| 21 | +pub struct Layered<Outer, Inner> { |
| 22 | + outer: Outer, |
| 23 | + inner: Inner, |
| 24 | +} |
| 25 | + |
| 26 | +impl<Outer, Inner> Layered<Outer, Inner> { |
| 27 | + /// Create a new [`Layered`] inspector with the given current and inner |
| 28 | + /// inspectors. |
| 29 | + pub const fn new(outer: Outer, inner: Inner) -> Self { |
| 30 | + Self { outer, inner } |
| 31 | + } |
| 32 | + |
| 33 | + /// Wrap this inspector in another, creating a new [`Layered`] inspector. |
| 34 | + /// with this as the inner inspector. |
| 35 | + pub const fn wrap_in<Other>(self, outer: Other) -> Layered<Other, Self> { |
| 36 | + Layered { outer, inner: self } |
| 37 | + } |
| 38 | + |
| 39 | + /// Wrap this inspector around another, creating a new [`Layered`] inspector |
| 40 | + /// with this as the outer inspector. |
| 41 | + pub const fn wrap_around<Other>(self, inner: Other) -> Layered<Self, Other> { |
| 42 | + Layered { outer: self, inner } |
| 43 | + } |
| 44 | + |
| 45 | + /// Get a reference to the current inspector. |
| 46 | + pub const fn outer(&self) -> &Outer { |
| 47 | + &self.outer |
| 48 | + } |
| 49 | + |
| 50 | + /// Get a mutable reference to the current inspector. |
| 51 | + pub fn outer_mut(&mut self) -> &mut Outer { |
| 52 | + &mut self.outer |
| 53 | + } |
| 54 | + |
| 55 | + /// Get a reference to the inner inspector. |
| 56 | + pub const fn inner(&self) -> &Inner { |
| 57 | + &self.inner |
| 58 | + } |
| 59 | + |
| 60 | + /// Get a mutable reference to the inner inspector. |
| 61 | + pub fn inner_mut(&mut self) -> &mut Inner { |
| 62 | + &mut self.inner |
| 63 | + } |
| 64 | +} |
| 65 | + |
| 66 | +impl<Ctx, Int: InterpreterTypes, Outer, Inner> Inspector<Ctx, Int> for Layered<Outer, Inner> |
| 67 | +where |
| 68 | + Outer: Inspector<Ctx, Int>, |
| 69 | + Inner: Inspector<Ctx, Int>, |
| 70 | +{ |
| 71 | + fn initialize_interp(&mut self, interp: &mut Interpreter<Int>, context: &mut Ctx) { |
| 72 | + self.outer.initialize_interp(interp, context); |
| 73 | + self.inner.initialize_interp(interp, context); |
| 74 | + } |
| 75 | + |
| 76 | + fn step(&mut self, interp: &mut Interpreter<Int>, context: &mut Ctx) { |
| 77 | + self.outer.step(interp, context); |
| 78 | + self.inner.step(interp, context); |
| 79 | + } |
| 80 | + |
| 81 | + fn step_end(&mut self, interp: &mut Interpreter<Int>, context: &mut Ctx) { |
| 82 | + self.outer.step_end(interp, context); |
| 83 | + self.inner.step_end(interp, context); |
| 84 | + } |
| 85 | + |
| 86 | + fn log(&mut self, interp: &mut Interpreter<Int>, context: &mut Ctx, log: Log) { |
| 87 | + self.outer.log(interp, context, log.clone()); |
| 88 | + self.inner.log(interp, context, log); |
| 89 | + } |
| 90 | + |
| 91 | + fn call(&mut self, context: &mut Ctx, inputs: &mut CallInputs) -> Option<CallOutcome> { |
| 92 | + if let Some(outcome) = self.outer.call(context, inputs) { |
| 93 | + return Some(outcome); |
| 94 | + } |
| 95 | + self.inner.call(context, inputs) |
| 96 | + } |
| 97 | + |
| 98 | + fn call_end(&mut self, context: &mut Ctx, inputs: &CallInputs, outcome: &mut CallOutcome) { |
| 99 | + self.outer.call_end(context, inputs, outcome); |
| 100 | + self.inner.call_end(context, inputs, outcome); |
| 101 | + } |
| 102 | + |
| 103 | + fn create(&mut self, context: &mut Ctx, inputs: &mut CreateInputs) -> Option<CreateOutcome> { |
| 104 | + if let Some(outcome) = self.outer.create(context, inputs) { |
| 105 | + return Some(outcome); |
| 106 | + } |
| 107 | + self.inner.create(context, inputs) |
| 108 | + } |
| 109 | + |
| 110 | + fn create_end( |
| 111 | + &mut self, |
| 112 | + context: &mut Ctx, |
| 113 | + inputs: &CreateInputs, |
| 114 | + outcome: &mut CreateOutcome, |
| 115 | + ) { |
| 116 | + self.outer.create_end(context, inputs, outcome); |
| 117 | + self.inner.create_end(context, inputs, outcome); |
| 118 | + } |
| 119 | + |
| 120 | + fn eofcreate( |
| 121 | + &mut self, |
| 122 | + context: &mut Ctx, |
| 123 | + inputs: &mut EOFCreateInputs, |
| 124 | + ) -> Option<CreateOutcome> { |
| 125 | + if let Some(outcome) = self.outer.eofcreate(context, inputs) { |
| 126 | + return Some(outcome); |
| 127 | + } |
| 128 | + self.inner.eofcreate(context, inputs) |
| 129 | + } |
| 130 | + |
| 131 | + fn eofcreate_end( |
| 132 | + &mut self, |
| 133 | + context: &mut Ctx, |
| 134 | + inputs: &EOFCreateInputs, |
| 135 | + outcome: &mut CreateOutcome, |
| 136 | + ) { |
| 137 | + self.outer.eofcreate_end(context, inputs, outcome); |
| 138 | + self.inner.eofcreate_end(context, inputs, outcome); |
| 139 | + } |
| 140 | + |
| 141 | + fn selfdestruct(&mut self, contract: Address, target: Address, value: U256) { |
| 142 | + self.outer.selfdestruct(contract, target, value); |
| 143 | + self.inner.selfdestruct(contract, target, value); |
| 144 | + } |
| 145 | +} |
0 commit comments