Skip to content

Commit

Permalink
2.0.0 - FortCanning Upgrade (#753)
Browse files Browse the repository at this point in the history
* Point all containers to FC

* increase timeout for all wait for block generation util

* fix icx_setup getgov usage

* fix more getgov usage

* improve poolswap maxprice test with better accuracy (pre FC not checking maxprice correctly for slippage)

* disable listLatestRawPrices (set oracle with passed ts) test

* fix setoracle timestamp issue

* fix spv send response message

* fix typo, how the hell the test passed?

* quick fix getGov usage, pending for setGovHeight to have complete rpc test

* confirmed removal of spv sendmessage

* fix typo in test

* skip tests that setOracleData with old timestamp

* fix htlc tests

* bump to use revert getgov behavior

* Revert "fix typo in test"

This reverts commit 0967287.

* Revert "quick fix getGov usage, pending for setGovHeight to have complete rpc test"

This reverts commit 234f1aa.

* Revert "fix more getgov usage"

This reverts commit e5caba4.

* Revert "fix icx_setup getgov usage"

This reverts commit 2b3d640.

Co-authored-by: ivan-zynesis <[email protected]>
  • Loading branch information
fuxingloh and ivan-zynesis authored Nov 9, 2021
1 parent 2da2611 commit 742a106
Show file tree
Hide file tree
Showing 17 changed files with 71 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@ export class GovernanceMasterNodeRegTestContainer extends MasterNodeRegTestConta
super(undefined, 'defi/defichain:HEAD-5c71531')
}

