update isSigned null check to handle multi-signed transactions (#2308)

* update isSigned null check to use &&

* update isSigned to handle multi-signed transactions

* add unit test for multi-signed transaction

---------

Co-authored-by: Elliot Lee <github.public@intelliot.com>
This commit is contained in:
Omar Khan
2023-05-18 18:51:00 -04:00
committed by GitHub
parent add72a175d
commit 97b2e668ab
2 changed files with 48 additions and 7 deletions

View File

@@ -2,6 +2,7 @@ import { decode, encode } from 'ripple-binary-codec'
import type { Client, SubmitRequest, SubmitResponse, Wallet } from '..'
import { ValidationError, XrplError } from '../errors'
import { Signer } from '../models/common'
import { TxResponse } from '../models/methods'
import { Transaction } from '../models/transactions'
import { hashes } from '../utils'
@@ -222,10 +223,26 @@ async function waitForFinalTransactionOutcome(
// checks if the transaction has been signed
function isSigned(transaction: Transaction | string): boolean {
const tx = typeof transaction === 'string' ? decode(transaction) : transaction
return (
typeof tx !== 'string' &&
(tx.SigningPubKey != null || tx.TxnSignature != null)
)
if (typeof tx === 'string') {
return false
}
if (tx.Signers != null) {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- we know that tx.Signers is an array of Signers
const signers = tx.Signers as Signer[]
for (const signer of signers) {
// eslint-disable-next-line max-depth -- necessary for checking if signer is signed
if (
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- necessary check
signer.Signer.SigningPubKey == null ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- necessary check
signer.Signer.TxnSignature == null
) {
return false
}
}
return true
}
return tx.SigningPubKey != null && tx.TxnSignature != null
}
// initializes a transaction for a submit request

View File

@@ -1,7 +1,8 @@
/* eslint-disable @typescript-eslint/restrict-template-expressions -- error type thrown can be any */
import { assert } from 'chai'
import cloneDeep from 'lodash/cloneDeep'
import { ValidationError } from '../../src'
import { multisign, ValidationError } from '../../src'
import { Transaction } from '../../src/models/transactions'
import Wallet from '../../src/Wallet'
import rippled from '../fixtures/rippled'
@@ -56,7 +57,6 @@ describe('client.submit', function () {
const response = await testContext.client.submit(tx, { wallet })
assert(response.result.engine_result, 'tesSUCCESS')
} catch (error) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions -- error type thrown can be any
assert(false, `Did not expect an error to be thrown: ${error}`)
}
})
@@ -114,7 +114,31 @@ describe('client.submit', function () {
const response = await testContext.client.submit(signedTxEncoded)
assert(response.result.engine_result, 'tesSUCCESS')
} catch (error) {
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions -- error type thrown can be any
assert(false, `Did not expect an error to be thrown: ${error}`)
}
})
it('should submit a multisigned transaction', async function () {
const signerWallet1 = Wallet.generate()
const signerWallet2 = Wallet.generate()
const accountSetTx: Transaction = {
TransactionType: 'AccountSet',
Account: 'rhvh5SrgBL5V8oeV9EpDuVszeJSSCEkbPc',
Sequence: 1,
Fee: '12',
LastLedgerSequence: 12312,
}
testContext.mockRippled!.addResponse('submit', rippled.submit.success)
const signed1 = signerWallet1.sign(accountSetTx, true)
const signed2 = signerWallet2.sign(accountSetTx, true)
const multisignedTxEncoded = multisign([signed1.tx_blob, signed2.tx_blob])
try {
const response = await testContext.client.submit(multisignedTxEncoded)
assert(response.result.engine_result, 'tesSUCCESS')
} catch (error) {
assert(false, `Did not expect an error to be thrown: ${error}`)
}
})