Skip to content

Commit

Permalink
Fix the volatileGet to not revert with OutOfGas when key does not exist
Browse files Browse the repository at this point in the history
  • Loading branch information
MoeMahhouk committed Mar 19, 2024
1 parent 4a47c01 commit fc0937a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 9 deletions.
6 changes: 3 additions & 3 deletions examples/Andromeda.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ contract Andromeda {
require(success);
}

function volatileGet(bytes32 key) public view returns (bytes32) {
function volatileGet(bytes32 key) public view returns (bool status, bytes32 val) {
(bool success, bytes memory value) = VOLATILEGET_ADDR.staticcall(abi.encodePacked((key)));
require(success);
require(value.length == 32);
return abi.decode(value, (bytes32));
// decode value into a boolean status and a bytes32 value
(status, val) = abi.decode(value, (bool, bytes32));
}

function attestSgx(bytes memory userdata) public view returns (bytes memory) {
Expand Down
45 changes: 41 additions & 4 deletions examples/andromeda_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fn simulate() -> eyre::Result<()> {
"function localRandom() returns (bytes32)",
"function attestSgx(bytes) returns (bytes)",
"function volatileSet(bytes32,bytes32)",
"function volatileGet(bytes32) returns (bytes32)",
"function volatileGet(bytes32) returns (bool, bytes32)",
"function sha512(bytes) returns (bytes)",
"struct HttpRequest { string url; string method; string[] headers; bytes body; bool withFlashbotsSignature; }",
"function doHTTPRequest(HttpRequest memory request) returns (bytes memory)",
Expand Down Expand Up @@ -89,7 +89,7 @@ fn simulate() -> eyre::Result<()> {
{
let calldata = abi.encode(
"volatileSet",
(Token::FixedBytes(mykey.clone()), Token::FixedBytes(myval)),
(Token::FixedBytes(mykey.clone()), Token::FixedBytes(myval.clone())),
)?;
evm.context.env.tx = TxEnv {
caller: ADDR_A,
Expand All @@ -100,6 +100,7 @@ fn simulate() -> eyre::Result<()> {
let _result = evm.transact()?;
//dbg!(result);
}
// Existing key test
{
let calldata = abi.encode("volatileGet", (Token::FixedBytes(mykey),))?;
evm.context.env.tx = TxEnv {
Expand All @@ -110,15 +111,51 @@ fn simulate() -> eyre::Result<()> {
};
let result = evm.transact()?;
let decoded = ethabi::decode(
&[ethabi::ParamType::FixedBytes(32)],
&[ethabi::ParamType::Bool, ethabi::ParamType::FixedBytes(32)],
result.result.output().unwrap(),
)?;
let val = match &decoded[0] {
let status = match &decoded[0] {
Token::Bool(b) => b,
_ => todo!(),
};
assert_eq!(status, &true);
let val = match &decoded[1] {
Token::FixedBytes(b) => b,
_ => todo!(),
};
assert_eq!(val.to_vec(), myval);

dbg!(std::str::from_utf8(val).unwrap());
}
// Non-existing key test
{
let nonExistingKey = "beefdeadbeefdeadbeefdeadbeefdead".as_bytes().to_vec();
let calldata = abi.encode("volatileGet", (Token::FixedBytes(nonExistingKey),))?;
evm.context.env.tx = TxEnv {
caller: ADDR_A,
transact_to: revm::primitives::TransactTo::Call(ADDR_B),
data: revm::primitives::Bytes::from(calldata.0),
..Default::default()
};
let result = evm.transact()?;
let decoded = ethabi::decode(
&[ethabi::ParamType::Bool, ethabi::ParamType::FixedBytes(32)],
result.result.output().unwrap(),
)?;
let status = match &decoded[0] {
Token::Bool(b) => b,
_ => todo!(),
};
assert_eq!(status, &false);
let val = match &decoded[1] {
Token::FixedBytes(b) => b,
_ => todo!(),
};
assert_eq!(val.to_vec(), vec![0u8; 32]);
//dbg!(std::str::from_utf8(val).unwrap());
}



//////////////////////////
// Suave.sha512
Expand Down
13 changes: 11 additions & 2 deletions src/precompiles/sgxattest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,19 @@ fn sgxattest_volatile_get(input: &[u8], gas_limit: u64, env: &Env) -> Precompile
let mut key: [u8; 52] = [0; 52];
key[0..20].copy_from_slice(&domain_sep.0 .0);
key[20..52].copy_from_slice(&input[0..32]);
let mut success = true;
let mut value = [0; 32];
if let Some(val) = vol.get(&key) {
return Ok((gas_used, val.to_vec()));
value = val.clone();
} else {
success = false;
}
return Err(SGX_VOLATILE_KEY_MISSING);
let result = &ethers::abi::encode(&[
Token::Bool(success),
Token::FixedBytes(value.to_vec()),
]);

return Ok((gas_used, result.to_vec()));
}
}

Expand Down

0 comments on commit fc0937a

Please sign in to comment.