Skip to content

Commit

Permalink
[gh-1625] add test suite for creating session key from session key.
Browse files Browse the repository at this point in the history
  • Loading branch information
Feliciss committed May 13, 2024
1 parent 7911595 commit b17502c
Show file tree
Hide file tree
Showing 15 changed files with 238 additions and 51 deletions.
125 changes: 124 additions & 1 deletion crates/rooch-framework-tests/src/tests/transaction_validator_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn test_session_key_rooch() {
let sender = keystore.addresses()[0];
let sequence_number = 0;

let session_auth_key = keystore.generate_session_key(&sender, None).unwrap();
let session_auth_key = keystore.generate_session_key(&sender, None, None).unwrap();

let session_scope = SessionScope::new(
ROOCH_FRAMEWORK_ADDRESS,
Expand Down Expand Up @@ -148,3 +148,126 @@ fn test_session_key_rooch() {
}
}
}

#[test]
fn test_session_key_from_session_key_failure_rooch() {
// prepare test
let _ = tracing_subscriber::fmt::try_init();
let mut first_binding_test = binding_test::RustBindingTest::new().unwrap();

let mut keystore = InMemKeystore::new_insecure_for_tests(1);
let sender = keystore.addresses()[0];
let sequence_number = 0;

// create first session key
let first_session_auth_key = keystore.generate_session_key(&sender, None, None).unwrap();

let session_scope_clone = SessionScope::new(
ROOCH_FRAMEWORK_ADDRESS,
Empty::MODULE_NAME.as_str(),
Empty::EMPTY_FUNCTION_NAME.as_str(),
)
.unwrap();
let test_app_name = MoveString::from_str("test").unwrap();
let test_app_url = MoveAsciiString::from_str("https://test-seed.rooch.network").unwrap();
let max_inactive_interval = 100;
let test_action =
rooch_types::framework::session_key::SessionKeyModule::create_session_key_action(
test_app_name,
test_app_url,
first_session_auth_key.as_ref().to_vec(),
session_scope_clone.clone(),
max_inactive_interval,
);
let test_tx_data = RoochTransactionData::new_for_test(sender, sequence_number, test_action);
let test_tx = keystore
.sign_transaction(&sender, test_tx_data, None)
.unwrap();
first_binding_test.execute(test_tx).unwrap();

// bind first session key
let test_session_key_module = first_binding_test
.as_module_binding::<rooch_types::framework::session_key::SessionKeyModule>(
);
let test_session_key_option = test_session_key_module
.get_session_key(sender.into(), &first_session_auth_key)
.unwrap();
assert!(
test_session_key_option.is_some(),
"Test session key not found"
);
let test_session_key_clone = test_session_key_option.clone().unwrap();
assert_eq!(
&test_session_key_clone.authentication_key,
first_session_auth_key.as_ref()
);
assert_eq!(test_session_key_clone.scopes, vec![session_scope_clone]);
assert_eq!(
test_session_key_clone.max_inactive_interval,
max_inactive_interval
);
keystore
.binding_session_key(sender, test_session_key_clone)
.unwrap();

// send transaction via first session key
let test_action = MoveAction::new_function_call(Empty::empty_function_id(), vec![], vec![]);
let test_tx_data =
RoochTransactionData::new_for_test(sender, sequence_number + 1, test_action.clone());
let test_tx = keystore
.sign_transaction_via_session_key(
&sender,
test_tx_data.clone(),
&first_session_auth_key,
None,
)
.unwrap();
first_binding_test.execute(test_tx).unwrap();

// create second session key from first session key
let second_session_auth_key = keystore
.generate_session_key(&sender, None, test_session_key_option)
.unwrap();

let session_scope = SessionScope::new(
ROOCH_FRAMEWORK_ADDRESS,
Empty::MODULE_NAME.as_str(),
Empty::EMPTY_FUNCTION_NAME.as_str(),
)
.unwrap();
let dev_app_name = MoveString::from_str("dev").unwrap();
let dev_app_url = MoveAsciiString::from_str("https://dev-seed.rooch.network").unwrap();
let dev_action =
rooch_types::framework::session_key::SessionKeyModule::create_session_key_action(
dev_app_name,
dev_app_url,
second_session_auth_key.as_ref().to_vec(),
session_scope.clone(),
max_inactive_interval,
);
let dev_tx_data = RoochTransactionData::new_for_test(sender, sequence_number + 2, dev_action);
let dev_tx = keystore
.sign_transaction(&sender, dev_tx_data, None)
.unwrap();
first_binding_test.execute(dev_tx).unwrap();

// let dev_session_key_module =
// second_binding_test.as_module_binding::<rooch_types::framework::session_key::SessionKeyModule>();
// let dev_session_key_option = dev_session_key_module
// .get_session_key(sender.into(), &second_session_auth_key)
// .unwrap();
// assert!(dev_session_key_option.is_some(), "Dev session key not found");
// let dev_session_key = dev_session_key_option.unwrap();
// assert_eq!(&dev_session_key.authentication_key, second_session_auth_key.as_ref());
// assert_eq!(dev_session_key.scopes, vec![session_scope]);
// assert_eq!(dev_session_key.max_inactive_interval, max_inactive_interval);
// keystore.binding_session_key(sender, dev_session_key).unwrap();

// send transaction via second session key
// let dev_action = MoveAction::new_function_call(Empty::empty_function_id(), vec![], vec![]);
// let test_tx_data = RoochTransactionData::new_for_test(sender, sequence_number + 2, test_action.clone());
// let dev_tx = keystore
// .sign_transaction_via_session_key(&sender, test_tx_data.clone(), &second_session_auth_key, None)
// .unwrap();
// first_binding_test.execute(dev_tx).unwrap();
}
1 change: 1 addition & 0 deletions crates/rooch-key/src/keystore/account_keystore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ pub trait AccountKeystore {
&mut self,
address: &RoochAddress,
password: Option<String>,
session_key: Option<SessionKey>,
) -> Result<AuthenticationKey, anyhow::Error>;

