diff --git a/packages/xrpl/src/client/index.ts b/packages/xrpl/src/client/index.ts index 2557539c..9fedf64d 100644 --- a/packages/xrpl/src/client/index.ts +++ b/packages/xrpl/src/client/index.ts @@ -235,8 +235,6 @@ class Client extends EventEmitter { this.feeCushion = options.feeCushion ?? DEFAULT_FEE_CUSHION this.maxFeeXRP = options.maxFeeXRP ?? DEFAULT_MAX_FEE_XRP - this.networkID = undefined - this.buildVersion = undefined this.connection = new Connection(server, options) diff --git a/packages/xrpl/src/sugar/autofill.ts b/packages/xrpl/src/sugar/autofill.ts index 92614248..45f6ee9d 100644 --- a/packages/xrpl/src/sugar/autofill.ts +++ b/packages/xrpl/src/sugar/autofill.ts @@ -13,6 +13,8 @@ import getFeeXrp from './getFeeXrp' // Expire unconfirmed transactions after 20 ledger versions, approximately 1 minute, by default const LEDGER_OFFSET = 20 // Sidechains are expected to have network IDs above this. +// Networks with ID above this restricted number are expected specify an accurate NetworkID field +// in every transaction to that chain to prevent replay attacks. // Mainnet and testnet are exceptions. More context: https://github.com/XRPLF/rippled/pull/4370 const RESTRICTED_NETWORKS = 1024 const REQUIRED_NETWORKID_VERSION = '1.11.0' @@ -95,6 +97,15 @@ async function autofill( return Promise.all(promises).then(() => tx) } +/** + * Determines whether the source rippled version is ealier than the target rippled version. + * Example usage: isEarlierRippledVersion('1.10.0', '1.11.0') returns true. + * isEarlierRippledVersion('1.10.0', '1.10.0-b1') returns false. + * + * @param source -- The source rippled version. + * @param target -- The target rippled version. + * @returns True if source is earlier than target, false otherwise. + */ // eslint-disable-next-line max-lines-per-function, max-statements -- Disable for this helper functions. function isEarlierRippledVersion(source: string, target: string): boolean { if (source === target) { @@ -152,13 +163,21 @@ function isEarlierRippledVersion(source: string, target: string): boolean { return false } +/** + * Determine if the transaction required a networkID to be valid. + * Transaction needs networkID if later than restricted ID and either the network is hooks testnet + * or build version is >= 1.11.0 + * + * @param client -- The connected client. + * @returns True if required networkID, false otherwise. + */ function txNeedsNetworkID(client: Client): boolean { if ( client.networkID !== undefined && client.networkID > RESTRICTED_NETWORKS ) { - // transaction needs networkID if either the network is hooks testnet or build version is >= 1.11.0 // TODO: remove the buildVersion logic when 1.11.0 is out and widely used. + // Issue: https://github.com/XRPLF/xrpl.js/issues/2339 if ( (client.buildVersion && isEarlierRippledVersion( diff --git a/packages/xrpl/test/client/autofill.test.ts b/packages/xrpl/test/client/autofill.test.ts index 2d4db695..e900b777 100644 --- a/packages/xrpl/test/client/autofill.test.ts +++ b/packages/xrpl/test/client/autofill.test.ts @@ -81,6 +81,8 @@ describe('client.autofill', function () { assert.strictEqual(txResult.NetworkID, undefined) }) + // NetworkID is required in transaction for network > 1024 and from version 1.11.0 or later. + // More context: https://github.com/XRPLF/rippled/pull/4370 it('overrides network ID if > 1024 and version is later than 1.11.0', async function () { await setupMockRippledVersionAndID('1.11.1', 1025) const tx: Payment = { @@ -99,6 +101,8 @@ describe('client.autofill', function () { assert.strictEqual(txResult.NetworkID, 1025) }) + // NetworkID is only required in transaction for version 1.11.0 or later. + // More context: https://github.com/XRPLF/rippled/pull/4370 it('ignores network ID if > 1024 but version is earlier than 1.11.0', async function () { await setupMockRippledVersionAndID('1.10.0', 1025) const tx: Payment = { @@ -117,6 +121,8 @@ describe('client.autofill', function () { assert.strictEqual(txResult.NetworkID, undefined) }) + // NetworkID <= 1024 does not require a newtorkID in transaction. + // More context: https://github.com/XRPLF/rippled/pull/4370 it('ignores network ID if <= 1024', async function () { await setupMockRippledVersionAndID('1.11.1', 1023) const tx: Payment = { @@ -135,7 +141,9 @@ describe('client.autofill', function () { assert.strictEqual(txResult.NetworkID, undefined) }) - it('override network ID for hooks testnet', async function () { + // Hooks Testnet requires networkID in transaction regardless of version. + // More context: https://github.com/XRPLF/rippled/pull/4370 + it('overrides network ID for hooks testnet', async function () { await setupMockRippledVersionAndID('1.10.1', HOOKS_TESTNET_ID) const tx: Payment = { TransactionType: 'Payment',