Skip to content

Commit

Permalink
tested what happens if submsg recipient suceeds but caller fails via …
Browse files Browse the repository at this point in the history
…a faulty sdk msg. once when this msg is added on the reply endpoint, and once on the regular execute
  • Loading branch information
eshelB committed Sep 24, 2023
1 parent 169795a commit aac36ae
Show file tree
Hide file tree
Showing 7 changed files with 228 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -645,18 +645,50 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> S
}
ExecuteMsg::IncrementAndSendFailingSubmessage { reply_on } => {
increment_simple(deps)?;
let mut response = send_failing_submsg(env, reply_on)?;
response.data = Some((count as u32).to_be_bytes().into());
let response = send_failing_submsg(env, reply_on)?;

Ok(response)
},
ExecuteMsg::IncrementAndSendSubmessageWithBankFail { reply_on } => {
increment_simple(deps)?;
let mut response = send_failing_submsg_with_bank_fail(env, reply_on)?;
response.data = Some((count as u32).to_be_bytes().into());
let response = send_failing_submsg_with_bank_fail(env, reply_on)?;

Ok(response)
},
ExecuteMsg::SendSucceedingSubmessageThenFailingMessageOnReply {} => {
increment_simple(deps)?;

let mut response = Response::default();
add_succeeding_submsg(env, &mut response, ReplyOn::Always, 9201);

// failing message is created on reply
Ok(response)
},
ExecuteMsg::SendSucceedingSubmessageAndFailingMessage {} => {
increment_simple(deps)?;

let mut response = Response::default();

// add_succeeding_submsg(env, &mut response, ReplyOn::Always, 9201);

// response = response.add_message(
// CosmosMsg::Bank(BankMsg::Send {
// to_address: "non-existent".to_string(),
// amount: vec![Coin::new(100, "non-existent")],
// })
// );

response = response.add_message(
CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: env.contract.address.clone().into_string(),
code_hash: env.contract.code_hash.clone(),
msg: Binary::from(r#"{"quick_error":{}}"#.as_bytes().to_vec()),
funds: vec![],
})
);

Ok(response)
}
ExecuteMsg::InitV10 {
counter,
code_id,
Expand Down Expand Up @@ -1767,6 +1799,34 @@ pub fn send_multiple_sub_messages_with_reply_with_error(
Ok(resp)
}

pub fn add_succeeding_submsg(
env: Env,
resp: &mut Response,
reply_on: ReplyOn,
id: u64,
) {
let message = ExecuteMsg::Increment { addition: 3 };

let message = Binary::from(
serde_json_wasm::to_string(&message)
.unwrap()
.as_bytes()
.to_vec()
);

resp.messages.push(SubMsg {
id: id,
msg: CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: env.contract.address.clone().into_string(),
code_hash: env.contract.code_hash.clone(),
msg: message,
funds: vec![],
}),
gas_limit: Some(10000000_u64),
reply_on,
});
}

