Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Test Coverage for packages/web3/src/transaction #462

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 114 additions & 1 deletion packages/web3/src/transaction/sign-verify.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import EC from 'elliptic'

import { transactionSign, transactionVerifySignature } from './sign-verify'
import { KeyType } from '../signer'

describe('transaction', function () {
it('should verify signature', () => {
Expand Down Expand Up @@ -46,4 +46,117 @@ describe('transaction', function () {
const signature = transactionSign(txHash, privateKey)
expect(transactionVerifySignature(txHash, publicKey, signature)).toEqual(true)
})

describe('transactionVerifySignature additional tests', () => {
const validTxHash = '8fc5f0d120b730f97f6cea5f02ae4a6ee7bf451d9261c623ea69d85e870201d2'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can

  1. Use randomTxId() function to create a validTxId
  2. Create validPubKey using PrivateKeyWallet.Random
  3. Generate the validSignature

So we don't need to hardcode value here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok sure. Thanks

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since I can't find a randomTxId() function, I actually don't know if there is a randomTxId() function somewhere. Hope I can create my own generateRandomTxId() function to achieve a good implementation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its in import { randomTxId } from '../contract'.

const validPubKey = '02625b26ae1c5f7986475009e4037b3e6fe6320fde3c3f3332bea11ecadc35dd13'
const validSignature = '78471e7c97e558c98ac307ef699ed535ece319102fc69ea416dbb44fbb3cbf9c42dbfbf4ce73eb68c5e0d66122eb25d2ebe1cf9e37ef4c4f4e7a2ed35de141bc'

it('should handle different key types', () => {
const ec = new EC.ec('secp256k1')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use PrivateKeyWallet.Random to generate key pair.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I will implement this

const key = ec.genKeyPair()
const privateKey = key.getPrivate().toString('hex')
const publicKey = key.getPublic().encode('hex', true)
const txHash = validTxHash

const signature = transactionSign(txHash, privateKey)
expect(transactionVerifySignature(txHash, publicKey, signature)).toEqual(true)
})

it('should handle invalid public keys', () => {
expect(transactionVerifySignature(validTxHash, 'invalid-pubkey', validSignature)).toEqual(false)
expect(transactionVerifySignature(validTxHash, '', validSignature)).toEqual(false)
expect(transactionVerifySignature(validTxHash, '0123456789', validSignature)).toEqual(false)
})

it('should handle invalid transaction hashes', () => {
expect(transactionVerifySignature('invalid-hash', validPubKey, validSignature)).toEqual(false)
expect(transactionVerifySignature('', validPubKey, validSignature)).toEqual(false)
expect(transactionVerifySignature('0123456789', validPubKey, validSignature)).toEqual(false)
})

it('should handle invalid signatures', () => {
expect(transactionVerifySignature(validTxHash, validPubKey, 'invalid-sig')).toEqual(false)
expect(transactionVerifySignature(validTxHash, validPubKey, '')).toEqual(false)
expect(transactionVerifySignature(validTxHash, validPubKey, '0123456789')).toEqual(false)
})
})

})

describe('transactionSign additional tests', () => {
const validTxHash = '8fc5f0d120b730f97f6cea5f02ae4a6ee7bf451d9261c623ea69d85e870201d2'
const validPubKey = '02625b26ae1c5f7986475009e4037b3e6fe6320fde3c3f3332bea11ecadc35dd13'

it('should handle invalid private keys', () => {
// Test with invalid private key formats
const invalidPrivateKeys = ['invalid-key', '', '0123456789', 'not-hex', '@#$%^&*']

invalidPrivateKeys.forEach(invalidKey => {
// Since invalid private keys might throw errors, we wrap in try-catch
try {
const signature = transactionSign(validTxHash, invalidKey)
// If no error thrown, the signature should fail verification
expect(transactionVerifySignature(validTxHash, validPubKey, signature)).toBeFalsy()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there two possible outcomes?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is overly complex, It will always throw an error. I will be providing a correct implementation

} catch (error) {
// Error thrown is also an acceptable outcome
expect(error).toBeTruthy()
}
})
})

it('should handle invalid transaction hashes', () => {
// Generate a valid private key for testing
const ec = new EC.ec('secp256k1')
const keyPair = ec.genKeyPair()
const validPrivateKey = keyPair.getPrivate().toString('hex')

// Test with invalid transaction hash formats
const invalidHashes = ['invalid-hash', '', '0123456789', 'not-hex', '@#$%^&*']

invalidHashes.forEach(invalidHash => {
const signature = transactionSign(invalidHash, validPrivateKey)
// Either the signature should be invalid when verified, or signing should return an empty/invalid signature
if (signature) {
expect(transactionVerifySignature(invalidHash, validPubKey, signature)).toBeFalsy()
} else {
expect(signature).toBeFalsy()
}
})
})

it('should handle various combinations of invalid inputs', () => {
// Test with combinations of invalid inputs
const invalidInputs = ['invalid-input', '', '0123456789']

invalidInputs.forEach(invalidInput => {
// Test invalid hash with valid private key
const ec = new EC.ec('secp256k1')
const keyPair = ec.genKeyPair()
const validPrivateKey = keyPair.getPrivate().toString('hex')

try {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In all the places where we have the pattern of

try {
   verify something
} catch (e) {
   error is ok
}

Shall we be explicit about the outcome? Either we should expect an error or we the condition of the verification should match.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

const sig1 = transactionSign(invalidInput, validPrivateKey)
expect(transactionVerifySignature(invalidInput, validPubKey, sig1)).toBeFalsy()
} catch (error) {
expect(error).toBeTruthy()
}

// Test valid hash with invalid private key
try {
const sig2 = transactionSign(validTxHash, invalidInput)
expect(transactionVerifySignature(validTxHash, validPubKey, sig2)).toBeFalsy()
} catch (error) {
expect(error).toBeTruthy()
}

// Test both invalid hash and invalid private key
try {
const sig3 = transactionSign(invalidInput, invalidInput)
expect(transactionVerifySignature(invalidInput, validPubKey, sig3)).toBeFalsy()
} catch (error) {
expect(error).toBeTruthy()
}
})
})
})
Loading