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

feat(jellyfish-api-core): Add account getPendingFutureSwaps RPC for dfip2203 futures #1321

Merged
merged 22 commits into from
Apr 9, 2022
Merged
Show file tree
Hide file tree
Changes from 10 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
20 changes: 20 additions & 0 deletions docs/node/CATEGORIES/08-account.md
Original file line number Diff line number Diff line change
Expand Up @@ -466,3 +466,23 @@ interface BurnInfo {
paybacktokens: string[]
}
```

## getPendingFutureSwaps

Get specific pending futures.

```ts title="client.account.getPendingFutureSwaps()"
interface account {
getPendingFutureSwaps (address: string): Promise<GetFutureInfo>
}

interface GetFutureInfo {
owner: string
values: FutureData[]
}

interface FutureData {
source: string
destination: string
}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,333 @@
import { MasterNodeRegTestContainer } from '@defichain/testcontainers'
import BigNumber from 'bignumber.js'
import { Testing } from '@defichain/jellyfish-testing'
import { RegTestFoundationKeys } from '@defichain/jellyfish-network'

describe('Account GetPendingFutureSwaps', () => {
const container = new MasterNodeRegTestContainer()
const testing = Testing.create(container)

const collateralAddress = RegTestFoundationKeys[0].owner.address
const futureRewardPercentage = 0.05
const futureInterval = 25

let tslaAddress: string

async function setup (): Promise<void> {
const oracleId = await testing.rpc.oracle.appointOracle(await testing.generateAddress(), [
{
currency: 'USD',
token: 'TSLA'
}
],
{ weightage: 1 }
)
await testing.generate(1)

await testing.rpc.oracle.setOracleData(oracleId, Math.floor(new Date().getTime() / 1000), {
prices: [
{
currency: 'USD',
tokenAmount: '2@TSLA'
}
]
})
await testing.generate(1)

await testing.rpc.loan.setLoanToken({
symbol: 'DUSD',
name: 'DUSD',
fixedIntervalPriceId: 'DUSD/USD',
mintable: true,
interest: new BigNumber(0)
})
await testing.generate(1)

await testing.rpc.loan.setLoanToken({
symbol: 'TSLA',
name: 'TSLA',
fixedIntervalPriceId: 'TSLA/USD',
mintable: true,
interest: new BigNumber(1)
})
await testing.generate(1)

await testing.token.mint({
symbol: 'DUSD',
amount: 4
})
await testing.generate(1)

await testing.token.mint({
symbol: 'TSLA',
amount: 4
})
await testing.generate(1)
jingyi2811 marked this conversation as resolved.
Show resolved Hide resolved

await testing.rpc.masternode.setGov({ ATTRIBUTES: { 'v0/params/dfip2203/active': 'false' } })
await testing.generate(1)

await testing.rpc.masternode.setGov({ ATTRIBUTES: { 'v0/params/dfip2203/reward_pct': futureRewardPercentage.toString(), 'v0/params/dfip2203/block_period': futureInterval.toString() } })
await testing.generate(1)

await testing.rpc.masternode.setGov({ ATTRIBUTES: { 'v0/params/dfip2203/active': 'true' } })
await testing.generate(1)

tslaAddress = await testing.generateAddress()

await testing.rpc.account.accountToAccount(collateralAddress, {
[tslaAddress]: '4@DUSD'
})
await testing.generate(1)

await testing.rpc.account.accountToAccount(collateralAddress, {
[tslaAddress]: '4@TSLA'
})
await testing.generate(1)
}

async function getNextSettleBlock (): Promise<number> {
const blockCount = await testing.rpc.blockchain.getBlockCount()
return blockCount + futureInterval - (blockCount % futureInterval)
}

beforeAll(async () => {
await testing.container.start()
await testing.container.waitForWalletCoinbaseMaturity()
await setup()
})

afterAll(async () => {
await testing.container.stop()
})

describe('Single futureswap', () => {
it('Should getPendingFutureSwaps if futureswap TSLA for DUSD', async () => {
// Call getpendingfutureswaps before performing futureswap
{
const pendingFutureSwaps = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps).toStrictEqual({
owner: tslaAddress,
values: []
})
}

// futureswap
await testing.container.call('futureswap', [tslaAddress, '1@TSLA'])
await testing.generate(1)

// Call getpendingfutureswaps after performing futureswap
const pendingFutureSwaps1 = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps1).toStrictEqual({
owner: tslaAddress,
values: [
{
source: '1.00000000@TSLA',
destination: 'DUSD'
}
]
})

// Wait for 1 block before the next settle block
const nextSettleBlock = await getNextSettleBlock()
await testing.generate(nextSettleBlock - await testing.rpc.blockchain.getBlockCount() - 1)

const pendingFutureSwaps2 = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps2).toStrictEqual(pendingFutureSwaps1) // Nothing change

// Generate 1 more block to settle
await testing.generate(1)

// Call getpendingfutureswaps after futureswap is settled
{
const pendingFutureSwaps = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps).toStrictEqual({
owner: tslaAddress,
values: []
})
}
})

