-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
146 additions
and
128 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,107 @@ | ||
import { KeyManager, ServerDependencies, StoredTransaction, TransactionManager, TxStoreManager } from "@rsksmart/rif-relay-server"; | ||
import { | ||
KeyManager, | ||
ServerDependencies, | ||
StoredTransaction, | ||
TransactionManager, | ||
TxStoreManager, | ||
} from '@rsksmart/rif-relay-server'; | ||
import { expect, use } from 'chai'; | ||
import { BigNumber, PopulatedTransaction } from "ethers"; | ||
import { BigNumber, PopulatedTransaction } from 'ethers'; | ||
import fs from 'fs/promises'; | ||
import sinon from "sinon"; | ||
import sinon from 'sinon'; | ||
import sinonChai from 'sinon-chai'; | ||
|
||
use(sinonChai); | ||
|
||
describe('TransactionManager', function () { | ||
const workdir = '/tmp/env-test'; | ||
let txManager: TransactionManager; | ||
let workersKeyManager: KeyManager; | ||
let workerAddress: string; | ||
const workdir = '/tmp/env-test'; | ||
let txManager: TransactionManager; | ||
let workersKeyManager: KeyManager; | ||
let workerAddress: string; | ||
|
||
beforeEach(async function () { | ||
const managerKeyManager = new KeyManager(1, workdir); | ||
workersKeyManager = new KeyManager(1, workdir); | ||
workerAddress = workersKeyManager.getAddress(0)!; | ||
const txStoreManager = new TxStoreManager({ workdir }) | ||
const dependencies: ServerDependencies = { | ||
managerKeyManager, | ||
workersKeyManager, | ||
txStoreManager | ||
}; | ||
await txStoreManager.putTx({ | ||
txId: 'id1', | ||
attempts: 1, | ||
nonce: 1, | ||
creationBlockNumber: 0, | ||
gasLimit: BigNumber.from(1), | ||
gasPrice: BigNumber.from(1), | ||
nonceSigner: { | ||
nonce: 1, | ||
signer: workerAddress | ||
}, | ||
from: workerAddress | ||
} as StoredTransaction); | ||
await txStoreManager.putTx({ | ||
txId: 'id2', | ||
attempts: 1, | ||
nonce: 2, | ||
creationBlockNumber: 0, | ||
gasLimit: BigNumber.from(1), | ||
gasPrice: BigNumber.from(2), | ||
nonceSigner: { | ||
nonce: 2, | ||
signer: workerAddress | ||
}, | ||
from: workerAddress | ||
} as StoredTransaction); | ||
beforeEach(async function () { | ||
const managerKeyManager = new KeyManager(1, workdir); | ||
workersKeyManager = new KeyManager(1, workdir); | ||
workerAddress = workersKeyManager.getAddress(0)!; | ||
const txStoreManager = new TxStoreManager({ workdir }); | ||
const dependencies: ServerDependencies = { | ||
managerKeyManager, | ||
workersKeyManager, | ||
txStoreManager, | ||
}; | ||
await txStoreManager.putTx({ | ||
txId: 'id1', | ||
attempts: 1, | ||
nonce: 1, | ||
creationBlockNumber: 0, | ||
gasLimit: BigNumber.from(1), | ||
gasPrice: BigNumber.from(1), | ||
nonceSigner: { | ||
nonce: 1, | ||
signer: workerAddress, | ||
}, | ||
from: workerAddress, | ||
} as StoredTransaction); | ||
await txStoreManager.putTx({ | ||
txId: 'id2', | ||
attempts: 1, | ||
nonce: 2, | ||
creationBlockNumber: 0, | ||
gasLimit: BigNumber.from(1), | ||
gasPrice: BigNumber.from(2), | ||
nonceSigner: { | ||
nonce: 2, | ||
signer: workerAddress, | ||
}, | ||
from: workerAddress, | ||
} as StoredTransaction); | ||
|
||
txManager = new TransactionManager(dependencies); | ||
}) | ||
txManager = new TransactionManager(dependencies); | ||
}); | ||
|
||
it('should boost underpriced pending transactions for a given signer', async function () { | ||
const currentBlockHeight = 100; | ||
sinon.stub(txManager, '_resolveNewGasPrice').returns({ | ||
isMaxGasPriceReached: false, | ||
newGasPrice: BigNumber.from(3) | ||
}); | ||
const resendTransactionStub = sinon.stub(txManager, "resendTransaction").callsFake(async ( | ||
tx: StoredTransaction, | ||
_: number, | ||
newGasPrice: BigNumber, | ||
__: boolean) => { | ||
const { | ||
to, | ||
from, | ||
nonce, | ||
gasLimit, | ||
} = tx | ||
const txToSign: PopulatedTransaction = { | ||
to, | ||
from, | ||
nonce, | ||
gasLimit, | ||
gasPrice: newGasPrice, | ||
}; | ||
const signedTransaction = await workersKeyManager.signTransaction( | ||
tx.from, | ||
txToSign | ||
); | ||
|
||
return signedTransaction; | ||
}) | ||
it('should boost underpriced pending transactions for a given signer', async function () { | ||
const currentBlockHeight = 100; | ||
sinon.stub(txManager, '_resolveNewGasPrice').returns({ | ||
isMaxGasPriceReached: false, | ||
newGasPrice: BigNumber.from(3), | ||
}); | ||
const resendTransactionStub = sinon | ||
.stub(txManager, 'resendTransaction') | ||
.callsFake( | ||
async ( | ||
tx: StoredTransaction, | ||
_: number, | ||
newGasPrice: BigNumber, | ||
__: boolean | ||
) => { | ||
const { to, from, nonce, gasLimit } = tx; | ||
const txToSign: PopulatedTransaction = { | ||
to, | ||
from, | ||
nonce, | ||
gasLimit, | ||
gasPrice: newGasPrice, | ||
}; | ||
const signedTransaction = await workersKeyManager.signTransaction( | ||
tx.from, | ||
txToSign | ||
); | ||
|
||
const boostedTransactions = await txManager.boostUnderpricedPendingTransactionsForSigner(workerAddress, currentBlockHeight); | ||
return signedTransaction; | ||
} | ||
); | ||
|
||
expect(resendTransactionStub).to.have.been.callCount(2); | ||
expect(boostedTransactions.size).to.be.eql(2); | ||
}); | ||
const boostedTransactions = | ||
await txManager.boostUnderpricedPendingTransactionsForSigner( | ||
workerAddress, | ||
currentBlockHeight | ||
); | ||
|
||
expect(resendTransactionStub).to.have.been.callCount(2); | ||
expect(boostedTransactions.size).to.be.eql(2); | ||
}); | ||
|
||
afterEach(async function () { | ||
await fs.rm(workdir, { recursive: true, force: true }); | ||
}) | ||
afterEach(async function () { | ||
await fs.rm(workdir, { recursive: true, force: true }); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,61 @@ | ||
import { expect } from 'chai'; | ||
import { KeyManager, StoredTransaction, TxStoreManager } from "@rsksmart/rif-relay-server"; | ||
import { BigNumber } from "ethers"; | ||
import { | ||
KeyManager, | ||
StoredTransaction, | ||
TxStoreManager, | ||
} from '@rsksmart/rif-relay-server'; | ||
import { BigNumber } from 'ethers'; | ||
import fs from 'fs/promises'; | ||
|
||
describe('TxStoreManager', function () { | ||
const workdir = '/tmp/env-test'; | ||
it('should return transactions with gasLimit and gasPrice as BigNumber', async function() { | ||
const workersKeyManager = new KeyManager(1, workdir); | ||
const workerAddress = workersKeyManager.getAddress(0)!; | ||
const txStoreManager = new TxStoreManager({workdir}) | ||
await txStoreManager.putTx({ | ||
txId: 'id1', | ||
attempts: 1, | ||
nonce: 1, | ||
creationBlockNumber: 0, | ||
gasLimit: BigNumber.from(1), | ||
gasPrice: BigNumber.from(1), | ||
nonceSigner: { | ||
nonce: 1, | ||
signer: workerAddress | ||
}, | ||
from: workerAddress | ||
} as StoredTransaction); | ||
await txStoreManager.putTx({ | ||
txId: 'id2', | ||
attempts: 1, | ||
nonce: 2, | ||
creationBlockNumber: 0, | ||
gasLimit: BigNumber.from(1), | ||
gasPrice: BigNumber.from(2), | ||
nonceSigner: { | ||
nonce: 2, | ||
signer: workerAddress | ||
}, | ||
from: workerAddress | ||
} as StoredTransaction); | ||
const workdir = '/tmp/env-test'; | ||
it('should return transactions with gasLimit and gasPrice as BigNumber', async function () { | ||
const workersKeyManager = new KeyManager(1, workdir); | ||
const workerAddress = workersKeyManager.getAddress(0)!; | ||
const txStoreManager = new TxStoreManager({ workdir }); | ||
await txStoreManager.putTx({ | ||
txId: 'id1', | ||
attempts: 1, | ||
nonce: 1, | ||
creationBlockNumber: 0, | ||
gasLimit: BigNumber.from(1), | ||
gasPrice: BigNumber.from(1), | ||
nonceSigner: { | ||
nonce: 1, | ||
signer: workerAddress, | ||
}, | ||
from: workerAddress, | ||
} as StoredTransaction); | ||
await txStoreManager.putTx({ | ||
txId: 'id2', | ||
attempts: 1, | ||
nonce: 2, | ||
creationBlockNumber: 0, | ||
gasLimit: BigNumber.from(1), | ||
gasPrice: BigNumber.from(2), | ||
nonceSigner: { | ||
nonce: 2, | ||
signer: workerAddress, | ||
}, | ||
from: workerAddress, | ||
} as StoredTransaction); | ||
|
||
const txs = await txStoreManager.getAllBySigner(workerAddress); | ||
const txs = await txStoreManager.getAllBySigner(workerAddress); | ||
|
||
const bn = BigNumber.from(1); | ||
const bigNumberProperties = Object.getOwnPropertyNames(bn); | ||
const isBigNumber = (value: any) => bigNumberProperties.every(prop => prop in value); | ||
const txExpectation = ({gasPrice, gasLimit}: StoredTransaction) => isBigNumber(gasPrice) && isBigNumber(gasLimit); | ||
const bn = BigNumber.from(1); | ||
const bigNumberProperties = Object.getOwnPropertyNames(bn); | ||
const isBigNumber = (value: any) => | ||
bigNumberProperties.every((prop) => prop in value); | ||
const txExpectation = ({ gasPrice, gasLimit }: StoredTransaction) => | ||
isBigNumber(gasPrice) && isBigNumber(gasLimit); | ||
|
||
expect(txs.every(txExpectation), 'the objects returned do not have gasPrice and gasLimit as BigNumber').to.be.true; | ||
|
||
}); | ||
expect( | ||
txs.every(txExpectation), | ||
'the objects returned do not have gasPrice and gasLimit as BigNumber' | ||
).to.be.true; | ||
}); | ||
|
||
afterEach(async function() { | ||
await fs.rm(workdir, {recursive: true, force: true}); | ||
}) | ||
afterEach(async function () { | ||
await fs.rm(workdir, { recursive: true, force: true }); | ||
}); | ||
}); |