Skip to content

Commit 7760aab

Browse files
committed
Release 0.90.5
2 parents 9b80c46 + 8405103 commit 7760aab

File tree

18 files changed

+104
-62
lines changed

18 files changed

+104
-62
lines changed

BlockSettleHW/hwdeviceinterface.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@
1616
#include <QNetworkReply>
1717
#include <QPointer>
1818

19+
namespace bs {
20+
namespace core {
21+
namespace wallet {
22+
class TXSignRequest;
23+
}
24+
}
25+
}
26+
1927
class HwDeviceInterface : public QObject
2028
{
2129
Q_OBJECT
@@ -35,7 +43,7 @@ class HwDeviceInterface : public QObject
3543

3644
// operation
3745
virtual void getPublicKey(AsyncCallBackCall&& cb = nullptr) = 0;
38-
virtual void signTX(const QVariant& reqTX, AsyncCallBackCall&& cb = nullptr) = 0;
46+
virtual void signTX(const bs::core::wallet::TXSignRequest& reqTX, AsyncCallBackCall&& cb = nullptr) = 0;
3947

4048
// Management
4149
virtual void setMatrixPin(const std::string& pin) {};

BlockSettleHW/hwdevicemanager.cpp

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,25 @@
1717
#include "WalletManager.h"
1818
#include "Wallets/SyncWalletsManager.h"
1919
#include "Wallets/SyncHDWallet.h"
20+
#include "ProtobufHeadlessUtils.h"
2021

2122
HwDeviceManager::HwDeviceManager(const std::shared_ptr<ConnectionManager>& connectionManager, std::shared_ptr<bs::sync::WalletsManager> walletManager,
2223
bool testNet, QObject* parent /*= nullptr*/)
2324
: QObject(parent)
25+
, logger_(connectionManager->GetLogger())
2426
, testNet_(testNet)
2527
{
2628
walletManager_ = walletManager;
2729
trezorClient_ = std::make_unique<TrezorClient>(connectionManager, walletManager, testNet, this);
28-
ledgerClient_ = std::make_unique<LedgerClient>(connectionManager->GetLogger(), walletManager, testNet);
30+
ledgerClient_ = std::make_unique<LedgerClient>(logger_, walletManager, testNet);
2931

3032
model_ = new HwDeviceModel(this);
3133
}
3234

33-
HwDeviceManager::~HwDeviceManager() = default;
35+
HwDeviceManager::~HwDeviceManager()
36+
{
37+
releaseConnection(nullptr);
38+
};
3439

3540
void HwDeviceManager::scanDevices()
3641
{
@@ -51,7 +56,7 @@ void HwDeviceManager::scanDevices()
5156

5257
ledgerClient_->scanDevices(doneScanning);
5358
releaseConnection([this, doneScanning] {
54-
trezorClient_->initConnection([this, doneScanning]() {
59+
trezorClient_->initConnection(true, [this, doneScanning]() {
5560
doneScanning();
5661
});
5762
});
@@ -185,11 +190,41 @@ void HwDeviceManager::signTX(QVariant reqTX)
185190
return;
186191
}
187192

188-
device->signTX(reqTX, [this](QVariant&& data) {
193+
Blocksettle::Communication::headless::SignTxRequest pbSignReq;
194+
bool rc = pbSignReq.ParseFromString(reqTX.toByteArray().toStdString());
195+
if (!rc) {
196+
SPDLOG_LOGGER_ERROR(logger_, "parse TX failed");
197+
emit operationFailed(tr("Invalid sign request"));
198+
return;
199+
}
200+
201+
auto signReq = bs::signer::pbTxRequestToCore(pbSignReq);
202+
203+
device->signTX(signReq, [this, signReq](QVariant&& data) {
189204
assert(data.canConvert<HWSignedTx>());
190205
auto tx = data.value<HWSignedTx>();
206+
207+
try {
208+
std::map<BinaryData, std::map<unsigned, UTXO>> utxoMap;
209+
for (const auto &utxo : signReq.inputs) {
210+
auto& idMap = utxoMap[utxo.getTxHash()];
211+
idMap.emplace(utxo.getTxOutIndex(), utxo);
212+
}
213+
unsigned flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_SEGWIT | SCRIPT_VERIFY_P2SH_SHA256;
214+
bool validSign = Signer::verify(SecureBinaryData::fromString(tx.signedTx)
215+
, utxoMap, flags, true).isValid();
216+
if (!validSign) {
217+
SPDLOG_LOGGER_ERROR(logger_, "sign verification failed");
218+
emit operationFailed(tr("Sign verification failed"));
219+
return;
220+
}
221+
} catch (const std::exception &e) {
222+
SPDLOG_LOGGER_ERROR(logger_, "sign verification failed: {}", e.what());
223+
emit operationFailed(tr("Sign verification failed"));
224+
return;
225+
}
226+
191227
txSigned({ BinaryData::fromString(tx.signedTx) });
192-
releaseDevices();
193228
});
194229

195230
connect(device, &HwDeviceInterface::requestPinMatrix,
@@ -235,7 +270,7 @@ void HwDeviceManager::releaseConnection(AsyncCallBack&& cb/*= nullptr*/)
235270
for (int i = 0; i < model_->rowCount(); ++i) {
236271
auto device = getDevice(model_->getDevice(i));
237272
if (device) {
238-
trezorClient_->initConnection([this, cbCopy = std::move(cb)] {
273+
trezorClient_->initConnection(true, [this, cbCopy = std::move(cb)] {
239274
trezorClient_->releaseConnection([this, cb = std::move(cbCopy)]() {
240275
if (cb) {
241276
cb();

BlockSettleHW/hwdevicemanager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class HwDeviceManager : public QObject
8282

8383
QPointer<HwDeviceInterface> getDevice(DeviceKey key);
8484

85+
std::shared_ptr<spdlog::logger> logger_;
86+
8587
public:
8688
std::unique_ptr<TrezorClient> trezorClient_;
8789
std::unique_ptr<LedgerClient> ledgerClient_;

BlockSettleHW/ledger/ledgerDevice.cpp

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -198,19 +198,8 @@ void LedgerDevice::getPublicKey(AsyncCallBackCall&& cb /*= nullptr*/)
198198
commandThread->start();
199199
}
200200

201-
void LedgerDevice::signTX(const QVariant& reqTX, AsyncCallBackCall&& cb /*= nullptr*/)
201+
void LedgerDevice::signTX(const bs::core::wallet::TXSignRequest& coreReq, AsyncCallBackCall&& cb /*= nullptr*/)
202202
{
203-
Blocksettle::Communication::headless::SignTxRequest request;
204-
if (!request.ParseFromString(reqTX.toByteArray().toStdString())) {
205-
logger_->debug("[LedgerDevice] signTX - failed to parse transaction request ");
206-
emit operationFailed({});
207-
return;
208-
}
209-
210-
// We do not pass wallet manager in next thread,
211-
// so catch any data we need here and put it in other thread
212-
auto coreReq = bs::signer::pbTxRequestToCore(request, logger_);
213-
214203
// retrieve inputs paths
215204
std::vector<bs::hd::Path> inputPathes;
216205
for (int i = 0; i < coreReq.inputs.size(); ++i) {
@@ -240,7 +229,7 @@ void LedgerDevice::signTX(const QVariant& reqTX, AsyncCallBackCall&& cb /*= null
240229
// create different thread because hidapi is working in blocking mode
241230
auto commandThread = blankCommand(std::move(cb));
242231
commandThread->prepareSignTx(
243-
key(), std::move(coreReq), std::move(inputPathes), std::move(changePath));
232+
key(), coreReq, std::move(inputPathes), std::move(changePath));
244233
commandThread->start();
245234
}
246235

@@ -386,9 +375,8 @@ void LedgerCommandThread::prepareGetPublicKey(const DeviceKey &deviceKey)
386375
deviceKey_ = deviceKey;
387376
}
388377

389-
void LedgerCommandThread::prepareSignTx(
390-
const DeviceKey &deviceKey,
391-
bs::core::wallet::TXSignRequest&& coreReq,
378+
void LedgerCommandThread::prepareSignTx(const DeviceKey &deviceKey,
379+
bs::core::wallet::TXSignRequest coreReq,
392380
std::vector<bs::hd::Path>&& paths, bs::hd::Path&& changePath)
393381
{
394382
threadPurpose_ = HardwareCommand::SignTX;

BlockSettleHW/ledger/ledgerDevice.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class LedgerDevice : public HwDeviceInterface
5252

5353
// operation
5454
void getPublicKey(AsyncCallBackCall&& cb = nullptr) override;
55-
void signTX(const QVariant& reqTX, AsyncCallBackCall&& cb = nullptr) override;
55+
void signTX(const bs::core::wallet::TXSignRequest &reqTX, AsyncCallBackCall&& cb = nullptr) override;
5656

5757
bool inited() {
5858
return !xpubRoot_.empty();
@@ -94,7 +94,7 @@ class LedgerCommandThread : public QThread
9494
void prepareGetPublicKey(const DeviceKey &deviceKey);
9595
void prepareSignTx(
9696
const DeviceKey &deviceKey,
97-
bs::core::wallet::TXSignRequest&& coreReq,
97+
bs::core::wallet::TXSignRequest coreReq,
9898
std::vector<bs::hd::Path>&& paths, bs::hd::Path&& changePath);
9999
void prepareGetRootKey();
100100

BlockSettleHW/trezor/trezorClient.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ QByteArray TrezorClient::getSessionId()
3636
return deviceData_.sessionId_;
3737
}
3838

39-
void TrezorClient::initConnection(AsyncCallBack&& cb)
39+
void TrezorClient::initConnection(bool force, AsyncCallBack&& cb)
4040
{
41-
auto initCallBack = [this, cbCopy = std::move(cb)](QNetworkReply* reply) mutable {
41+
auto initCallBack = [this, cbCopy = std::move(cb), force](QNetworkReply* reply) mutable {
4242

4343
if (!reply || reply->error() != QNetworkReply::NoError) {
4444
connectionManager_->GetLogger()->error(
@@ -67,7 +67,7 @@ void TrezorClient::initConnection(AsyncCallBack&& cb)
6767
state_ = State::Init;
6868
emit initialized();
6969

70-
enumDevices(std::move(cbCopy));
70+
enumDevices(force, std::move(cbCopy));
7171
reply->deleteLater();
7272
};
7373

@@ -81,7 +81,7 @@ void TrezorClient::initConnection(QString&& deviceId, AsyncCallBackCall&& cb /*=
8181
originCb({ copyDeviceId });
8282
};
8383

84-
initConnection(std::move(cbWrapper));
84+
initConnection(false, std::move(cbWrapper));
8585
}
8686

8787
void TrezorClient::releaseConnection(AsyncCallBack&& cb)
@@ -109,6 +109,10 @@ void TrezorClient::releaseConnection(AsyncCallBack&& cb)
109109
state_ = State::Released;
110110
emit deviceReleased();
111111

112+
if (cbCopy) {
113+
cbCopy();
114+
}
115+
112116
reply->deleteLater();
113117
};
114118

@@ -180,9 +184,9 @@ QPointer<TrezorDevice> TrezorClient::getTrezorDevice(const QString& deviceId)
180184
return trezorDevice_;
181185
}
182186

183-
void TrezorClient::enumDevices(AsyncCallBack&& cb)
187+
void TrezorClient::enumDevices(bool forceAcquire, AsyncCallBack&& cb)
184188
{
185-
auto enumCallback = [this, cbCopy = std::move(cb)](QNetworkReply* reply) mutable {
189+
auto enumCallback = [this, cbCopy = std::move(cb), forceAcquire](QNetworkReply* reply) mutable {
186190

187191
if (!reply || reply->error() != QNetworkReply::NoError) {
188192
connectionManager_->GetLogger()->error(
@@ -223,6 +227,12 @@ void TrezorClient::enumDevices(AsyncCallBack&& cb)
223227

224228
// If there will be a few trezor devices connected, let's choose first one for now
225229
// later we could expand this functionality to many of them
230+
if (!forceAcquire && trezorDevice_ && trezorDevices.first().sessionId_ == deviceData_.sessionId_) {
231+
// this is our previous session so we could go straight away on it
232+
cbCopy();
233+
return;
234+
}
235+
226236
deviceData_ = trezorDevices.first();
227237
connectionManager_->GetLogger()->info(
228238
"[TrezorClient] enumDevices - Enumerate request succeeded. Total device available : "

BlockSettleHW/trezor/trezorClient.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class TrezorClient : public QObject
4040

4141
QByteArray getSessionId();
4242

43-
void initConnection(AsyncCallBack&& cb = nullptr);
43+
void initConnection(bool force, AsyncCallBack&& cb = nullptr);
4444
void initConnection(QString&& deviceId, AsyncCallBackCall&& cb = nullptr);
4545
void releaseConnection(AsyncCallBack&& cb = nullptr);
4646

@@ -53,7 +53,7 @@ class TrezorClient : public QObject
5353
void postToTrezor(QByteArray&& urlMethod, std::function<void(QNetworkReply*)> &&cb, bool timeout = false);
5454
void postToTrezorInput(QByteArray&& urlMethod, std::function<void(QNetworkReply*)> &&cb, QByteArray&& input);
5555

56-
void enumDevices(AsyncCallBack&& cb = nullptr);
56+
void enumDevices(bool forceAcquire, AsyncCallBack&& cb = nullptr);
5757
void acquireDevice(AsyncCallBack&& cb = nullptr);
5858
void post(QByteArray&& urlMethod, std::function<void(QNetworkReply*)> &&cb, QByteArray&& input, bool timeout = false);
5959

BlockSettleHW/trezor/trezorDevice.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,16 +263,9 @@ void TrezorDevice::clearSession(AsyncCallBack&& cb)
263263
}
264264

265265

266-
void TrezorDevice::signTX(const QVariant& reqTX, AsyncCallBackCall&& cb /*= nullptr*/)
266+
void TrezorDevice::signTX(const bs::core::wallet::TXSignRequest &reqTX, AsyncCallBackCall&& cb /*= nullptr*/)
267267
{
268-
Blocksettle::Communication::headless::SignTxRequest request;
269-
bool res = request.ParseFromString(reqTX.toByteArray().toStdString());
270-
if (!res) {
271-
connectionManager_->GetLogger()->debug("[TrezorDevice] signTX - failed to parse transaction request ");
272-
return;
273-
}
274-
275-
currentTxSignReq_.reset(new bs::core::wallet::TXSignRequest(bs::signer::pbTxRequestToCore(request, connectionManager_->GetLogger())));
268+
currentTxSignReq_.reset(new bs::core::wallet::TXSignRequest(reqTX));
276269
connectionManager_->GetLogger()->debug("[TrezorDevice] SignTX - specify init data to " + features_.label());
277270

278271
const int change = static_cast<bool>(currentTxSignReq_->change.value) ? 1 : 0;

BlockSettleHW/trezor/trezorDevice.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class TrezorDevice : public HwDeviceInterface
6161

6262
// operation
6363
void getPublicKey(AsyncCallBackCall&& cb = nullptr) override;
64-
void signTX(const QVariant& reqTX, AsyncCallBackCall&& cb = nullptr) override;
64+
void signTX(const bs::core::wallet::TXSignRequest& reqTX, AsyncCallBackCall&& cb = nullptr) override;
6565

6666
// Management
6767
void setMatrixPin(const std::string& pin) override;

BlockSettleSigner/qml/BsDialogs/TxSignDialog.qml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,6 @@ BSWalletHandlerDialog {
8484
}
8585
}
8686

87-
onAboutToHide: {
88-
hwDeviceManager.releaseDevices();
89-
}
90-
9187
Connections {
9288
target: hwDeviceManager
9389
onRequestPinMatrix: JsHelper.showHwPinMatrix(0);
@@ -108,6 +104,7 @@ BSWalletHandlerDialog {
108104
acceptAnimated();
109105
}
110106
onCancelledOnDevice: rejectAnimated()
107+
onOperationFailed: showWalletError(reason)
111108
}
112109

113110
Timer {
@@ -398,6 +395,7 @@ BSWalletHandlerDialog {
398395
anchors.right: walletInfo.encType === QPasswordData.Hardware ? parent.right : undefined
399396
anchors.bottom: parent.bottom
400397
onClicked: {
398+
hwDeviceManager.releaseDevices()
401399
if (walletInfo.encType === QPasswordData.Hardware &&
402400
hwDeviceManager.awaitingUserAction(0)) {
403401
let warning = JsHelper.showDropHwDeviceMessage();

0 commit comments

Comments
 (0)