Skip to content

Commit 6924e84

Browse files
committed
better r,s & v handling when using hsm for signing
1 parent 347169c commit 6924e84

File tree

4 files changed

+54
-27
lines changed

4 files changed

+54
-27
lines changed

federator/src/lib/HSM.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
11
const net = require('net');
2-
const utils = require('./utils');
32

4-
const payloadBuilder =
5-
(
6-
command,
7-
keyId,
8-
txnHash
9-
) => `{"command":"${command}","keyId":"${keyId}","message":{"hash":"${txnHash}"},"version":2}`;
3+
function hsmPayloadBuilder(command, keyId, txnHash) {
4+
return `{"command":"${command}","keyId":"${keyId}","message":{"hash":"${txnHash}"},"version":2}`;
5+
}
106

117
module.exports = class HSM {
128
constructor({
139
host = '127.0.0.1',
1410
port = 6000,
15-
}) {
11+
}, logger) {
1612
this.host = host;
1713
this.port = port;
14+
this.logger = logger;
1815
this.client = null;
1916
}
2017

@@ -36,7 +33,7 @@ module.exports = class HSM {
3633
}
3734

3835
send(msgToSign = '') {
39-
const payload = utils.hsmPayloadBuilder(`sign`, `m/44'/137'/0'/0/0`, msgToSign);
36+
const payload = hsmPayloadBuilder(`sign`, `m/44'/137'/0'/0/0`, msgToSign);
4037
return this.client.write(`${payload}\n`);
4138
}
4239

@@ -46,7 +43,8 @@ module.exports = class HSM {
4643
this.send(msgToSign);
4744
return this.receive();
4845
} catch(err) {
49-
console.log(`HSM (connectSendAndReceive)`, err);
46+
this.logger.error(`HSM (connectSendAndReceive)`, err);
47+
throw err;
5048
}
5149
}
5250
}

federator/src/lib/TransactionSender.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module.exports = class TransactionSender {
1616
this.hsm = new HSM({
1717
port: config.hsmPort,
1818
host: config.hsmHost
19-
})
19+
}, this.logger);
2020
}
2121

2222
async getNonce(address) {
@@ -135,26 +135,22 @@ module.exports = class TransactionSender {
135135
if(!useHSM) {
136136
tx.sign(utils.hexStringToBuffer(privateKey));
137137
} else {
138-
const txHash = tx.hash(false).toString();
139-
const {
138+
const txHash = tx.hash(false).toString('hex');
139+
const {
140140
errorcode,
141141
signature: {
142142
r,
143143
s
144-
}
144+
} = { r: '0x0', s: '0x0' }
145145
} = JSON.parse(await this.hsm.connectSendAndReceive(txHash));
146146

147147
if(errorcode != 0) {
148148
throw new Error(`error while signing txn with HSM`)
149149
}
150-
151-
tx = {
152-
...tx,
153-
r,
154-
s,
155-
v: this.getChainId() * 2 + 8
156-
}
157-
150+
151+
tx.r = Buffer.from(r, 'hex');
152+
tx.s = Buffer.from(s, 'hex');
153+
tx.v = Buffer.from((this.getChainId() * 2 + 8).toString());
158154
}
159155
return tx;
160156
}

federator/src/lib/utils.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,7 @@ async function evm_mine(iterations, web3Instance = null) {
176176
await asyncMine(web3Instance);
177177
};
178178
};
179-
function hsmPayloadBuilder(command, keyId, txnHash) {
180-
return `{"command":"${command}","keyId":"${keyId}","message":{"hash":"${txnHash}"},"version":2}`;
181-
}
179+
182180

183181
module.exports = {
184182
asyncMine,
@@ -197,5 +195,4 @@ module.exports = {
197195
retry,
198196
retry3Times,
199197
getHeartbeatPollingInterval,
200-
hsmPayloadBuilder
201198
}

federator/test/TransactionSender.test.js

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,40 @@ describe('TransactionSender module tests', () => {
7474
expect(result).toEqual(expectedAddr.toLocaleLowerCase());
7575
});
7676

77-
});
77+
it('should sign the same with HSM and web3', async () => {
78+
const rawTx = {
79+
chainId: 5777,
80+
gasPrice: '0x6fc23ac00',
81+
value: '0x0',
82+
to: '0x557b77f7B280006f7732dCc123C3A966F5Fe1372',
83+
data: '0x7ff4657e000000000000000000000000de451f57d061b915525736937d0f5d24c551edd1000000000000000000000000000000000000000000000000000000000000004000000000000000000000000013263f73dcbe9b123a9ea32c13040b2becfe1e5c00000000000000000000000013263f73dcbe9b123a9ea32c13040b2becfe1e5c000000000000000000000000000000000000000000000000125195019f840000157f354383710432cdc131e73815a179a4e858ea304e4916b0f4d1db6553a7a70612db9f2ee9b8d7078e8f00338f600080ebc2a1e27f39376f54f0f6d7fb73750000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000044d41494e00000000000000000000000000000000000000000000000000000000',
84+
from: '0x57093C0C2aFEACaF7D677356c3eAC3E99933F7C0',
85+
nonce: '0x49',
86+
r: 0,
87+
s: 0,
88+
gas: '0x284d8'
89+
}
90+
91+
const pk = `3f28f888373e9ad1651a1227a5efdc0d7ea55bce6de3b5448de56c8588c6bd4d`;
92+
const pk2 = `dfac7a2bfe2cd7f7fc8caffd65995300eb0e1a652502147da8d7a9e5bce16ac2`;
93+
const from = `0x3444f14CbC7081ADEd7203E32E65304D17fe3bdA`;
94+
const sender = new TransactionSender(web3Mock, logger, {
95+
hsmPort: 6000,
96+
hsmHost: '127.0.0.1'
97+
});
98+
99+
const signedRawTransaction = await sender.signRawTransaction(rawTx, pk2, false);
100+
const r = signedRawTransaction.r.toString('hex');
101+
const s = signedRawTransaction.s.toString('hex');
102+
const v = signedRawTransaction.v.toString('hex');
103+
104+
const signedHsmRawTransaction = await sender.signRawTransaction(rawTx, pk2, true);
105+
const rHSM = signedHsmRawTransaction.r.toString('hex');
106+
const sHSM = signedHsmRawTransaction.s.toString('hex');
107+
const vHSM = signedHsmRawTransaction.v.toString('hex');
108+
109+
expect(rHSM).toEqual(r);
110+
expect(sHSM).toEqual(s);
111+
});
112+
113+
});

0 commit comments

Comments
 (0)