Skip to content

Commit

Permalink
Fetch nonce for hardware transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
spylogsster committed May 20, 2022
1 parent 59163f1 commit efc3292
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 16 deletions.
15 changes: 12 additions & 3 deletions components/brave_wallet/browser/fil_transaction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,13 @@ absl::optional<std::string> FilTransaction::GetMessageToSign() const {
value.SetIntKey("Method", 0);
value.SetIntKey("Version", 0);
value.SetStringKey("Params", "");
const std::string* nonce_value = value.FindStringKey("Nonce");
bool nonce_empty = nonce_value && nonce_value->empty();
// Nonce is empty usually for first transactions. We set it to 0 and skip
// conversion bellow to get correct signature.
if (nonce_empty) {
value.SetIntKey("Nonce", 0);
}
std::string json;
base::JSONWriter::Write(value, &json);

Expand All @@ -191,9 +198,11 @@ absl::optional<std::string> FilTransaction::GetMessageToSign() const {
.c_str();
if (converted_json.empty())
return absl::nullopt;
converted_json = json::convert_string_value_to_uint64(
"/Nonce", converted_json.c_str(), false)
.c_str();
if (!nonce_empty) {
converted_json = json::convert_string_value_to_uint64(
"/Nonce", converted_json.c_str(), false)
.c_str();
}
return converted_json;
}

Expand Down
19 changes: 18 additions & 1 deletion components/brave_wallet/browser/fil_transaction_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,26 @@ TEST(FilTransactionUnitTest, Serialization) {

TEST(FilTransactionUnitTest, GetMessageToSignSecp) {
auto transaction = FilTransaction::FromTxData(mojom::FilTxData::New(
"1", "2", "3", "1", "5", "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q",
"", "2", "3", "1", "5", "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q",
"t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq", "6"));
auto message_to_sign = transaction->GetMessageToSign();
ASSERT_TRUE(message_to_sign);
CompareJSONs(*message_to_sign,
R"({
"From": "t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq",
"GasFeeCap": "3",
"GasLimit": 1,
"GasPremium": "2",
"Method": 0,
"Params": "",
"Nonce": 0,
"To": "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q",
"Value": "6",
"Version": 0
})");
transaction->set_nonce(1);
message_to_sign = transaction->GetMessageToSign();
ASSERT_TRUE(message_to_sign);
CompareJSONs(*message_to_sign,
R"({
"From": "t1h5tg3bhp5r56uzgjae2373znti6ygq4agkx4hzq",
Expand All @@ -168,6 +184,7 @@ TEST(FilTransactionUnitTest, GetMessageToSignSecp) {
"Value": "6",
"Version": 0
})");

std::string private_key_decoded =
DecodePrivateKey("8VcW07ADswS4BV2cxi5rnIadVsyTDDhY1NfDH19T8Uo=");
std::vector<uint8_t> private_key(private_key_decoded.begin(),
Expand Down
29 changes: 29 additions & 0 deletions components/brave_wallet/browser/fil_tx_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,35 @@ void FilTxManager::GetTransactionMessageToSign(
std::move(callback).Run(absl::nullopt);
return;
}
if (!meta->tx()->nonce()) {
auto from = meta->from();
nonce_tracker_->GetNextNonce(
from, base::BindOnce(&FilTxManager::OnGetNextNonceForHardware,
weak_factory_.GetWeakPtr(), std::move(meta),
std::move(callback)));
} else {
uint64_t nonce = meta->tx()->nonce().value();
OnGetNextNonceForHardware(std::move(meta), std::move(callback), true,
nonce);
}
}

void FilTxManager::OnGetNextNonceForHardware(
std::unique_ptr<FilTxMeta> meta,
GetTransactionMessageToSignCallback callback,
bool success,
uint256_t nonce) {
if (!success) {
meta->set_status(mojom::TransactionStatus::Error);
tx_state_manager_->AddOrUpdateTx(*meta);
std::move(callback).Run(absl::nullopt);
return;
}
DCHECK_LE(nonce, static_cast<uint256_t>(UINT64_MAX));
meta->tx()->set_nonce(static_cast<uint64_t>(nonce));
DCHECK(!keyring_service_->IsLocked());
meta->set_status(mojom::TransactionStatus::Approved);
tx_state_manager_->AddOrUpdateTx(*meta);
std::move(callback).Run(meta->tx()->GetMessageToSign());
}

Expand Down
5 changes: 5 additions & 0 deletions components/brave_wallet/browser/fil_tx_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ class FilTxManager : public TxManager, public FilBlockTracker::Observer {
ApproveTransactionCallback callback,
bool success,
uint256_t nonce);
void OnGetNextNonceForHardware(std::unique_ptr<FilTxMeta> meta,
GetTransactionMessageToSignCallback callback,
bool success,
uint256_t nonce);
void OnSendFilecoinTransaction(const std::string& tx_meta_id,
ApproveTransactionCallback callback,
const std::string& tx_hash,
Expand All @@ -93,6 +97,7 @@ class FilTxManager : public TxManager, public FilBlockTracker::Observer {
int64_t gas_limit,
mojom::FilecoinProviderError error,
const std::string& error_message);

void OnGetFilStateSearchMsgLimited(const std::string& tx_meta_id,
int64_t exit_code,
mojom::FilecoinProviderError error,
Expand Down
58 changes: 46 additions & 12 deletions components/brave_wallet/browser/fil_tx_manager_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -446,18 +446,19 @@ TEST_F(FilTxManagerUnitTest, SomeSiteOrigin) {
TEST_F(FilTxManagerUnitTest, GetTransactionMessageToSign) {
const std::string from_account = "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q";
const std::string to_account = "t1lqarsh4nkg545ilaoqdsbtj4uofplt6sto26ziy";

auto tx_data = mojom::FilTxData::New(
"1" /* nonce */, "2" /* gas_premium */, "3" /* gas_fee_cap */,
"4" /* gas_limit */, "" /* max_fee */, to_account, from_account, "11");
std::string meta_id;
AddUnapprovedTransaction(std::move(tx_data), from_account, absl::nullopt,
&meta_id);
auto tx_meta = fil_tx_manager()->GetTxForTesting(meta_id);
ASSERT_TRUE(tx_meta);
EXPECT_EQ(tx_meta->from(), from_account);
EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Unapproved);
GetTransactionMessageToSign(meta_id, R"(
// non-empty nonce
{
auto tx_data = mojom::FilTxData::New(
"1" /* nonce */, "2" /* gas_premium */, "3" /* gas_fee_cap */,
"4" /* gas_limit */, "" /* max_fee */, to_account, from_account, "11");
std::string meta_id;
AddUnapprovedTransaction(std::move(tx_data), from_account, absl::nullopt,
&meta_id);
auto tx_meta = fil_tx_manager()->GetTxForTesting(meta_id);
ASSERT_TRUE(tx_meta);
EXPECT_EQ(tx_meta->from(), from_account);
EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Unapproved);
GetTransactionMessageToSign(meta_id, R"(
{
"From": "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q",
"GasFeeCap": "3",
Expand All @@ -471,6 +472,39 @@ TEST_F(FilTxManagerUnitTest, GetTransactionMessageToSign) {
"Version": 0
}
)");
}
// empty nonce
{
SetInterceptor(GetNetwork(mojom::kLocalhostChainId, mojom::CoinType::FIL),
"Filecoin.MpoolGetNonce",
R"({ "jsonrpc": "2.0", "id": 1, "result": 5 })");

auto tx_data = mojom::FilTxData::New(
"" /* nonce */, "2" /* gas_premium */, "3" /* gas_fee_cap */,
"4" /* gas_limit */, "" /* max_fee */, to_account, from_account, "11");
std::string meta_id;
AddUnapprovedTransaction(std::move(tx_data), from_account, absl::nullopt,
&meta_id);
auto tx_meta = fil_tx_manager()->GetTxForTesting(meta_id);
ASSERT_TRUE(tx_meta);
EXPECT_EQ(tx_meta->from(), from_account);
EXPECT_EQ(tx_meta->status(), mojom::TransactionStatus::Unapproved);
GetTransactionMessageToSign(meta_id, R"(
{
"From": "t1h4n7rphclbmwyjcp6jrdiwlfcuwbroxy3jvg33q",
"GasFeeCap": "3",
"GasLimit": 4,
"GasPremium": "2",
"Method": 0,
"Nonce": 5,
"Params": "",
"To": "t1lqarsh4nkg545ilaoqdsbtj4uofplt6sto26ziy",
"Value": "11",
"Version": 0
}
)");
}

GetTransactionMessageToSign("unknown id", absl::nullopt);
GetTransactionMessageToSign("", absl::nullopt);
}
Expand Down

0 comments on commit efc3292

Please sign in to comment.