Skip to content

Commit

Permalink
Merge branch '2.x' into fix/utils-stripHexPrefix
Browse files Browse the repository at this point in the history
  • Loading branch information
nivida authored Aug 2, 2019
2 parents 67f7aca + 60ec964 commit d390665
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 64 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- ``ContractOptions`` type definitions corrected (#2939)
- Scrypt compatibility with older and newer nodejs versions fixed (#2952)
- Encryption of the V3Keystore fixed (#2950)
- Provider timeout fixed and Maps are used now to handle subscriptions (#2955)

1 change: 1 addition & 0 deletions docs/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ For web3.js, check ``Web3.givenProvider``. If this property is ``null`` you sho
.. code-block:: javascript
// in node.js use: const Web3 = require('web3');
// for a frontend app, you must be using webpack, otherwise you need to bundle the modules externally.
// use the given Provider, e.g in the browser with Metamask, or instantiate a new websocket provider
const web3 = new Web3(Web3.givenProvider || 'ws://localhost:8546', null, {});
Expand Down
8 changes: 5 additions & 3 deletions docs/web3-eth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1064,8 +1064,8 @@ Example
.. code-block:: javascript
const Tx = require('ethereumjs-tx');
const privateKey = new Buffer('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', 'hex')
const Tx = require('ethereumjs-tx').Transaction;
const privateKey = Buffer.from('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', 'hex')
const rawTx = {
nonce: '0x00',
Expand All @@ -1076,7 +1076,7 @@ Example
data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057'
}
const tx = new Tx(rawTx);
const tx = new Tx(rawTx, {'chain':'ropsten'});
tx.sign(privateKey);
const serializedTx = tx.serialize();
Expand All @@ -1089,6 +1089,8 @@ Example
> // see eth.getTransactionReceipt() for details
.. note:: When use the package `ethereumjs-tx` at the version of `2.x`, if we don't specify the parameter `chain`, it will use `mainnet`, so if you wan to use at the other network, you should add this parameter `chain` to specify.
------------------------------------------------------------------------------
sign
Expand Down
19 changes: 16 additions & 3 deletions packages/web3-eth-accounts/src/models/Account.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export default class Account {

// 64 hex characters + hex-prefix
if (privateKey.length !== 66) {
throw new Error("Private key must be 32 bytes long");
throw new Error('Private key must be 32 bytes long');
}

return new Account(EthLibAccount.fromPrivate(privateKey), accounts);
Expand Down Expand Up @@ -160,13 +160,26 @@ export default class Account {
if (kdf === 'pbkdf2') {
kdfparams.c = options.c || 262144;
kdfparams.prf = 'hmac-sha256';
derivedKey = pbkdf2Sync(Buffer.from(password), Buffer.from(kdfparams.salt, 'hex'), kdfparams.c, kdfparams.dklen, 'sha256');
derivedKey = pbkdf2Sync(
Buffer.from(password),
Buffer.from(kdfparams.salt, 'hex'),
kdfparams.c,
kdfparams.dklen,
'sha256'
);
} else if (kdf === 'scrypt') {
// FIXME: support progress reporting callback
kdfparams.n = options.n || 8192; // 2048 4096 8192 16384
kdfparams.r = options.r || 8;
kdfparams.p = options.p || 1;
derivedKey = scrypt(Buffer.from(password), Buffer.from(kdfparams.salt, 'hex'), kdfparams.n, kdfparams.r, kdfparams.p, kdfparams.dklen);
derivedKey = scrypt(
Buffer.from(password),
Buffer.from(kdfparams.salt, 'hex'),
kdfparams.n,
kdfparams.r,
kdfparams.p,
kdfparams.dklen
);
} else {
throw new Error('Unsupported kdf');
}
Expand Down
12 changes: 6 additions & 6 deletions packages/web3-eth-accounts/tests/src/models/AccountTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ describe('AccountTest', () => {

it('calls fromPrivateKey with incorrect private key length and throws error', () => {
expect(() => {
Account.fromPrivateKey('asdfasdf')
Account.fromPrivateKey('asdfasdf');
}).toThrow('Private key must be 32 bytes long');
});

it('calls fromPrivateKey with incorrect private key prefix and throws error', () => {
mockKey = '0z0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef';

expect(() => {
Account.fromPrivateKey(mockKey)
Account.fromPrivateKey(mockKey);
}).toThrow('Private key must be 32 bytes long');
});

Expand Down Expand Up @@ -167,9 +167,9 @@ describe('AccountTest', () => {
final: jest.fn()
};

decipher.update.mockReturnValueOnce(Buffer.from(mockKey.slice(2,34), 'hex'));
decipher.update.mockReturnValueOnce(Buffer.from(mockKey.slice(2, 34), 'hex'));

decipher.final.mockReturnValueOnce(Buffer.from(mockKey.slice(34,66), 'hex'));
decipher.final.mockReturnValueOnce(Buffer.from(mockKey.slice(34, 66), 'hex'));

createDecipheriv.mockReturnValueOnce(decipher);

Expand Down Expand Up @@ -233,9 +233,9 @@ describe('AccountTest', () => {
final: jest.fn()
};

decipher.update.mockReturnValueOnce(Buffer.from(mockKey.slice(2,34), 'hex'));
decipher.update.mockReturnValueOnce(Buffer.from(mockKey.slice(2, 34), 'hex'));

decipher.final.mockReturnValueOnce(Buffer.from(mockKey.slice(34,66), 'hex'));
decipher.final.mockReturnValueOnce(Buffer.from(mockKey.slice(34, 66), 'hex'));

createDecipheriv.mockReturnValueOnce(decipher);

Expand Down
39 changes: 20 additions & 19 deletions packages/web3-providers/lib/providers/AbstractSocketProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export default class AbstractSocketProvider extends EventEmitter {
super();
this.connection = connection;
this.timeout = timeout;
this.subscriptions = {};
this.subscriptions = new Map();
this.registerEventListeners();

this.READY = 'ready';
Expand Down Expand Up @@ -188,23 +188,23 @@ export default class AbstractSocketProvider extends EventEmitter {
* @method onConnect
*/
async onConnect() {
const subscriptionKeys = Object.keys(this.subscriptions);
if (this.subscriptions.size > 0) {
let subscriptionId, value;

if (subscriptionKeys.length > 0) {
let subscriptionId;
for (let item of this.subscriptions) {
value = item[1];

for (let key of subscriptionKeys) {
subscriptionId = await this.subscribe(
this.subscriptions[key].subscribeMethod,
this.subscriptions[key].parameters[0],
this.subscriptions[key].parameters.slice(1)
value.subscribeMethod,
value.parameters[0],
value.parameters.slice(1)
);

if (key !== subscriptionId) {
delete this.subscriptions[subscriptionId];
if (item[0] !== subscriptionId) {
this.subscriptions.delete(subscriptionId);
}

this.subscriptions[key].id = subscriptionId;
value.id = subscriptionId;
}
}

Expand Down Expand Up @@ -265,11 +265,11 @@ export default class AbstractSocketProvider extends EventEmitter {

return this.send(subscribeMethod, parameters)
.then((subscriptionId) => {
this.subscriptions[subscriptionId] = {
this.subscriptions.set(subscriptionId, {
id: subscriptionId,
subscribeMethod: subscribeMethod,
parameters: parameters
};
});

return subscriptionId;
})
Expand All @@ -294,7 +294,7 @@ export default class AbstractSocketProvider extends EventEmitter {
if (response) {
this.removeAllListeners(this.getSubscriptionEvent(subscriptionId));

delete this.subscriptions[subscriptionId];
this.subscriptions.delete(subscriptionId);
}

return response;
Expand All @@ -316,9 +316,10 @@ export default class AbstractSocketProvider extends EventEmitter {
clearSubscriptions(unsubscribeMethod = 'eth_unsubscribe') {
let unsubscribePromises = [];

Object.keys(this.subscriptions).forEach((key) => {
this.subscriptions.forEach((value, key) => {
this.removeAllListeners(key);
unsubscribePromises.push(this.unsubscribe(this.subscriptions[key].id, unsubscribeMethod));

unsubscribePromises.push(this.unsubscribe(value.id, unsubscribeMethod));
});

return Promise.all(unsubscribePromises).then((results) => {
Expand Down Expand Up @@ -353,13 +354,13 @@ export default class AbstractSocketProvider extends EventEmitter {
* @returns {String}
*/
getSubscriptionEvent(subscriptionId) {
if (this.subscriptions[subscriptionId]) {
if (this.subscriptions.get(subscriptionId)) {
return subscriptionId;
}

let event;
Object.keys(this.subscriptions).forEach((key) => {
if (this.subscriptions[key].id === subscriptionId) {
this.subscriptions.forEach((value, key) => {
if (value.id === subscriptionId) {
event = key;
}
});
Expand Down
6 changes: 2 additions & 4 deletions packages/web3-providers/src/providers/MetamaskProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ export default class MetamaskProvider extends AbstractSocketProvider {
* @method removeAllSocketListeners
*/
removeAllSocketListeners() {
this.connection.removeListener(this.SOCKET_NETWORK_CHANGED, this.onNetworkChanged);
this.connection.removeListener(this.SOCKET_ACCOUNTS_CHANGED, this.onAccountsChanged);
this.removeAllListeners(this.SOCKET_ACCOUNTS_CHANGED);
this.removeAllListeners(this.SOCKET_NETWORK_CHANGED);

super.removeAllSocketListeners();
}
Expand Down Expand Up @@ -141,8 +141,6 @@ export default class MetamaskProvider extends AbstractSocketProvider {
sendPayload(payload) {
return new Promise((resolve, reject) => {
this.connection.send(payload, (error, response) => {
this.removeAllListeners(payload.id);

if (!error) {
return resolve(response);
}
Expand Down
2 changes: 0 additions & 2 deletions packages/web3-providers/src/providers/MistEthereumProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ export default class MistEthereumProvider extends AbstractSocketProvider {
sendPayload(payload) {
return new Promise((resolve, reject) => {
this.connection.send(payload, (error, response) => {
this.removeAllListeners(payload.id);

if (!error) {
return resolve(response);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ export default class Web3EthereumProvider extends AbstractSocketProvider {
* @method removeAllSocketListeners
*/
removeAllSocketListeners() {
this.connection.removeAllListeners();
this.removeAllListeners(this.SOCKET_ACCOUNTS_CHANGED);
this.removeAllListeners(this.SOCKET_NETWORK_CHANGED);

super.removeAllSocketListeners()
}

/**
Expand Down
15 changes: 9 additions & 6 deletions packages/web3-providers/src/providers/WebsocketProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,18 +217,21 @@ export default class WebsocketProvider extends AbstractSocketProvider {
return reject(error);
}

if (this.timeout) {
timeout = setTimeout(() => {
reject(new Error('Connection error: Timeout exceeded'));
}, this.timeout);
}

if (isArray(payload)) {
id = payload[0].id;
} else {
id = payload.id;
}

if (this.timeout) {
timeout = setTimeout(() => {
this.removeListener('error', reject);
this.removeAllListeners(id);

reject(new Error('Connection error: Timeout exceeded'));
}, this.timeout);
}

this.once(id, (response) => {
if (timeout) {
clearTimeout(timeout);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('AbstractSocketProviderTest', () => {

expect(abstractSocketProvider.timeout).toEqual(0);

expect(abstractSocketProvider.subscriptions).toEqual({});
expect(abstractSocketProvider.subscriptions).toEqual(new Map());

expect(abstractSocketProvider.connection).toEqual(socketMock);

Expand Down Expand Up @@ -120,11 +120,11 @@ describe('AbstractSocketProviderTest', () => {
const callback = jest.fn();
abstractSocketProvider.on('connect', callback);

abstractSocketProvider.subscriptions['0x0'] = {
abstractSocketProvider.subscriptions.set('0x0', {
id: '0x0',
subscribeMethod: 'eth_subscribe',
parameters: ['logs', {}]
};
});

abstractSocketProvider.send = jest.fn((subscribeMethod, parameters) => {
expect(subscribeMethod).toEqual('eth_subscribe');
Expand All @@ -138,7 +138,7 @@ describe('AbstractSocketProviderTest', () => {

expect(callback).toHaveBeenCalled();

expect(abstractSocketProvider.subscriptions['0x0'].id).toEqual('0x1');
expect(abstractSocketProvider.subscriptions.get('0x0').id).toEqual('0x1');

expect(abstractSocketProvider.send).toHaveBeenCalled();
});
Expand All @@ -164,7 +164,7 @@ describe('AbstractSocketProviderTest', () => {
});

it('calls onMessage and the subscription id will be used as event name', (done) => {
abstractSocketProvider.subscriptions['0x0'] = {subscription: '0x0'};
abstractSocketProvider.subscriptions.set('0x0', {subscription: '0x0'});

abstractSocketProvider.on('0x0', (response) => {
expect(response).toEqual({subscription: '0x0'});
Expand Down Expand Up @@ -209,7 +209,7 @@ describe('AbstractSocketProviderTest', () => {

expect(response).toEqual('0x1');

expect(abstractSocketProvider.subscriptions['0x1'].id).toEqual('0x1');
expect(abstractSocketProvider.subscriptions.get('0x1').id).toEqual('0x1');

expect(abstractSocketProvider.send).toHaveBeenCalled();
});
Expand All @@ -234,8 +234,8 @@ describe('AbstractSocketProviderTest', () => {
);
});

it('calls unsubscribe and resolves to a promise', async () => {
abstractSocketProvider.subscriptions['0x0'] = true;
it('calls unsubscribe and resolves the returned Promise object', async () => {
abstractSocketProvider.subscriptions.set('0x0', true);
abstractSocketProvider.removeAllListeners = jest.fn();

abstractSocketProvider.send = jest.fn((subscribeMethod, parameters) => {
Expand All @@ -252,11 +252,11 @@ describe('AbstractSocketProviderTest', () => {

expect(abstractSocketProvider.removeAllListeners).toHaveBeenCalledWith('0x0');

expect(abstractSocketProvider.subscriptions['0x0']).toBeUndefined();
expect(abstractSocketProvider.subscriptions.get('0x0')).toBeUndefined();
});

it('calls clearSubscriptions and one unsubscribe call returns false', async () => {
abstractSocketProvider.subscriptions['0x0'] = {id: '0x0'};
abstractSocketProvider.subscriptions.set('0x0', {id: '0x0'});
abstractSocketProvider.removeAllListeners = jest.fn();

abstractSocketProvider.send = jest.fn((subscribeMethod, parameters) => {
Expand All @@ -275,7 +275,7 @@ describe('AbstractSocketProviderTest', () => {
});

it('calls clearSubscriptions and all unsubscribe calls are returning true', async () => {
abstractSocketProvider.subscriptions['0x0'] = {id: '0x0'};
abstractSocketProvider.subscriptions.set('0x0', {id: '0x0'});
abstractSocketProvider.removeAllListeners = jest.fn();

abstractSocketProvider.send = jest.fn((subscribeMethod, parameters) => {
Expand All @@ -292,11 +292,11 @@ describe('AbstractSocketProviderTest', () => {

expect(abstractSocketProvider.removeAllListeners).toHaveBeenCalledWith('0x0');

expect(abstractSocketProvider.subscriptions).toEqual({});
expect(abstractSocketProvider.subscriptions).toEqual(new Map());
});

it('calls getSubscriptionEvent and has to iterate over all items', () => {
abstractSocketProvider.subscriptions['ID'] = {id: '0x0'};
abstractSocketProvider.subscriptions.set('ID', {id: '0x0'});

expect(abstractSocketProvider.getSubscriptionEvent('0x0')).toEqual('ID');
});
Expand Down
Loading

0 comments on commit d390665

Please sign in to comment.