Skip to content

Commit

Permalink
fix Balance some small bug (FISCO-BCOS#4091)
Browse files Browse the repository at this point in the history
  • Loading branch information
wenlinlee authored Dec 5, 2023
1 parent 79a5844 commit 340d536
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 50 deletions.
39 changes: 13 additions & 26 deletions bcos-executor/src/precompiled/extension/AccountPrecompiled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,15 @@ void AccountPrecompiled::getAccountBalance(const std::string& accountTableName,
const auto& blockContext = _executive->blockContext();
auto codec = CodecWrapper(blockContext.hashHandler(), blockContext.isWasm());
auto table = _executive->storage().openTable(accountTableName);

// if account table not exist in apps but usr exist, return 0 by default
if (!table)
{
_callParameters->setExecResult(codec.encode(0));
// BOOST_THROW_EXCEPTION(PrecompiledError("Account table not exist!"));
PRECOMPILED_LOG(ERROR) << BLOCK_NUMBER(blockContext.number())
<< LOG_BADGE("AccountPrecompiled, getAccountBalance")
<< LOG_DESC("Account table not exist, return 0 by default")
<< LOG_KV("account", accountTableName);
_callParameters->setExecResult(codec.encode(0));
return;
}
auto entry = _executive->storage().getRow(accountTableName, ACCOUNT_BALANCE);
Expand All @@ -242,7 +243,7 @@ void AccountPrecompiled::getAccountBalance(const std::string& accountTableName,
<< LOG_BADGE("AccountPrecompiled, getAccountBalance")
<< LOG_DESC("balance not exist, return 0 by default")
<< LOG_KV("account", accountTableName);
BOOST_THROW_EXCEPTION(PrecompiledError("Account balance not exist!"));
_callParameters->setExecResult(codec.encode(0));
return;
}
balance = u256(std::string(entry->get()));
Expand Down Expand Up @@ -276,21 +277,14 @@ void AccountPrecompiled::addAccountBalance(const std::string& accountTableName,
return;
}

// check account exist, if not exist, create it
// check account exist
auto table = _executive->storage().openTable(accountTableName);
if (!table.has_value()) [[unlikely]]
{
// create account table, and set balance
std::string balanceFiled(ACCOUNT_BALANCE);
_executive->storage().createTable(accountTableName, balanceFiled);
Entry Balance;
Balance.importFields({boost::lexical_cast<std::string>(value)});
_executive->storage().setRow(accountTableName, ACCOUNT_BALANCE, std::move(Balance));
PRECOMPILED_LOG(INFO) << BLOCK_NUMBER(blockContext.number())
<< LOG_BADGE("AccountPrecompiled, addAccountBalance")
<< LOG_DESC("table not exist, create and initialize balance")
<< LOG_KV("account balance", to_string(value));
_callParameters->setExecResult(codec.encode(int32_t(CODE_SUCCESS)));
PRECOMPILED_LOG(WARNING) << BLOCK_NUMBER(blockContext.number())
<< LOG_BADGE("AccountPrecompiled, addAccountBalance")
<< LOG_DESC("table not exist!");
BOOST_THROW_EXCEPTION(PrecompiledError("Account table not exist, addBalance failed!"));
return;
}

Expand Down Expand Up @@ -343,19 +337,12 @@ void AccountPrecompiled::subAccountBalance(const std::string& accountTableName,

// check account exist
auto table = _executive->storage().openTable(accountTableName);
// if table not exist, create it
if (!table.has_value()) [[unlikely]]
{
// create account table, and set balance is 0
std::string balanceField(ACCOUNT_BALANCE);
_executive->storage().createTable(accountTableName, balanceField);
Entry Balance;
Balance.importFields({"0"});
_executive->storage().setRow(accountTableName, ACCOUNT_BALANCE, std::move(Balance));
PRECOMPILED_LOG(INFO) << BLOCK_NUMBER(blockContext.number())
<< LOG_BADGE("AccountPrecompiled, subAccountBalance")
<< LOG_DESC("table not exist, create and initialize balance is 0");
BOOST_THROW_EXCEPTION(PrecompiledError("Account table not exist!"));
PRECOMPILED_LOG(WARNING) << BLOCK_NUMBER(blockContext.number())
<< LOG_BADGE("AccountPrecompiled, subAccountBalance")
<< LOG_DESC("table not exist!");
BOOST_THROW_EXCEPTION(PrecompiledError("Account table not exist, subBalance failed!"));
return;
}

Expand Down
95 changes: 77 additions & 18 deletions bcos-executor/src/precompiled/extension/BalancePrecompiled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,32 @@ std::shared_ptr<PrecompiledExecResult> BalancePrecompiled::call(
return _callParameters;
}

void BalancePrecompiled::createAccount(
const std::shared_ptr<executor::TransactionExecutive>& _executive,
const PrecompiledExecResult::Ptr& _callParameters, const bcos::CodecWrapper& codec,
std::string_view accountHex)
{
auto accountTableName = getAccountTableName(accountHex);

// prefix + address + tableName
std::string codeString = getDynamicPrecompiledCodeString(ACCOUNT_ADDRESS, accountTableName);
auto input = codec.encode(accountTableName, codeString);

auto response = externalRequest(_executive, ref(input), _callParameters->m_origin,
_callParameters->m_codeAddress, accountHex, false, true, _callParameters->m_gasLeft, true);

if (response->status != (int32_t)TransactionStatus::None)
{
PRECOMPILED_LOG(INFO) << LOG_BADGE("AccountManagerPrecompiled")
<< LOG_DESC("createAccount failed")
<< LOG_KV("accountTableName", accountTableName)
<< LOG_KV("status", response->status);
BOOST_THROW_EXCEPTION(PrecompiledError("Create account error."));
}
return;
}


void BalancePrecompiled::getBalance(
const std::shared_ptr<executor::TransactionExecutive>& _executive,
PrecompiledExecResult::Ptr const& _callParameters)
Expand All @@ -106,20 +132,19 @@ void BalancePrecompiled::getBalance(
codec.decode(_callParameters->params(), account);
std::string accountStr = account.hex();

PRECOMPILED_LOG(TRACE) << BLOCK_NUMBER(blockContext.number()) << LOG_BADGE("BalancePrecompiled")
<< LOG_DESC("getBalance") << LOG_KV("account", accountStr);
auto accountTableName = getContractTableName(executor::USER_APPS_PREFIX, accountStr);
auto table = _executive->storage().openTable(accountTableName);
if (!table)

auto usrTableName = getAccountTableName(accountStr);
auto usrTable = _executive->storage().openTable(usrTableName);
auto appsTableName = getContractTableName(executor::USER_APPS_PREFIX, accountStr);
auto appsTable = _executive->storage().openTable(appsTableName);
if (!usrTable && !appsTable)
{
_callParameters->setExecResult(codec.encode(int32_t(CODE_ACCOUNT_NOT_EXIST)));
PRECOMPILED_LOG(ERROR) << BLOCK_NUMBER(blockContext.number())
<< LOG_BADGE("BalancePrecompiled") << LOG_DESC("getBalance")
<< LOG_KV("account", accountStr)
<< LOG_KV("accountTableNotExist", "true");
BOOST_THROW_EXCEPTION(protocol::PrecompiledError("account not exist, getBalance failed"));
BOOST_THROW_EXCEPTION(protocol::PrecompiledError(
"account appsTable and usrTable not exist, getBalance failed"));
return;
}

// get balance from account table
auto params = codec.encodeWithSig("getAccountBalance()");
auto tableName = getContractTableName(executor::USER_APPS_PREFIX, accountStr);
Expand Down Expand Up @@ -168,18 +193,27 @@ void BalancePrecompiled::addBalance(
protocol::PrecompiledError("caller table not exist, addBalance failed"));
}
auto entry = _executive->storage().getRow(SYS_BALANCE_CALLER, caller);
if (!entry.has_value() || entry->get() == "0")
{
_callParameters->setExecResult(codec.encode(int32_t(CODE_CHECK_CALLER_FAILED)));
BOOST_THROW_EXCEPTION(
protocol::PrecompiledError("the request's sender not caller, addBalance failed"));
return;
}
PRECOMPILED_LOG(DEBUG) << BLOCK_NUMBER(blockContext.number()) << LOG_BADGE("BalancePrecompiled")
<< LOG_DESC("addBalance") << LOG_KV("account", accountStr)
<< LOG_KV("value", value) << LOG_KV("caller", caller)
<< LOG_KV("callerEntry", entry->get());
if (!entry.has_value() || entry->get() == "0")

// check the account whether exist, if not exist, create the account
auto accountTableName = getAccountTableName(accountStr);
auto table1 = _executive->storage().openTable(accountTableName);
if (!table1)
{
_callParameters->setExecResult(codec.encode(int32_t(CODE_CHECK_CALLER_FAILED)));
BOOST_THROW_EXCEPTION(protocol::PrecompiledError("caller not exist, addBalance failed"));
createAccount(_executive, _callParameters, codec, accountStr);
}

// AccountPrecompiledAddress + addAccountBalance(value), internal call

auto balanceParams = codec.encodeWithSig("addAccountBalance(uint256)", value);
auto tableName = getContractTableName(executor::USER_APPS_PREFIX, accountStr);
std::vector<std::string> tableNameVector = {tableName};
Expand Down Expand Up @@ -212,12 +246,13 @@ void BalancePrecompiled::subBalance(
if (!table)
{
PRECOMPILED_LOG(WARNING) << BLOCK_NUMBER(blockContext.number())
<< LOG_BADGE("BalancePrecompiled") << LOG_DESC("subBalance")
<< LOG_KV("account", accountStr) << LOG_KV("value", value)
<< LOG_KV("caller", caller) << LOG_KV("callerTableNotExist", "true");
<< LOG_BADGE("BalancePrecompiled") << LOG_DESC("subBalance")
<< LOG_KV("account", accountStr) << LOG_KV("value", value)
<< LOG_KV("caller", caller)
<< LOG_KV("callerTableNotExist", "true");
_callParameters->setExecResult(codec.encode(int32_t(CODE_CALLER_TABLE_NOT_EXIST)));
BOOST_THROW_EXCEPTION(
protocol::PrecompiledError("caller table not exist, subBalance failed"));
protocol::PrecompiledError("the request's sender not caller, subBalance failed"));
return;
}
auto entry = table->getRow(caller);
Expand All @@ -227,6 +262,13 @@ void BalancePrecompiled::subBalance(
BOOST_THROW_EXCEPTION(protocol::PrecompiledError("caller not exist, subBalance failed"));
}

// check the account whether exist, if not exist, create the account
auto accountTableName = getAccountTableName(accountStr);
auto table1 = _executive->storage().openTable(accountTableName);
if (!table1)
{
createAccount(_executive, _callParameters, codec, accountStr);
}

// AccountPrecompiledAddress + subAccountBalance(value), internal call
auto balanceParams = codec.encodeWithSig("subAccountBalance(uint256)", value);
Expand All @@ -242,6 +284,7 @@ void BalancePrecompiled::subBalance(

_callParameters->setExternalResult(std::move(subBalanceResult));
}

void BalancePrecompiled::transfer(const std::shared_ptr<executor::TransactionExecutive>& _executive,
PrecompiledExecResult::Ptr const& _callParameters)
{
Expand Down Expand Up @@ -289,6 +332,14 @@ void BalancePrecompiled::transfer(const std::shared_ptr<executor::TransactionExe
std::vector<std::string> fromTableNameVector = {formTableName};
auto inputParams = codec.encode(fromTableNameVector, params);

// check the from account whether exist, if not exist, create the account
auto fromAccountTableName = getAccountTableName(fromStr);
auto fromTable = _executive->storage().openTable(fromAccountTableName);
if (!fromTable)
{
createAccount(_executive, _callParameters, codec, fromStr);
}

auto subParams = codec.encode(std::string(ACCOUNT_ADDRESS), inputParams);
auto subBalanceResult = externalRequest(_executive, ref(subParams), _callParameters->m_origin,
_callParameters->m_codeAddress, fromStr, _callParameters->m_staticCall,
Expand All @@ -302,6 +353,14 @@ void BalancePrecompiled::transfer(const std::shared_ptr<executor::TransactionExe
auto inputParams1 = codec.encode(toTableNameVector, params1);
auto addParams = codec.encode(std::string(ACCOUNT_ADDRESS), inputParams1);

// check the to account whether exist, if not exist, create the account
auto toAccountTableName = getAccountTableName(toStr);
auto toTable = _executive->storage().openTable(toAccountTableName);
if (!toTable)
{
createAccount(_executive, _callParameters, codec, toStr);
}

auto addBalanceResult =
externalRequest(_executive, ref(addParams), _callParameters->m_origin,
_callParameters->m_codeAddress, toStr, _callParameters->m_staticCall,
Expand Down
4 changes: 4 additions & 0 deletions bcos-executor/src/precompiled/extension/BalancePrecompiled.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class BalancePrecompiled : public bcos::precompiled::Precompiled
void unregisterCaller(const std::shared_ptr<executor::TransactionExecutive>& _executive,
PrecompiledExecResult::Ptr const& _callParameters);

void createAccount(const std::shared_ptr<executor::TransactionExecutive>& _executive,
PrecompiledExecResult::Ptr const& _callParameters, const CodecWrapper& codec,
std::string_view accountHex);

private:
mutable std::map<std::string, u256> m_fakeBalancePrecompiled;
};
Expand Down
12 changes: 6 additions & 6 deletions bcos-executor/src/precompiled/solidity/BalancePrecompiled.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
pragma solidity ^0.8.0;

contract BalancePrecompiled {
function getBalance(address account) external returns (uint256) {}
function getBalance(address account) public returns (uint256) {}

function addBalance(address account, uint256 amount) external {}
function addBalance(address account, uint256 amount) public {}

function subBalance(address account, uint256 amount) external {}
function subBalance(address account, uint256 amount) public {}

function transfer(address from, address to, uint256 amount) external {}
function transfer(address from, address to, uint256 amount) public {}

function registerCaller(address account) external {}
function registerCaller(address account) public {}

function unregisterCaller(address account) external {}
function unregisterCaller(address account) public {}
}

0 comments on commit 340d536

Please sign in to comment.