it('Should getPendingFutureSwaps if futureswap DUSD for TSLA', async () => {
// Call getpendingfutureswaps before performing futureswap
Copy link
Contributor Author

@jingyi2811 jingyi2811 Apr 6, 2022

Choose a reason for hiding this comment

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

It looks redundant as Line 142 does the same thing.
However, I believe every code in every Jest Item (It) should be independent.

{
const pendingFutureSwaps = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps).toStrictEqual({
owner: tslaAddress,
values: []
})
}

// futureswap
await testing.container.call('futureswap', [tslaAddress, '1@DUSD', 'TSLA'])
await testing.generate(1)

// Call getpendingfutureswaps after performing futureswap
const pendingFutureSwaps1 = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps1).toStrictEqual({
owner: tslaAddress,
values: [
{
source: '1.00000000@DUSD',
destination: 'TSLA'
}
]
})

// Wait for 1 block before the next settle block
const nextSettleBlock = await getNextSettleBlock()
await testing.generate(nextSettleBlock - await testing.rpc.blockchain.getBlockCount() - 1)

const pendingFutureSwaps2 = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps2).toStrictEqual(pendingFutureSwaps1) // Nothing change

// Generate 1 more block to settle
await testing.generate(1)

// Call getpendingfutureswaps after futureswap is settled
{
const pendingFutureSwaps = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps).toStrictEqual({
owner: tslaAddress,
values: []
})
}
})
})

describe('Multiple futureswaps', () => {
it('Should getPendingFutureSwaps if futureswap TSLA for DUSD', async () => {
// Call getpendingfutureswaps before performing futureswap
{
const pendingFutureSwaps = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps).toStrictEqual({
owner: tslaAddress,
values: []
})
}

// futureswap 4 times
await testing.container.call('futureswap', [tslaAddress, '0.7@TSLA'])
await testing.generate(1)

await testing.container.call('futureswap', [tslaAddress, '0.6@TSLA'])
await testing.generate(1)

await testing.container.call('futureswap', [tslaAddress, '0.5@TSLA'])
await testing.generate(1)

await testing.container.call('futureswap', [tslaAddress, '0.2@TSLA'])
await testing.generate(1)
jingyi2811 marked this conversation as resolved.
Show resolved Hide resolved

// Call getpendingfutureswaps after performing futureswap
const pendingFutureSwaps1 = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps1).toStrictEqual({
owner: tslaAddress,
values: [
{
source: '0.20000000@TSLA',
destination: 'DUSD'
},
{
source: '0.50000000@TSLA',
destination: 'DUSD'
},
{
source: '0.60000000@TSLA',
destination: 'DUSD'
},
{
source: '0.70000000@TSLA',
destination: 'DUSD'
}
]
})

// Wait for 1 block before the next settle block
const nextSettleBlock = await getNextSettleBlock()
await testing.generate(nextSettleBlock - await testing.rpc.blockchain.getBlockCount() - 1)

const pendingFutureSwaps2 = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps2).toStrictEqual(pendingFutureSwaps1) // Nothing change

// Generate 1 more block to settle
await testing.generate(1)

// Call getpendingfutureswaps after futureswap is settled
{
const pendingFutureSwaps = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps).toStrictEqual({
owner: tslaAddress,
values: []
})
}
})

