diff --git a/diem-move/diem-framework/core/transactional-tests/recovery_address/basics.exp b/diem-move/diem-framework/core/transactional-tests/recovery_address/basics.exp new file mode 100644 index 0000000000..f3e31307e6 --- /dev/null +++ b/diem-move/diem-framework/core/transactional-tests/recovery_address/basics.exp @@ -0,0 +1,19 @@ +processed 11 tasks + +task 5 'run'. lines 45-48: +Error: Failed to execute transaction. VMStatus: status ABORTED of type Execution with sub status 775 + +task 6 'run'. lines 49-52: +Error: Failed to execute transaction. VMStatus: status ABORTED of type Execution with sub status 1285 + +task 7 'run'. lines 53-58: +Error: Failed to execute transaction. VMStatus: status ABORTED of type Execution with sub status 1031 + +task 8 'run'. lines 59-64: +Error: Failed to execute transaction. VMStatus: status ABORTED of type Execution with sub status 1285 + +task 9 'run'. lines 65-70: +Error: Failed to execute transaction. VMStatus: status ABORTED of type Execution with sub status 519 + +task 10 'run'. lines 71-71: +Error: Failed to execute transaction. VMStatus: status ABORTED of type Execution with sub status 7 diff --git a/diem-move/diem-framework/core/transactional-tests/recovery_address/basics.move b/diem-move/diem-framework/core/transactional-tests/recovery_address/basics.move new file mode 100644 index 0000000000..1312b14891 --- /dev/null +++ b/diem-move/diem-framework/core/transactional-tests/recovery_address/basics.move @@ -0,0 +1,71 @@ +//# init --parent-vasps Parent1 Parent2 +//# --addresses Child1=0xe42bd8dd8e9a3c5cdcb0a99619884fa1 +//# Child2=0xdd00316615da8ef1b1114c6a9f20cd8a +//# --private-keys Child1=915d621309cf25b9ae00c7ea7d2a2e99dcd77a2b71b79a5cf44c0291d8bdce6f +//# Child2=75f1fbb7f1bc78e9de643ee11589c92a53ee616de15cdad0cc48f89024b55a4b + + + +// === Setup === + +//# run --signers Parent1 +//# --type-args 0x1::XUS::XUS +//# --args @Child1 +//# x"e59531e507f309f5731a67600c845078" +//# false +//# 0 +//# -- 0x1::AccountCreationScripts::create_child_vasp_account + +//# run --signers Parent1 +//# --type-args 0x1::XUS::XUS +//# --args @Child2 +//# x"189804b7934e02fd0e57e66977819e81" +//# false +//# 0 +//# -- 0x1::AccountCreationScripts::create_child_vasp_account + + + +// === Intended usage === + +// Make child1 a recovery address. +// +//# run --signers Child1 -- 0x1::AccountAdministrationScripts::create_recovery_address + +// Delegate parent1's key to child1. +// +//# run --signers Parent1 --args @Child1 -- 0x1::AccountAdministrationScripts::add_recovery_rotation_capability + + + +// ==== Abort cases === + +// Delegating parent2's key to child1 should abort because they are different VASPs. +// +//# run --signers Parent2 --args @Child1 -- 0x1::AccountAdministrationScripts::add_recovery_rotation_capability + +// Delegating parent2's key to an account without a RecoveryAddress resource should abort. +// +//# run --signers Parent2 --args 0x3333 -- 0x1::AccountAdministrationScripts::add_recovery_rotation_capability + +// Trying to recover an account that hasn't delegated its KeyRotationCapability to a recovery. +// +//# run --signers Child2 +//# --args @Child1 @Child2 x"7013b6ed7dde3cfb1251db1b04ae9cd7853470284085693590a75def645a926d" +//# -- 0x1::AccountAdministrationScripts::rotate_authentication_key_with_recovery_address + +// Trying to recover from an account without a RecoveryAddress resource should abort. +// +//# run --signers Child1 +//# --args @Child2 @Child1 x"7013b6ed7dde3cfb1251db1b04ae9cd7853470284085693590a75def645a926d" +//# -- 0x1::AccountAdministrationScripts::rotate_authentication_key_with_recovery_address + +// Parent1 shouldn't be able to rotate child1's address. +// +//# run --signers Parent1 +//# --args @Child1 @Child1 x"7013b6ed7dde3cfb1251db1b04ae9cd7853470284085693590a75def645a926d" +//# -- 0x1::AccountAdministrationScripts::rotate_authentication_key_with_recovery_address + +// A non-vasp can't create a recovery address +// +//# run --signers TreasuryCompliance -- 0x1::AccountAdministrationScripts::create_recovery_address diff --git a/diem-move/diem-framework/core/transactional-tests/recovery_address/invalid_rotation_capability.exp b/diem-move/diem-framework/core/transactional-tests/recovery_address/invalid_rotation_capability.exp new file mode 100644 index 0000000000..b0d5a0acc3 --- /dev/null +++ b/diem-move/diem-framework/core/transactional-tests/recovery_address/invalid_rotation_capability.exp @@ -0,0 +1,4 @@ +processed 4 tasks + +task 3 'run'. lines 33-43: +Error: Transaction discarded. VMStatus: status ABORTED of type Execution with sub status 263 diff --git a/diem-move/diem-framework/core/transactional-tests/recovery_address/invalid_rotation_capability.move b/diem-move/diem-framework/core/transactional-tests/recovery_address/invalid_rotation_capability.move new file mode 100644 index 0000000000..cff0d761f9 --- /dev/null +++ b/diem-move/diem-framework/core/transactional-tests/recovery_address/invalid_rotation_capability.move @@ -0,0 +1,43 @@ +//# init --parent-vasps Test Vasp1 Vasp2 + +// TODO: 1. Check if this test has the right name. +// 2, Consider rewriting this as a unit test. + +//# publish +module Test::Holder { + struct Holder has key { x: T } + public fun hold(account: &signer, x: T) { + move_to(account, Holder { x }); + } + + public fun get(addr: address): T + acquires Holder { + let Holder{ x } = move_from>(addr); + x + } +} + +//# run --admin-script --signers DiemRoot Vasp1 +script { + use Test::Holder; + use DiemFramework::DiemAccount; + + fun main(_dr: signer, account: signer) { + Holder::hold(&account, DiemAccount::extract_key_rotation_capability(&account)); + } +} + + +// Try to create a recovery address with an invalid key rotation capability. +// +//# run --admin-script --signers DiemRoot Vasp2 +script { + use Test::Holder; + use DiemFramework::DiemAccount; + use DiemFramework::RecoveryAddress; + + fun main(_dr: signer, account: signer) { + let cap = Holder::get(@Vasp1); + RecoveryAddress::publish(&account, cap); + } +} diff --git a/language/move-compiler/functional-tests/tests/diem/recovery_address/basics.move b/language/move-compiler/functional-tests/tests/diem/recovery_address/basics.move deleted file mode 100644 index 37c9ac50db..0000000000 --- a/language/move-compiler/functional-tests/tests/diem/recovery_address/basics.move +++ /dev/null @@ -1,225 +0,0 @@ -//! account: parent1, 0, 0, address -//! account: child1, 0, 0, address -//! account: child2, 0, 0, address -//! account: parent2, 0, 0, address - -//! account: vasp1, 0, 0, address -//! account: vasp2, 0, 0, address - -// === Setup === - -// create parent VASP accounts for parent1 and 2 -// create a parent VASP -//! new-transaction -//! sender: blessed -script { -use DiemFramework::XUS::XUS; -use DiemFramework::DiemAccount; -fun main(tc_account: signer) { - let tc_account = &tc_account; - let add_all_currencies = false; - - DiemAccount::create_parent_vasp_account( - tc_account, - @{{parent1}}, - {{parent1::auth_key}}, - x"A1", - add_all_currencies, - ); - - DiemAccount::create_parent_vasp_account( - tc_account, - @{{parent2}}, - {{parent2::auth_key}}, - x"B1", - add_all_currencies, - ); - -} -} -// check: "Keep(EXECUTED)" - -// create two children for parent1 -//! new-transaction -//! sender: parent1 -script { -use DiemFramework::XUS::XUS; -use DiemFramework::DiemAccount; -fun main(account: signer) { - let account = &account; - DiemAccount::create_child_vasp_account(account, @{{child1}}, {{child1::auth_key}}, false); - DiemAccount::create_child_vasp_account(account, @{{child2}}, {{child2::auth_key}}, false) -} -} -// check: "Keep(EXECUTED)" - -// === Intended usage === - -// make child1 a recovery address -//! new-transaction -//! sender: child1 -script { -use DiemFramework::DiemAccount; -use DiemFramework::RecoveryAddress; -fun main(account: signer) { - let account = &account; - RecoveryAddress::publish(account, DiemAccount::extract_key_rotation_capability(account)) -} -} -// check: "Keep(EXECUTED)" - -// delegate parent1's key to child1 -//! new-transaction -//! sender: parent1 -script { -use DiemFramework::DiemAccount; -use DiemFramework::RecoveryAddress; -fun main(account: signer) { - let account = &account; - RecoveryAddress::add_rotation_capability( - DiemAccount::extract_key_rotation_capability(account), @{{child1}} - ); -} -} -// check: "Keep(EXECUTED)" - -// ==== Abort cases === - -// delegating parent2's key to child1 should abort because they are different VASPs -//! new-transaction -//! sender: parent2 -script { -use DiemFramework::DiemAccount; -use DiemFramework::RecoveryAddress; -fun main(account: signer) { - let account = &account; - RecoveryAddress::add_rotation_capability( - DiemAccount::extract_key_rotation_capability(account), @{{child1}} - ) -} -} -// check: "ABORTED { code: 775," - -// delegating parent2's key to an account without a RecoveryAddress resource should abort -//! new-transaction -//! sender: parent2 -script { -use DiemFramework::DiemAccount; -use DiemFramework::RecoveryAddress; -fun main(account: signer) { - let account = &account; - RecoveryAddress::add_rotation_capability( - DiemAccount::extract_key_rotation_capability(account), @0x3333 - ) -} -} -// check: "ABORTED { code: 1285," - -// trying to recover an account that hasn't delegated its KeyRotationCapability to a recovery -// address should abort -//! new-transaction -//! sender: child2 -script { -use DiemFramework::RecoveryAddress; -fun main(account: signer) { - let account = &account; - let dummy_auth_key = x"7013b6ed7dde3cfb1251db1b04ae9cd7853470284085693590a75def645a926d"; - RecoveryAddress::rotate_authentication_key(account, @{{child1}}, @{{child2}}, dummy_auth_key); -} -} -// check: "ABORTED { code: 1031," - -// trying to recover from an account without a RecoveryAddress resource should abort -//! new-transaction -//! sender: child1 -script { -use DiemFramework::RecoveryAddress; -fun main(account: signer) { - let account = &account; - let dummy_auth_key = x"7013b6ed7dde3cfb1251db1b04ae9cd7853470284085693590a75def645a926d"; - RecoveryAddress::rotate_authentication_key(account, @{{child2}}, @{{child1}}, dummy_auth_key); -} -} -// check: "ABORTED { code: 1285," - - -// parent1 shouldn't be able to rotate child1's address -//! new-transaction -//! sender: parent1 -script { -use DiemFramework::RecoveryAddress; -fun main(account: signer) { - let account = &account; - let dummy_auth_key = x"7013b6ed7dde3cfb1251db1b04ae9cd7853470284085693590a75def645a926d"; - RecoveryAddress::rotate_authentication_key(account, @{{child1}}, @{{child1}}, dummy_auth_key); -} -} -// check: "ABORTED { code: 519," - -// A non-vasp can't create a recovery address -//! new-transaction -//! sender: blessed -script { -use DiemFramework::RecoveryAddress; -use DiemFramework::DiemAccount; -fun main(account: signer) { - let account = &account; - RecoveryAddress::publish(account, DiemAccount::extract_key_rotation_capability(account)) -} -} -// check: "ABORTED { code: 7," - -//! new-transaction -module {{default}}::Holder { - struct Holder has key { x: T } - public fun hold(account: &signer, x: T) { - move_to(account, Holder { x }); - } - - public fun get(addr: address): T - acquires Holder { - let Holder{ x } = move_from>(addr); - x - } -} - -//! new-transaction -//! sender: blessed -//! type-args: 0x1::XUS::XUS -//! args: 0, {{vasp1}}, {{vasp1::auth_key}}, b"bob", true -stdlib_script::AccountCreationScripts::create_parent_vasp_account -// check: "Keep(EXECUTED)" - -//! new-transaction -//! sender: blessed -//! type-args: 0x1::XUS::XUS -//! args: 0, {{vasp2}}, {{vasp2::auth_key}}, b"bob", true -stdlib_script::AccountCreationScripts::create_parent_vasp_account -// check: "Keep(EXECUTED)" - -//! new-transaction -//! sender: vasp1 -script { -use {{default}}::Holder; -use DiemFramework::DiemAccount; -fun main(account: signer) { - let account = &account; - Holder::hold(account, DiemAccount::extract_key_rotation_capability(account)); -} -} -// check: "Keep(EXECUTED)" - -// Try to create a recovery address with an invalid key rotation capability -//! new-transaction -//! sender: vasp2 -script { -use DiemFramework::RecoveryAddress; -use {{default}}::Holder; -use DiemFramework::DiemAccount; -fun main(account: signer) { - let account = &account; - let cap = Holder::get(@{{vasp1}}); - RecoveryAddress::publish(account, cap); -} -} -// check: "ABORTED { code: 263,"