Skip to content

Commit

Permalink
VG-5126 fix(Stellar): idempotent account creation (#869)
Browse files Browse the repository at this point in the history
* fix(Stellar): idempotency on account creation

Corresponding error code is expected by WD

* bump patch version

* Add integration tests
  • Loading branch information
BertrandD committed May 5, 2022
1 parent 95a7bd5 commit c339f80
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 39 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ include_what_you_use() # add cmake conf option IWYU=ON to activate
# The project version number.
set(VERSION_MAJOR 4 CACHE STRING "Project major version number.")
set(VERSION_MINOR 1 CACHE STRING "Project minor version number.")
set(VERSION_PATCH 12 CACHE STRING "Project patch version number.")
set(VERSION_PATCH 13 CACHE STRING "Project patch version number.")
mark_as_advanced(VERSION_MAJOR VERSION_MINOR VERSION_PATCH)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build)
Expand Down
2 changes: 1 addition & 1 deletion core/src/wallet/stellar/StellarLikeWallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ namespace ledger {
soci::session sql(self->getDatabase()->getPool());
{
if (AccountDatabaseHelper::accountExists(sql, getWalletUid(), info.index)) {
throw make_exception(api::ErrorCode::ILLEGAL_ARGUMENT, "Account {} already exists", info.index);
throw make_exception(api::ErrorCode::ACCOUNT_ALREADY_EXISTS, "Account {} already exists", info.index);
}
auto keychain = self->_params.keychainFactory->build(
info.index, path, std::dynamic_pointer_cast<DynamicObject>(self->getConfiguration()),
Expand Down
77 changes: 40 additions & 37 deletions core/test/integration/account_creation_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,28 @@
#include "api/TezosConfiguration.hpp"
#include "api/TezosConfigurationDefaults.hpp"

class AccountCreationTest : public BaseFixture {};
class AccountCreationTest : public BaseFixture {
protected:
void CheckDoubleAccountCreation(const api::AccountCreationInfo& aci, const std::string& currencyName, const std::shared_ptr<api::DynamicObject> &configuration) {
auto pool = newDefaultPool();
const auto walletName = "my_wallet_createaccountwithinfo";
auto wallet = uv::wait(pool->createWallet(walletName, currencyName, configuration));
uv::wait(wallet->newAccountWithInfo(aci));
try
{
uv::wait(wallet->newAccountWithInfo(aci));
}
catch(const ledger::core::Exception& e)
{
EXPECT_EQ(e.getErrorCode(), ledger::core::api::ErrorCode::ACCOUNT_ALREADY_EXISTS);
}
catch(...)
{
ADD_FAILURE() << "Expected ledger::core::Exception exception";
}
uv::wait(pool->deleteWallet(walletName));
}
};

TEST_F(AccountCreationTest, CreateBitcoinAccountWithInfo) {
auto pool = newDefaultPool();
Expand Down Expand Up @@ -98,43 +119,25 @@ TEST_F(AccountCreationTest, ChangePassword) {
}

TEST_F(AccountCreationTest, CreateBitcoinAccountTwiceShouldRaiseError) {
auto pool = newDefaultPool();
const auto walletName = "my_wallet_createbtcaccountwithinfo";
auto wallet = uv::wait(pool->createWallet(walletName, "bitcoin", DynamicObject::newInstance()));
auto account = std::dynamic_pointer_cast<BitcoinLikeAccount>(uv::wait(wallet->newAccountWithInfo(P2PKH_MEDIUM_KEYS_INFO)));
try
{
uv::wait(wallet->newAccountWithInfo(P2PKH_MEDIUM_KEYS_INFO));
}
catch(const ledger::core::Exception& e)
{
EXPECT_EQ(e.getErrorCode(), ledger::core::api::ErrorCode::ACCOUNT_ALREADY_EXISTS);
}
catch(...)
{
ADD_FAILURE() << "Expected ledger::core::Exception exception";
}
uv::wait(pool->deleteWallet(walletName));
CheckDoubleAccountCreation(P2PKH_MEDIUM_KEYS_INFO, "bitcoin", DynamicObject::newInstance());
}

TEST_F(AccountCreationTest, CreateEthereumAccountTwiceShouldRaiseError) {
CheckDoubleAccountCreation(ETH_KEYS_INFO, "ethereum", DynamicObject::newInstance());
}

TEST_F(AccountCreationTest, CreateTezosAccountTwiceShouldRaiseError) {
auto pool = newDefaultPool();
auto configuration = DynamicObject::newInstance();
configuration->putString(api::TezosConfiguration::TEZOS_XPUB_CURVE, api::TezosConfigurationDefaults::TEZOS_XPUB_CURVE_ED25519);
const auto walletName = "my_wallet_createbtcaccountwithinfo";
auto wallet = uv::wait(pool->createWallet(walletName, "tezos", configuration));
auto account = std::dynamic_pointer_cast<BitcoinLikeAccount>(uv::wait(wallet->newAccountWithInfo(XTZ_KEYS_INFO)));
try
{
uv::wait(wallet->newAccountWithInfo(XTZ_KEYS_INFO));
}
catch(const ledger::core::Exception& e)
{
EXPECT_EQ(e.getErrorCode(), ledger::core::api::ErrorCode::ACCOUNT_ALREADY_EXISTS);
}
catch(...)
{
ADD_FAILURE() << "Expected ledger::core::Exception exception";
}
uv::wait(pool->deleteWallet(walletName));
auto configuration = DynamicObject::newInstance();
configuration->putString(api::TezosConfiguration::TEZOS_XPUB_CURVE, api::TezosConfigurationDefaults::TEZOS_XPUB_CURVE_ED25519);
CheckDoubleAccountCreation(XTZ_KEYS_INFO, "tezos", configuration);
}

TEST_F(AccountCreationTest, CreateStellarAccountTwiceShouldRaiseError) {
CheckDoubleAccountCreation(api::AccountCreationInfo(0, {"main"}, {"44'/148'/0'"}, {ledger::core::hex::toByteArray(
"a1083d11720853a2c476a07e29b64e0f9eb2ff894f1e485628faa7b63de77a4f")}, {}), "stellar",
DynamicObject::newInstance());
}

TEST_F(AccountCreationTest, CreateRippleAccountTwiceShouldRaiseError) {
CheckDoubleAccountCreation(XRP_KEYS_INFO, "ripple", DynamicObject::newInstance());
}

0 comments on commit c339f80

Please sign in to comment.