it('Should getPendingFutureSwaps if futureswap DUSD for TSLA', async () => {
// Call getpendingfutureswaps before performing futureswap
{
const pendingFutureSwaps = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps).toStrictEqual({
owner: tslaAddress,
values: []
})
}

// futureswap 4 times
await testing.container.call('futureswap', [tslaAddress, '0.8@DUSD', 'TSLA'])
await testing.generate(1)

await testing.container.call('futureswap', [tslaAddress, '0.6@DUSD', 'TSLA'])
await testing.generate(1)

await testing.container.call('futureswap', [tslaAddress, '0.4@DUSD', 'TSLA'])
await testing.generate(1)

await testing.container.call('futureswap', [tslaAddress, '0.2@DUSD', 'TSLA'])
await testing.generate(1)

// Call getpendingfutureswaps after performing futureswap
const pendingFutureSwaps1 = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps1).toStrictEqual({
owner: tslaAddress,
values: [
{
source: '0.20000000@DUSD',
destination: 'TSLA'
},
{
source: '0.40000000@DUSD',
destination: 'TSLA'
},
{
source: '0.60000000@DUSD',
destination: 'TSLA'
},
{
source: '0.80000000@DUSD',
destination: 'TSLA'
}
]
})

// Wait for 1 block before the next settle block
const nextSettleBlock = await getNextSettleBlock()
await testing.generate(nextSettleBlock - await testing.rpc.blockchain.getBlockCount() - 1)

const pendingFutureSwaps2 = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps2).toStrictEqual(pendingFutureSwaps1) // Nothing change

// Generate 1 more block to settle
await testing.generate(1)

// Call getpendingfutureswaps after futureswap is settled
{
const pendingFutureSwaps = await testing.rpc.account.getPendingFutureSwaps(tslaAddress)
expect(pendingFutureSwaps).toStrictEqual({
owner: tslaAddress,
values: []
})
}
})
})
})
19 changes: 19 additions & 0 deletions packages/jellyfish-api-core/src/category/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,15 @@ export class Account {
async getBurnInfo (): Promise<BurnInfo> {
return await this.client.call('getburninfo', [], 'bignumber')
}

/**
* Get specific pending futures.
*
* @return {Promise<GetFutureInfo>}
*/
async getPendingFutureSwaps (address: string): Promise<GetFutureInfo> {
return await this.client.call('getpendingfutureswaps', [address], 'number')
}
}

export interface AccountPagination {
Expand Down Expand Up @@ -552,3 +561,13 @@ export interface BurnInfo {
*/
paybacktokens: string[]
}

export interface GetFutureInfo {
owner: string
values: FutureData[]
}

export interface FutureData {
source: string
jingyi2811 marked this conversation as resolved.
Show resolved Hide resolved
destination: string
}
2 changes: 1 addition & 1 deletion packages/testcontainers/src/containers/DeFiDContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export abstract class DeFiDContainer extends DockerContainer {
if (process?.env?.DEFICHAIN_DOCKER_IMAGE !== undefined) {
return process.env.DEFICHAIN_DOCKER_IMAGE
}
return 'defi/defichain:master-2a236bb79'
return 'defi/defichain:master-57c099c1a'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should be the latest docker, if not reviewer please change this for me.

}

public static readonly DefaultStartOptions = {
Expand Down