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

Deep Freeze XLS-77d #2873

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .ci-config/rippled.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,4 @@ fixNFTokenPageLinks
fixInnerObjTemplate2
fixEnforceNFTokenTrustline
fixReducedOffersV2
DeepFreeze
3 changes: 3 additions & 0 deletions packages/xrpl/HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xr
### Changed
* Deprecated `setTransactionFlagsToNumber`. Start using convertTxFlagsToNumber instead

### Added
* Support for XLS-77d Deep-Freeze amendment

## 4.1.0 (2024-12-23)

### Added
Expand Down
4 changes: 4 additions & 0 deletions packages/xrpl/src/models/ledger/RippleState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,8 @@ export enum RippleStateFlags {
lsfHighFreeze = 0x00800000,
// True, trust line to AMM. Used by client apps to identify payments via AMM.
lsfAMMNode = 0x01000000,
// True, low side has set deep freeze flag
lsfLowDeepFreeze = 0x02000000,
// True, high side has set deep freeze flag
lsfHighDeepFreeze = 0x04000000,
}
10 changes: 10 additions & 0 deletions packages/xrpl/src/models/transactions/trustSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ export enum TrustSetFlags {
tfSetFreeze = 0x00100000,
/** Unfreeze the trust line. */
tfClearFreeze = 0x00200000,
/** Deep-Freeze the trustline -- disallow sending and receiving the said IssuedCurrency */
/** Allowed only if the trustline is already regularly frozen, or if tfSetFreeze is set in the same transaction. */
tfSetDeepFreeze = 0x00400000,
ckeshava marked this conversation as resolved.
Show resolved Hide resolved
/** Clear a Deep-Frozen trustline */
tfClearDeepFreeze = 0x00800000,
}

/**
Expand Down Expand Up @@ -89,6 +94,11 @@ export interface TrustSetFlagsInterface extends GlobalFlags {
tfSetFreeze?: boolean
/** Unfreeze the trust line. */
tfClearFreeze?: boolean
/** Deep-Freeze the trustline -- disallow sending and receiving the said IssuedCurrency */
/** Allowed only if the trustline is already regularly frozen, or if tfSetFreeze is set in the same transaction. */
tfSetDeepFreeze?: boolean
ckeshava marked this conversation as resolved.
Show resolved Hide resolved
/** Clear a Deep-Frozen trust line */
tfClearDeepFreeze?: boolean
Comment on lines +99 to +101
Copy link
Collaborator

Choose a reason for hiding this comment

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

could also possibly add a validation check that tfSetDeepFreeze and tfClearDeepFreeze should not be set in the same transaction? And possibly add a unit test for this.

unrelated to this PR, but a similar validation can be added for tfSetFreeze and tfClearFreeze to make sure they aren't set at the same time (and a unit test).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmm, in the worst case, erring users will be greeted with a temINVALID_FLAG error here: https://github.com/XRPLF/rippled/blob/1b75dc8bcd536ff09a4d96064725c016e0df7293/src/xrpld/app/tx/detail/SetTrust.cpp#L42 (Users do not lose any transaction fees)

I have elaborated here as well: #2873 (comment)

We will need to replicate the tfTrustSetMask variable to do a complete validation. It feels a bit of an overkill.

}