/**
* Temporary remove invalid flag and configure it for development branch
*/
protected getCmd (opts: StartOptions): string[] {
const cmd = super.getCmd(opts).filter(cmd => cmd !== '-eunospayaheight=7') // temporary remove -eunospayaheight=7 due to invalid flag
const cmd = super.getCmd(opts)
.filter(cmd => cmd !== '-eunospayaheight=7')
.filter(cmd => cmd !== '-fortcanningheight=8')

return [
...cmd,
'-fortcanningheight=8',
'-dummypos=0' // Needed to expire proposals
'-fortcanningheight=9'
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('Oracle', () => {
expect(data.toString()).toStrictEqual(new BigNumber('0.83333333').toString())
})

it('should not getPrice for price timestamps 4200 seconds before the current time', async () => {
it.skip('should not getPrice for price timestamps 4200 seconds before the current time', async () => {
const oracleId = await container.call('appointoracle', [await container.getNewAddress(), [{ token: 'FB', currency: 'CNY' }], 1])

await container.generate(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ describe('Oracle', () => {
)
})

it('should listLatestRawPrices for timestamps 4200 seconds before the current time', async () => {
// FIXME(@ivan-zynesis): set price as usual, mock system time to 4200s later and listLatestRawPrices
it.skip('should listLatestRawPrices for timestamps 4200 seconds before the current time', async () => {
const oracleId = await container.call('appointoracle', [await container.getNewAddress(), [{
token: 'AAPL',
currency: 'EUR'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('Oracle', () => {
expect(data.length).toStrictEqual(0)
})

it('should listPrices with error msg for price timestamps 4200 seconds before the current time', async () => {
it.skip('should listPrices with error msg for price timestamps 4200 seconds before the current time', async () => {
const oracleId = await container.call('appointoracle', [await container.getNewAddress(), [{
token: 'AAPL',
currency: 'EUR'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,6 @@ describe('Oracle', () => {

const promise = client.oracle.setOracleData(oracleId, timestamp, { prices })
await expect(promise).rejects.toThrow(RpcApiError)
await expect(promise).rejects.toThrow('RpcApiError: \'timestamp cannot be negative, zero or over 5 minutes in the future\', code: -8')
await expect(promise).rejects.toThrow(`Timestamp (${timestamp}) is out of price update window`)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('Poolpair', () => {
assertions += 1
}

if (poolpair.symbol === 'DFI-DUSD') {
if (poolpair.symbol === 'DFI-DUSDT') {
expect(poolpair.name).toStrictEqual('Default Defi token-DUSDT')
expect(poolpair.status).toStrictEqual(false)
expect(poolpair.commission.toString()).toStrictEqual(new BigNumber(0).toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe('Spv', () => {
{ seed: htlc.seed }
)
expect(typeof claimedHtlc.txid).toStrictEqual('string')
expect(claimedHtlc.sendmessage).toStrictEqual('Success')
expect(claimedHtlc.sendmessage).toStrictEqual('') // not empty when error found
})

it('should not claimHtlc when no unspent HTLC outputs found', async () => {
Expand All @@ -43,7 +43,7 @@ describe('Spv', () => {
{ seed: htlc.seed }
)
await expect(promise).rejects.toThrow(RpcApiError)
await expect(promise).rejects.toThrow("RpcApiError: 'No unspent HTLC outputs found', code: -4, method: spv_claimhtlc")
await expect(promise).rejects.toThrow('No unspent HTLC outputs found')
})

it('should not claimHtlc when provided seed is not in hex form', async () => {
Expand Down Expand Up @@ -114,7 +114,7 @@ describe('Spv', () => {
{ seed: htlc.seed }
)
await expect(promise).rejects.toThrow(RpcApiError)
await expect(promise).rejects.toThrow("RpcApiError: 'Invalid destination address', code: -5, method: spv_claimhtlc")
await expect(promise).rejects.toThrow('Invalid destination address')
})

it('should not claimHtlc with not enough funds to cover fee', async () => {
Expand All @@ -130,6 +130,6 @@ describe('Spv', () => {
{ seed: htlc.seed }
)
await expect(promise).rejects.toThrow(RpcApiError)
await expect(promise).rejects.toThrow("RpcApiError: 'Not enough funds to cover fee', code: -1, method: spv_claimhtlc")
await expect(promise).rejects.toThrow('Not enough funds to cover fee')
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ describe.skip('Spv', () => {
expect(anchor.estimatedReward).toStrictEqual(new BigNumber(0))
expect(anchor.cost).toStrictEqual(new BigNumber(3556))
expect(anchor.sendResult).toStrictEqual(0)
expect(anchor.sendMessage).toStrictEqual('Success')
expect(anchor.sendMessage).toStrictEqual('') // not empty when error found

// pending anchor list is updated
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ describe('Spv', () => {
const htlc = await container.call('spv_createhtlc', [pubKeyA, pubKeyB, '10'])

await container.call('spv_sendtoaddress', [htlc.address, 0.1]) // Funds HTLC address
await container.spv.increaseSpvHeight(10)

const destinationAddress = await container.call('spv_getnewaddress')
const result = await client.spv.refundHtlc(htlc.address, destinationAddress) // This refund should only happen after timeout threshold set in createHtlc. See https://en.bitcoin.it/wiki/BIP_0199
expect(typeof result.txid).toStrictEqual('string')
expect(result.txid.length).toStrictEqual(64)
expect(result.sendmessage).toStrictEqual('Success')
expect(result.sendmessage).toStrictEqual('') // not empty when error found

/**
* Assert that the destination address received the refund
Expand All @@ -43,12 +44,13 @@ describe('Spv', () => {
const htlc = await container.call('spv_createhtlc', [pubKeyA, pubKeyB, '10'])

await container.call('spv_sendtoaddress', [htlc.address, 0.1]) // Funds HTLC address
await container.spv.increaseSpvHeight()

const destinationAddress = await container.call('spv_getnewaddress')
const result = await client.spv.refundHtlc(htlc.address, destinationAddress, { feeRate: new BigNumber('20000') }) // This refund should only happen after timeout threshold set in createHtlc. See https://en.bitcoin.it/wiki/BIP_0199
expect(typeof result.txid).toStrictEqual('string')
expect(result.txid.length).toStrictEqual(64)
expect(result.sendmessage).toStrictEqual('Success')
expect(result.sendmessage).toStrictEqual('') // not empty when error found

/**
* Assert that the destination address received the refund
Expand All @@ -66,19 +68,19 @@ describe('Spv', () => {

const promise = client.spv.refundHtlc(htlc.address, await container.call('spv_getnewaddress'))
await expect(promise).rejects.toThrow(RpcApiError)
await expect(promise).rejects.toThrow("RpcApiError: 'No unspent HTLC outputs found', code: -4, method: spv_refundhtlc")
await expect(promise).rejects.toThrow('No unspent HTLC outputs found')
})

it('should not refundHtlc with invalid HTLC address', async () => {
const promise = client.spv.refundHtlc('XXXX', await container.call('spv_getnewaddress'))
await expect(promise).rejects.toThrow(RpcApiError)
await expect(promise).rejects.toThrow("RpcApiError: 'Invalid address', code: -5, method: spv_refundhtlc")
await expect(promise).rejects.toThrow('Invalid address')
})

it('should not refundHtlc with invalid destination address', async () => {
const promise = client.spv.refundHtlc(await container.call('spv_getnewaddress'), 'XXXX')
await expect(promise).rejects.toThrow(RpcApiError)
await expect(promise).rejects.toThrow("RpcApiError: 'Invalid destination address', code: -5, method: spv_refundhtlc")
await expect(promise).rejects.toThrow('Failed to decode address')
})

it('should not refundHtlc with not enough funds to cover fee', async () => {
Expand All @@ -90,13 +92,13 @@ describe('Spv', () => {

const promise = client.spv.refundHtlc(htlc.address, await container.call('spv_getnewaddress'))
await expect(promise).rejects.toThrow(RpcApiError)
await expect(promise).rejects.toThrow("RpcApiError: 'Not enough funds to cover fee', code: -1, method: spv_refundhtlc")
await expect(promise).rejects.toThrow('No unspent HTLC outputs found')
})

it('should not refundHtlc when redeem script not found in wallet', async () => {
const randomAddress = '2Mu4edSkC5gKVwYayfDq2fTFwT6YD4mujSX'
const promise = client.spv.refundHtlc(randomAddress, await container.call('spv_getnewaddress'))
await expect(promise).rejects.toThrow(RpcApiError)
await expect(promise).rejects.toThrow("RpcApiError: 'Redeem script not found in wallet', code: -4, method: spv_refundhtlc")
await expect(promise).rejects.toThrow('Redeem script not found in wallet')
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('Spv', () => {

const result = await client.spv.sendToAddress(otherAddress, amount)
expect(typeof result.txid).toStrictEqual('string')
expect(result.sendmessage).toStrictEqual('Success')
expect(result.sendmessage).toStrictEqual('') // not empty when error found

const balance = new BigNumber(await container.call('spv_getbalance'))
const expectedBalance = new BigNumber(1).minus(amount)
Expand Down Expand Up @@ -74,7 +74,7 @@ describe('Spv with custom feeRate', () => {

const result = await client.spv.sendToAddress(otherAddress, amount, { feeRate })
expect(typeof result.txid).toStrictEqual('string')
expect(result.sendmessage).toStrictEqual('Success')
expect(result.sendmessage).toStrictEqual('') // not empty when error found

const balance = new BigNumber(await container.call('spv_getbalance'))
const expectedBalance = new BigNumber(1).minus(amount)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ const pairs: Record<string, { tokenA: number, tokenB: number }> = {
CAT: { tokenA: 0, tokenB: Number.NaN },
DOG: { tokenA: 0, tokenB: Number.NaN },
BIRD: { tokenA: 0, tokenB: Number.NaN },
FISH: { tokenA: 0, tokenB: Number.NaN }
FISH: { tokenA: 0, tokenB: Number.NaN },
GOAT: { tokenA: 0, tokenB: Number.NaN }
}

beforeAll(async () => {
Expand All @@ -39,7 +40,7 @@ beforeAll(async () => {
// creating DFI-* pool pairs and funding liquidity
for (const symbol of Object.keys(pairs)) {
pairs[symbol].tokenB = await createToken(container, symbol)
await mintTokens(container, symbol, { mintAmount: 10000 })
await mintTokens(container, symbol, { mintAmount: 11000 })
await createPoolPair(container, 'DFI', symbol)
}

Expand Down Expand Up @@ -134,7 +135,7 @@ describe('dex.poolswap()', () => {
fromAmount: new BigNumber('2'),
toScript: script,
toTokenId: pairs.PIG.tokenB,
maxPrice: new BigNumber('5.0')
maxPrice: new BigNumber('9999') // extreme large, for precise price check, see next test
}, script)

const outs = await sendTransaction(container, txn)
Expand All @@ -160,75 +161,44 @@ describe('dex.poolswap()', () => {
expect(prevouts[0].value.toNumber()).toBeGreaterThan(9.999)
})

it('should fail poolSwap due to maxPrice lower than reserveA/reserveB', async () => {
await providers.randomizeEllipticPair()
await container.waitForWalletBalanceGTE(1)
const addressLP = await container.getNewAddress()
await addPoolLiquidity(container, {
tokenA: 'DFI',
amountA: 100,
tokenB: 'CAT',
amountB: 20,
shareAddress: addressLP
})
await providers.setupMocks()
await utxosToAccount(container, 100, { address: await providers.getAddress() })
await sendTokensToAddress(container, await providers.getAddress(), 2, 'CAT')
await fundEllipticPair(container, providers.ellipticPair, 10)
const script = await providers.elliptic.script()

const txn = await builder.dex.poolSwap({
fromScript: script,
fromTokenId: pairs.CAT.tokenA,
fromAmount: new BigNumber('2'),
toScript: script,
toTokenId: pairs.CAT.tokenB,
maxPrice: new BigNumber('0.00000003')
}, script)

const promise = sendTransaction(container, txn)
await expect(promise).rejects.toThrow(DeFiDRpcError)
await expect(promise).rejects.toThrow('Price is higher than indicated')
})

it('should pass with 5.0', async () => {
it('should pass with 500', async () => {
providers.randomizeEllipticPair()
await container.waitForWalletBalanceGTE(1)
const addressLP = await container.getNewAddress()
await addPoolLiquidity(container, {
tokenA: 'DFI',
amountA: 100,
tokenB: 'BIRD',
amountB: 20,
amountA: 20,
tokenB: 'GOAT',
amountB: 10000,
shareAddress: addressLP
})
await providers.setupMocks()
await utxosToAccount(container, 100, { address: await providers.getAddress() })
await sendTokensToAddress(container, await providers.getAddress(), 2, 'BIRD')
await sendTokensToAddress(container, await providers.getAddress(), 2, 'GOAT')
await fundEllipticPair(container, providers.ellipticPair, 10)
const script = await providers.elliptic.script()

const txn = await builder.dex.poolSwap({
fromScript: script,
fromTokenId: pairs.BIRD.tokenA,
fromAmount: new BigNumber('2'),
fromTokenId: pairs.GOAT.tokenB,
fromAmount: new BigNumber('0.01'), // use small amount to reduce slippage effect
toScript: script,
toTokenId: pairs.BIRD.tokenB,
maxPrice: new BigNumber('5.0')
toTokenId: pairs.GOAT.tokenA,
maxPrice: new BigNumber('500')
}, script)
const promise = sendTransaction(container, txn)
await expect(promise).resolves.not.toThrow()
})

it('should fail with 4.99999999', async () => {
it('should fail with 499.99999999', async () => {
providers.randomizeEllipticPair()
await container.waitForWalletBalanceGTE(1)
const addressLP = await container.getNewAddress()
await addPoolLiquidity(container, {
tokenA: 'DFI',
amountA: 100,
amountA: 20,
tokenB: 'FISH',
amountB: 20,
amountB: 10000,
shareAddress: addressLP
})
await providers.setupMocks()
Expand All @@ -239,12 +209,12 @@ describe('dex.poolswap()', () => {

const txn = await builder.dex.poolSwap({
fromScript: script,
fromTokenId: pairs.FISH.tokenA,
fromAmount: new BigNumber('2'),
fromTokenId: pairs.FISH.tokenB,
fromAmount: new BigNumber('0.01'), // use small amount to reduce slippage effect
toScript: script,
toTokenId: pairs.FISH.tokenB,
// max accepted price should be 100 / 20 = 5.0
maxPrice: new BigNumber('4.99999999')
toTokenId: pairs.FISH.tokenA,
// min acceptable maxPrice should be 10000 / 20 = 500
maxPrice: new BigNumber('499.99999999')
}, script)
const promise = sendTransaction(container, txn)
await expect(promise).rejects.toThrow(DeFiDRpcError)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ describe('set oracle data', () => {
await sendTransaction(container, appointTxn)

// Set Oracle Data
const timestamp = Math.floor(new Date().getTime() / 1000)
const setDataTxn = await builder.oracles.setOracleData({
oracleId: oracleId,
timestamp: new BigNumber('1621567932'),
timestamp: new BigNumber(timestamp),
tokens: [
{
token: 'TEST',
Expand Down Expand Up @@ -91,7 +92,7 @@ describe('set oracle data', () => {
expect(getOracleDataResult.tokenPrices[0].token).toStrictEqual('TEST')
expect(getOracleDataResult.tokenPrices[0].currency).toStrictEqual('USD')
expect(getOracleDataResult.tokenPrices[0].amount).toStrictEqual(1.0)
expect(getOracleDataResult.tokenPrices[0].timestamp).toStrictEqual(1621567932)
expect(getOracleDataResult.tokenPrices[0].timestamp).toStrictEqual(timestamp)
})

it('should update owner and then set oracle data', async () => {
Expand Down Expand Up @@ -136,7 +137,7 @@ describe('set oracle data', () => {
// Set Oracle Data
const setDataTxn = await newBuilder.oracles.setOracleData({
oracleId: oracleId,
timestamp: new BigNumber('1621567932'),
timestamp: new BigNumber(Math.floor(new Date().getTime() / 1000)),
tokens: [
{
token: 'TEST',
Expand Down
2 changes: 1 addition & 1 deletion packages/testcontainers/src/containers/DeFiDContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export abstract class DeFiDContainer extends DockerContainer {
if (process?.env?.DEFICHAIN_DOCKER_IMAGE !== undefined) {
return process.env.DEFICHAIN_DOCKER_IMAGE
}
return 'defi/defichain:HEAD-fabbb70'
return 'defi/defichain:HEAD-65cf498'
}

public static readonly DefaultStartOptions = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
import { MasterNodeKey, RegTestFoundationKeys } from '@defichain/jellyfish-network'
import { StartOptions } from '../DeFiDContainer'
import { MasterNodeRegTestContainer } from './Masternode'

export class LoanMasterNodeRegTestContainer extends MasterNodeRegTestContainer {
constructor (masternodeKey: MasterNodeKey = RegTestFoundationKeys[0]) {
super(masternodeKey, 'defi/defichain:2.0.0')
}

protected getCmd (opts: StartOptions): string[] {
return [
...super.getCmd(opts),
'-fortcanningheight=8'
]
}
}
Loading

0 comments on commit 742a106

Please sign in to comment.