pub fn send_failing_submsg_with_bank_fail(
env: Env,
reply_on: ReplyOn,
Expand All @@ -1785,7 +1845,7 @@ pub fn send_failing_submsg_with_bank_fail(

let mut resp = Response::default();
resp.messages.push(SubMsg {
id: 9200,
id: 9202,
msg: CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: env.contract.address.clone().into_string(),
code_hash: env.contract.code_hash.clone(),
Expand Down Expand Up @@ -2336,9 +2396,28 @@ pub fn reply(deps: DepsMut, env: Env, reply: Reply) -> StdResult<Response> {
(9200, SubMsgResult::Err(_)) => Ok(Response::default().set_data(
(count_read(deps.storage).load()? as u32).to_be_bytes()
)),
(11337, SubMsgResult::Ok(SubMsgResponse { data, .. })) => {
(9201, _) => {
// check that the submessage worked
if count_read(deps.storage).load()? != 14 {
return Ok(Response::default()); // test expects error, so this will fail the test
}

increment_simple(deps)?;

let response = Response::default().add_message(
CosmosMsg::Bank(BankMsg::Send {
to_address: "non-existent".to_string(),
amount: vec![Coin::new(100, "non-existent")],
})
);

Ok(response)
},
(9202, _) => {
increment_simple(deps)?;
Ok(Response::default())
},
(11337, SubMsgResult::Ok(SubMsgResponse { data, .. })) => {
let ( contract_addr,
new_code_id,
callback_code_hash,
Expand All @@ -2360,10 +2439,6 @@ pub fn reply(deps: DepsMut, env: Env, reply: Reply) -> StdResult<Response> {
},
};





Ok(
Response::new().add_message(CosmosMsg::Wasm(WasmMsg::Migrate {
contract_addr,
Expand All @@ -2375,46 +2450,36 @@ pub fn reply(deps: DepsMut, env: Env, reply: Reply) -> StdResult<Response> {
}
(11338, SubMsgResult::Ok(SubMsgResponse { data, .. })) => {
let contract_addr= match from_binary(&data.unwrap()) {
Ok(ExecuteMsg::SendMsgClearAdmin {
contract_addr,
..
}) => contract_addr,

Ok(_) => {
return Err(StdError::generic_err("cannot parse into SendMsgClearAdmin"));

}
Err(err) => {
return Err(StdError::generic_err(format!("cannot parse into SendMsgClearAdmin: {:?}",err)));
Ok(ExecuteMsg::SendMsgClearAdmin {
contract_addr,
..
}) => contract_addr,

},
};
Ok(_) => {
return Err(StdError::generic_err("cannot parse into SendMsgClearAdmin"));

}
Err(err) => {
return Err(StdError::generic_err(format!("cannot parse into SendMsgClearAdmin: {:?}",err)));

},
};
Ok(Response::new().add_message(CosmosMsg::Wasm(WasmMsg::ClearAdmin { contract_addr })))
}
(11339, SubMsgResult::Ok(SubMsgResponse { data, .. })) => {
let ( contract_addr,
new_admin)= match from_binary(&data.unwrap()) {
Ok(ExecuteMsg::SendMsgUpdateAdmin {
contract_addr,
new_admin,
..
}) => ( contract_addr,
new_admin),
let (contract_addr, new_admin) = match from_binary(&data.unwrap()) {
Ok(ExecuteMsg::SendMsgUpdateAdmin {
contract_addr,
new_admin,
..
}) => (contract_addr, new_admin),
Ok(_) => {
return Err(StdError::generic_err("cannot parse into SendMsgUpdateAdmin"));

return Err(StdError::generic_err("cannot parse into SendMsgUpdateAdmin"));
}
Err(err) => {
return Err(StdError::generic_err(format!("cannot parse into SendMsgUpdateAdmin: {:?}",err)));

},
};




Err(err) => {
return Err(StdError::generic_err(format!("cannot parse into SendMsgUpdateAdmin: {:?}",err)));
},
};
Ok(Response::new().add_message(
CosmosMsg::Wasm(WasmMsg::UpdateAdmin {
contract_addr,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ pub enum ExecuteMsg {
IncrementAndSendSubmessageWithBankFail {
reply_on: ReplyOn,
},
SendSucceedingSubmessageThenFailingMessageOnReply {},
SendSucceedingSubmessageAndFailingMessage {},
InitV10 {
code_id: u64,
code_hash: String,
Expand Down
4 changes: 2 additions & 2 deletions go-cosmwasm/types/systemerror.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ func (e ExceededRecursionLimit) Error() string {
return "unknown system error"
}

// ToSystemError will try to convert the given error to an SystemError.
// This is important to returning any Go error back to Rust.
// ToSystemError will try to convert the given error to a SystemError.
// This is important for returning any Go error back to Rust.
//
// If it is already StdError, return self.
// If it is an error, which could be a sub-field of StdError, embed it.
Expand Down
2 changes: 1 addition & 1 deletion x/compute/internal/keeper/msg_dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ func (d MessageDispatcher) DispatchSubmessages(ctx sdk.Context, contractAddr sdk
// In a case when the reply is encrypted but the sdk failed (Most likely, funds issue)
// we return a error
if isReplyEncrypted(msg) && isSdkError {
return nil, fmt.Errorf("an sdk error occoured while sending a sub-message: %s", redactedErr.Error())
return nil, fmt.Errorf("an sdk error occurred while sending a sub-message: %s", redactedErr.Error())
}

if isReplyEncrypted(msg) {
Expand Down
2 changes: 1 addition & 1 deletion x/compute/internal/keeper/secret_contracts_exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1594,7 +1594,7 @@ func TestV1SendsFundsWithErrorWithReply(t *testing.T) {
_, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"send_funds_with_error_with_reply":{}}`, false, true, math.MaxUint64, 0)

require.NotEmpty(t, err)
require.Contains(t, fmt.Sprintf("%+v", err), "an sdk error occoured while sending a sub-message")
require.Contains(t, fmt.Sprintf("%+v", err), "an sdk error occurred while sending a sub-message")
}

func TestCallbackSanity(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions x/compute/internal/keeper/secret_contracts_migrate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1579,7 +1579,7 @@ func TestV1SendsFundsWithErrorWithReplyAfterMigrate(t *testing.T) {
_, _, _, _, _, err := execHelper(t, keeper, ctx, contractAddress, walletA, privKeyA, `{"send_funds_with_error_with_reply":{}}`, false, testContract.IsCosmWasmV1After, math.MaxUint64, 0)

require.NotEmpty(t, err)
require.Contains(t, fmt.Sprintf("%+v", err), "an sdk error occoured while sending a sub-message")
require.Contains(t, fmt.Sprintf("%+v", err), "an sdk error occurred while sending a sub-message")
})
}
}
Expand Down Expand Up @@ -3899,7 +3899,7 @@ func TestV1SendsFundsWithErrorWithReplyDuringMigrate(t *testing.T) {
_, err := migrateHelper(t, keeper, ctx, newCodeId, contractAddress, walletA, privKeyA, `{"send_funds_with_error_with_reply":{}}`, false, testContract.IsCosmWasmV1After, math.MaxUint64)

require.NotEmpty(t, err)
require.Contains(t, fmt.Sprintf("%+v", err), "an sdk error occoured while sending a sub-message")
require.Contains(t, fmt.Sprintf("%+v", err), "an sdk error occurred while sending a sub-message")
})
}
}
Expand Down
Loading

0 comments on commit aac36ae

Please sign in to comment.