revm_interpreter/interpreter/
serde.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use super::Interpreter;
use crate::{
    Contract, FunctionStack, Gas, InstructionResult, InterpreterAction, SharedMemory, Stack,
};
use primitives::Bytes;
use serde::{Deserialize, Deserializer, Serialize, Serializer};

#[derive(Serialize)]
struct InterpreterSerde<'a> {
    program_counter: usize,

    gas: &'a Gas,
    contract: &'a Contract,
    instruction_result: InstructionResult,
    bytecode: &'a Bytes,
    is_eof: bool,
    is_eof_init: bool,
    shared_memory: &'a SharedMemory,
    stack: &'a Stack,
    function_stack: &'a FunctionStack,
    return_data_buffer: &'a Bytes,
    is_static: bool,
    next_action: &'a InterpreterAction,
}

#[derive(Deserialize)]
struct InterpreterDe {
    program_counter: usize,

    gas: Gas,
    contract: Contract,
    instruction_result: InstructionResult,
    bytecode: Bytes,
    is_eof: bool,
    is_eof_init: bool,
    shared_memory: SharedMemory,
    stack: Stack,
    function_stack: FunctionStack,
    return_data_buffer: Bytes,
    is_static: bool,
    next_action: InterpreterAction,
}

impl Serialize for Interpreter {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        InterpreterSerde {
            program_counter: self.program_counter(),
            gas: &self.gas,
            contract: &self.contract,
            instruction_result: self.instruction_result,
            bytecode: &self.bytecode,
            is_eof: self.is_eof,
            is_eof_init: self.is_eof_init,
            shared_memory: &self.shared_memory,
            stack: &self.stack,
            function_stack: &self.function_stack,
            return_data_buffer: &self.return_data_buffer,
            is_static: self.is_static,
            next_action: &self.next_action,
        }
        .serialize(serializer)
    }
}

impl<'de> Deserialize<'de> for Interpreter {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let InterpreterDe {
            program_counter,
            gas,
            contract,
            instruction_result,
            bytecode,
            is_eof,
            is_eof_init,
            shared_memory,
            stack,
            function_stack,
            return_data_buffer,
            is_static,
            next_action,
        } = InterpreterDe::deserialize(deserializer)?;

        // Reconstruct the instruction pointer from usize
        if program_counter >= bytecode.len() {
            return Err(serde::de::Error::custom("program_counter out of bounds"));
        }

        // SAFETY: range of program_counter checked above
        let instruction_pointer = unsafe { bytecode.as_ptr().add(program_counter) };

        Ok(Interpreter {
            instruction_pointer,
            gas,
            contract,
            instruction_result,
            bytecode,
            is_eof,
            is_eof_init,
            shared_memory,
            stack,
            function_stack,
            return_data_buffer,
            is_static,
            next_action,
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_serde() {
        let interp = Interpreter::new(Contract::default(), u64::MAX, false);
        let serialized = bincode::serialize(&interp).unwrap();
        let de: Interpreter = bincode::deserialize(&serialized).unwrap();
        assert_eq!(interp.program_counter(), de.program_counter());
    }
}