/**
Expand Down
68 changes: 64 additions & 4 deletions packages/xrpl/test/integration/transactions/offerCreate.test.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
import { assert } from 'chai'

import { OfferCreate } from '../../../src'
import { OfferCreate, TrustSet, Wallet } from '../../../src'
import serverUrl from '../serverUrl'
import {
setupClient,
teardownClient,
type XrplIntegrationTestContext,
} from '../setup'
import { testTransaction } from '../utils'
import {
testTransaction,
generateFundedWallet,
submitTransaction,
} from '../utils'

// how long before each test case times out
const TIMEOUT = 20000

describe('OfferCreate', function () {
let testContext: XrplIntegrationTestContext
let wallet_deep_freeze_trustline: Wallet | undefined

beforeEach(async () => {
beforeAll(async () => {
testContext = await setupClient(serverUrl)
if (!wallet_deep_freeze_trustline) {
// eslint-disable-next-line require-atomic-updates -- race condition doesn't really matter
wallet_deep_freeze_trustline = await generateFundedWallet(
testContext.client,
)
}
})
afterEach(async () => teardownClient(testContext))

afterAll(async () => teardownClient(testContext))

it(
'base',
Expand Down Expand Up @@ -49,4 +61,52 @@ describe('OfferCreate', function () {
},
TIMEOUT,
)

it(
'OfferCreate with Deep-Frozen trustline must fail',
async () => {
assert(wallet_deep_freeze_trustline != null)

// deep-freeze the trust line
const trust_set_tx: TrustSet = {
TransactionType: 'TrustSet',
Account: testContext.wallet.classicAddress,
LimitAmount: {
currency: 'USD',
issuer: wallet_deep_freeze_trustline.classicAddress,
value: '10',
},
Flags: {
tfSetFreeze: true,
tfSetDeepFreeze: true,
},
}

await testTransaction(
testContext.client,
trust_set_tx,
testContext.wallet,
)

const offer_create_tx: OfferCreate = {
TransactionType: 'OfferCreate',
Account: testContext.wallet.classicAddress,
TakerGets: '13100000',
TakerPays: {
currency: 'USD',
issuer: wallet_deep_freeze_trustline.classicAddress,
value: '10',
},
}

const response = await submitTransaction({
client: testContext.client,
transaction: offer_create_tx,
wallet: testContext.wallet,
})

assert.equal(response.result.engine_result, 'tecFROZEN')
},
TIMEOUT,
)
})
49 changes: 47 additions & 2 deletions packages/xrpl/test/integration/transactions/trustSet.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { assert } from 'chai'

import { TrustSet, percentToQuality, Wallet } from '../../../src'
import { TrustSet, percentToQuality, Wallet, TrustSetFlags } from '../../../src'
import serverUrl from '../serverUrl'
import {
setupClient,
teardownClient,
type XrplIntegrationTestContext,
} from '../setup'
import { generateFundedWallet, testTransaction } from '../utils'

import RippleState from '../../../src/models/ledger/RippleState'
// how long before each test case times out
const TIMEOUT = 20000

Expand Down Expand Up @@ -85,4 +85,49 @@ describe('TrustSet', function () {
},
TIMEOUT,
)

it(
'Create a Deep-Frozen trustline',
async () => {
assert(wallet2 != null)
// deep-freeze a trustline with the specified counter-party/currency-code
const tx: TrustSet = {
TransactionType: 'TrustSet',
Account: testContext.wallet.classicAddress,
LimitAmount: {
currency: 'USD',
issuer: wallet2.classicAddress,
value: '10',
},
Flags: {
tfSetFreeze: true,
tfSetDeepFreeze: true,
},
}

const response = await testTransaction(
testContext.client,
tx,
testContext.wallet,
)
assert.equal(response.result.engine_result, 'tesSUCCESS')

// assert that the trustline is frozen
const trustLine = await testContext.client.request({
command: 'account_lines',
account: testContext.wallet.classicAddress,
})
assert.equal(trustLine.result.lines[0].freeze, true)

// verify that the trust-line is deep-frozen
// this operation cannot be done with the account_lines RPC
const account_objects = await testContext.client.request({
command: 'account_objects',
account: testContext.wallet.classicAddress,
})
assert.isTrue(((account_objects.result.account_objects[0] as RippleState).Flags & TrustSetFlags.tfSetDeepFreeze) != 0)

},
ckeshava marked this conversation as resolved.
Show resolved Hide resolved
TIMEOUT,
)
})
5 changes: 5 additions & 0 deletions packages/xrpl/test/models/trustSet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ describe('TrustSet', function () {
},
QualityIn: 1234,
QualityOut: 4321,
// an example of deep-frozen trustline
Flags: {
tfSetFreeze: true,
tfSetDeepFreeze: true,
},
} as any
})

Expand Down
Loading