/// Binding on-chain SessionKey to LocalSessionKey
Expand Down
3 changes: 2 additions & 1 deletion crates/rooch-key/src/keystore/base_keystore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ impl AccountKeystore for BaseKeyStore {
&mut self,
address: &RoochAddress,
password: Option<String>,
session_key: Option<SessionKey>,
) -> Result<AuthenticationKey, anyhow::Error> {
//TODO define derivation_path for session key
let result = generate_new_key_pair(None, None, None, password.clone())?;
Expand All @@ -231,7 +232,7 @@ impl AccountKeystore for BaseKeyStore {
let authentication_key = kp.public().authentication_key();
let inner_map = self.session_keys.entry(*address).or_default();
let local_session_key = LocalSessionKey {
session_key: None,
session_key,
private_key: result.key_pair_data.private_key_encryption,
};
inner_map.insert(authentication_key.clone(), local_session_key);
Expand Down
6 changes: 5 additions & 1 deletion crates/rooch-key/src/keystore/file_keystore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::key_derive::retrieve_key_pair;
use crate::keystore::account_keystore::AccountKeystore;
use crate::keystore::base_keystore::BaseKeyStore;
use anyhow::anyhow;
use rooch_types::framework::session_key::SessionKey;
use rooch_types::key_struct::{MnemonicData, MnemonicResult};
use rooch_types::{
address::RoochAddress,
Expand Down Expand Up @@ -137,8 +138,11 @@ impl AccountKeystore for FileBasedKeystore {
&mut self,
address: &RoochAddress,
password: Option<String>,
session_key: Option<SessionKey>,
) -> Result<AuthenticationKey, anyhow::Error> {
let auth_key = self.keystore.generate_session_key(address, password)?;
let auth_key = self
.keystore
.generate_session_key(address, password, session_key)?;
self.save()?;
Ok(auth_key)
}
Expand Down
5 changes: 4 additions & 1 deletion crates/rooch-key/src/keystore/memory_keystore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use super::types::LocalAccount;
use crate::key_derive::get_key_pair_from_red;
use crate::keystore::account_keystore::AccountKeystore;
use crate::keystore::base_keystore::BaseKeyStore;
use rooch_types::framework::session_key::SessionKey;
use rooch_types::key_struct::{MnemonicData, MnemonicResult};
use rooch_types::{
address::RoochAddress,
Expand Down Expand Up @@ -125,8 +126,10 @@ impl AccountKeystore for InMemKeystore {
&mut self,
address: &RoochAddress,
password: Option<String>,
session_key: Option<SessionKey>,
) -> Result<AuthenticationKey, anyhow::Error> {
self.keystore.generate_session_key(address, password)
self.keystore
.generate_session_key(address, password, session_key)
}

fn binding_session_key(
Expand Down
8 changes: 6 additions & 2 deletions crates/rooch-key/src/keystore/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::keystore::account_keystore::AccountKeystore;
use crate::keystore::file_keystore::FileBasedKeystore;
use enum_dispatch::enum_dispatch;
use memory_keystore::InMemKeystore;
use rooch_types::framework::session_key::SessionKey;
use rooch_types::key_struct::{MnemonicData, MnemonicResult};
use rooch_types::{
address::RoochAddress,
Expand Down Expand Up @@ -205,12 +206,15 @@ impl AccountKeystore for Keystore {
&mut self,
address: &RoochAddress,
password: Option<String>,
session_key: Option<SessionKey>,
) -> Result<AuthenticationKey, anyhow::Error> {
// Implement this method to generate a session key for the appropriate variant (File or InMem)
match self {
Keystore::File(file_keystore) => file_keystore.generate_session_key(address, password),
Keystore::File(file_keystore) => {
file_keystore.generate_session_key(address, password, session_key)
}
Keystore::InMem(inmem_keystore) => {
inmem_keystore.generate_session_key(address, password)
inmem_keystore.generate_session_key(address, password, session_key)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/testsuite/features/cmd.feature
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ Feature: Rooch CLI integration tests

# session key
Then cmd: "session-key create --app-name test --app-url https://test-seed.rooch.network --scope 0x3::empty::empty"
Then cmd: "move run --function 0x3::empty::empty --session-key {{$.session-key[-1].authentication_key}}"
Then cmd: "move run --function 0x3::empty::empty --session-key {{$.session-key[-1].authentication_key}}"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"

# session key from session key
Then cmd: "session-key create --app-name test --app-url https://test-seed.rooch.network --session-key {{$.session-key[-1].authentication_key}} --scope 0x3::empty::empty"
Then cmd: "move run --function 0x3:cargo test -p testsuite --test integration:empty::empty --session-key {{$.session-key[-1].authentication_key}}"
Then cmd: "move run --function 0x3:cargo test -p testsuite --test integration:empty::empty --session-key {{$.session-key[-1].authentication_key}}"
Then assert: "{{$.move[-1].execution_info.status.type}} == executed"

# transaction
Expand Down
53 changes: 48 additions & 5 deletions frameworks/rooch-framework/doc/auth_validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ fun post_execute()
- [Function `validator_module_name`](#0x3_auth_validator_validator_module_name)
- [Function `new_tx_validate_result`](#0x3_auth_validator_new_tx_validate_result)
- [Function `get_validate_result_from_ctx`](#0x3_auth_validator_get_validate_result_from_ctx)
- [Function `get_validator_id_from_ctx`](#0x3_auth_validator_get_validator_id_from_ctx)
- [Function `get_auth_validator_id_from_ctx_option`](#0x3_auth_validator_get_auth_validator_id_from_ctx_option)
- [Function `get_auth_validator_from_ctx_option`](#0x3_auth_validator_get_auth_validator_from_ctx_option)
- [Function `get_session_key_from_ctx_option`](#0x3_auth_validator_get_session_key_from_ctx_option)
- [Function `is_validate_via_auth_validator`](#0x3_auth_validator_is_validate_via_auth_validator)
- [Function `is_validate_via_session_key`](#0x3_auth_validator_is_validate_via_session_key)
- [Function `get_auth_validator_from_ctx`](#0x3_auth_validator_get_auth_validator_from_ctx)
- [Function `get_session_key_from_ctx`](#0x3_auth_validator_get_session_key_from_ctx)


<pre><code><b>use</b> <a href="">0x1::ascii</a>;
<b>use</b> <a href="">0x1::debug</a>;
<b>use</b> <a href="">0x1::option</a>;
<b>use</b> <a href="">0x2::tx_context</a>;
</code></pre>
Expand Down Expand Up @@ -183,14 +187,28 @@ Get the TxValidateResult from the TxContext, Only can be called after the transa



<a name="0x3_auth_validator_get_validator_id_from_ctx"></a>
<a name="0x3_auth_validator_get_auth_validator_id_from_ctx_option"></a>

## Function `get_validator_id_from_ctx`
## Function `get_auth_validator_id_from_ctx_option`

Get the auth validator's id from the TxValidateResult in the TxContext
If the TxValidateResult or AuthValidatorId is None, return None


<pre><code><b>public</b> <b>fun</b> <a href="auth_validator.md#0x3_auth_validator_get_validator_id_from_ctx">get_validator_id_from_ctx</a>(): u64
<pre><code><b>public</b> <b>fun</b> <a href="auth_validator.md#0x3_auth_validator_get_auth_validator_id_from_ctx_option">get_auth_validator_id_from_ctx_option</a>(): <a href="_Option">option::Option</a>&lt;u64&gt;
</code></pre>



<a name="0x3_auth_validator_get_auth_validator_from_ctx_option"></a>

## Function `get_auth_validator_from_ctx_option`

Get the auth validator from the TxValidateResult in the TxContext
If the TxValidateResult or AuthValidator is None, return None


<pre><code><b>public</b> <b>fun</b> <a href="auth_validator.md#0x3_auth_validator_get_auth_validator_from_ctx_option">get_auth_validator_from_ctx_option</a>(): <a href="_Option">option::Option</a>&lt;<a href="auth_validator.md#0x3_auth_validator_AuthValidator">auth_validator::AuthValidator</a>&gt;
</code></pre>


Expand All @@ -200,14 +218,26 @@ Get the auth validator's id from the TxValidateResult in the TxContext
## Function `get_session_key_from_ctx_option`

Get the session key from the TxValidateResult in the TxContext
If the TxValidateResult, AuthValidator or SessionKey is None, return None
If the TxValidateResult or SessionKey is None, return None


<pre><code><b>public</b> <b>fun</b> <a href="auth_validator.md#0x3_auth_validator_get_session_key_from_ctx_option">get_session_key_from_ctx_option</a>(): <a href="_Option">option::Option</a>&lt;<a href="">vector</a>&lt;u8&gt;&gt;
</code></pre>



<a name="0x3_auth_validator_is_validate_via_auth_validator"></a>

## Function `is_validate_via_auth_validator`

The current tx is validate via the auth validator or not


<pre><code><b>public</b> <b>fun</b> <a href="auth_validator.md#0x3_auth_validator_is_validate_via_auth_validator">is_validate_via_auth_validator</a>(): bool
</code></pre>



<a name="0x3_auth_validator_is_validate_via_session_key"></a>

## Function `is_validate_via_session_key`
Expand All @@ -220,6 +250,19 @@ The current tx is validate via the session key or not



<a name="0x3_auth_validator_get_auth_validator_from_ctx"></a>

## Function `get_auth_validator_from_ctx`

Get the auth validator from the TxValidateResult in the TxContext
Only can be called after the transaction is validated


<pre><code><b>public</b> <b>fun</b> <a href="auth_validator.md#0x3_auth_validator_get_auth_validator_from_ctx">get_auth_validator_from_ctx</a>(): <a href="auth_validator.md#0x3_auth_validator_AuthValidator">auth_validator::AuthValidator</a>
</code></pre>



<a name="0x3_auth_validator_get_session_key_from_ctx"></a>

## Function `get_session_key_from_ctx`
Expand Down
1 change: 1 addition & 0 deletions frameworks/rooch-framework/doc/session_key.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@


<pre><code><b>use</b> <a href="">0x1::ascii</a>;
<b>use</b> <a href="">0x1::debug</a>;
<b>use</b> <a href="">0x1::option</a>;
<b>use</b> <a href="">0x1::signer</a>;
<b>use</b> <a href="">0x1::string</a>;
Expand Down
3 changes: 2 additions & 1 deletion frameworks/rooch-framework/doc/transaction_validator.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
- [Function `validate`](#0x3_transaction_validator_validate)


<pre><code><b>use</b> <a href="">0x1::option</a>;
<pre><code><b>use</b> <a href="">0x1::debug</a>;
<b>use</b> <a href="">0x1::option</a>;
<b>use</b> <a href="">0x2::account</a>;
<b>use</b> <a href="">0x2::signer</a>;
<b>use</b> <a href="">0x2::tx_context</a>;
Expand Down
Loading

0 comments on commit b17502c

Please sign in to comment.