From b4df405030947eccade9ba58b39b7ae7db49d8e8 Mon Sep 17 00:00:00 2001 From: Mark Tan Date: Tue, 1 Nov 2022 12:42:17 +0800 Subject: [PATCH 01/64] Add updateMasternode rpc (WIP) --- docs/node/CATEGORIES/11-masternode.md | 17 ++++++ .../masternode/updatemasternode.test.ts | 57 +++++++++++++++++++ .../src/category/masternode.ts | 24 ++++++++ 3 files changed, 98 insertions(+) create mode 100644 packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts diff --git a/docs/node/CATEGORIES/11-masternode.md b/docs/node/CATEGORIES/11-masternode.md index feda9551a0..857d8c4f6f 100644 --- a/docs/node/CATEGORIES/11-masternode.md +++ b/docs/node/CATEGORIES/11-masternode.md @@ -172,6 +172,23 @@ interface UTXO { } ``` +## updatemasternode + +Creates (and submits to local node and network) a masternode update transaction which update the masternode operator addresses, spending the given inputs.. +The last optional argument (may be empty array) is an array of specific UTXOs to spend. + +```ts title="client.masternode.updatemasternode()" +interface masternode { + updateMasternode(masternodeId: string, values: UpdateMasternodeValues, utxos: UTXO[] = []): Promise +} + +interface UpdateMasternodeValues { + ownerAddress?: string + operatorAddress?: string + rewardAddress?: string +} +``` + ## setGov Set special governance variables diff --git a/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts b/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts new file mode 100644 index 0000000000..87e8bfd19e --- /dev/null +++ b/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts @@ -0,0 +1,57 @@ +import { MasterNodeRegTestContainer } from '@defichain/testcontainers/dist/index' +import { ContainerAdapterClient } from '../../container_adapter_client' + +describe('Masternode', () => { + const container = new MasterNodeRegTestContainer() + const client = new ContainerAdapterClient(container) + + beforeAll(async () => { + await container.start() + await container.waitForWalletCoinbaseMaturity() + }) + + afterAll(async () => { + await container.stop() + }) + + it('should updateMasternode', async () => { + const ownerAddress1 = await container.getNewAddress() + const masternodeId = await client.masternode.createMasternode(ownerAddress1) + + await container.generate(20) + + const masternodesBefore = await client.masternode.listMasternodes() + const masternodesLengthBefore = Object.keys(masternodesBefore).length + + const ownerAddress2 = await container.getNewAddress() + await client.masternode.updateMasternode(masternodeId, { + ownerAddress: ownerAddress2 + }) + + await container.generate(60) + + const masternodesAfter = await client.masternode.listMasternodes() + const masternodesLengthAfter = Object.keys(masternodesAfter).length + expect(masternodesLengthAfter).toStrictEqual(masternodesLengthBefore) + + const mn = masternodesAfter[masternodeId] + if (mn === undefined) { + throw new Error('should not reach here') + } + + expect(mn).toStrictEqual({ + operatorAuthAddress: ownerAddress1, + ownerAuthAddress: ownerAddress2, + creationHeight: expect.any(Number), + resignHeight: expect.any(Number), + resignTx: expect.any(String), + collateralTx: expect.any(String), + rewardAddress: expect.any(String), + state: expect.any(String), + mintedBlocks: expect.any(Number), + ownerIsMine: expect.any(Boolean), + localMasternode: expect.any(Boolean), + operatorIsMine: expect.any(Boolean) + }) + }) +}) diff --git a/packages/jellyfish-api-core/src/category/masternode.ts b/packages/jellyfish-api-core/src/category/masternode.ts index b9bdd9d615..e9ea9812b8 100644 --- a/packages/jellyfish-api-core/src/category/masternode.ts +++ b/packages/jellyfish-api-core/src/category/masternode.ts @@ -144,6 +144,24 @@ export class Masternode { return await this.client.call('resignmasternode', [masternodeId, utxos], 'number') } + /** + * Creates (and submits to local node and network) a masternode update transaction which update the masternode operator addresses, spending the given inputs.. + * The last optional argument (may be empty array) is an array of specific UTXOs to spend. + * + * @param {string} masternodeId The masternode's id. + * @param {UpdateMasternodeValues} values + * @param {string} [values.ownerAddress] The new masternode owner address, requires masternode collateral fee (P2PKH or P2WPKH). + * @param {string} [values.operatorAddress] The new masternode operator address (P2PKH or P2WPKH). + * @param {string} [values.rewardAddress] Masternode`s new reward address, empty "" to remove reward address. + * @param {UTXO[]} [utxos = []] Array of specified utxos to spend. + * @param {string} [utxos.txid] The transaction id. + * @param {number} [utxos.vout] The output number. + * @return {Promise} Resignation Transaction. + */ + async updateMasternode (masternodeId: string, values: UpdateMasternodeValues, utxos: UTXO[] = []): Promise { + return await this.client.call('updatemasternode', [masternodeId, values, utxos], 'number') + } + /** * Set special governance variables * @@ -308,3 +326,9 @@ export interface AnchorTeamResult { export interface MasternodeResult { [id: string]: T } + +export interface UpdateMasternodeValues { + ownerAddress?: string + operatorAddress?: string + rewardAddress?: string +} From 80cee4a203079e78f80406c806f00684e688236c Mon Sep 17 00:00:00 2001 From: Mark Tan Date: Wed, 2 Nov 2022 14:43:42 +0800 Subject: [PATCH 02/64] Add test cases --- .../masternode/updatemasternode.test.ts | 118 +++++++++++++++++- .../src/containers/DeFiDContainer.ts | 2 +- .../src/containers/RegTestContainer/index.ts | 1 + 3 files changed, 115 insertions(+), 6 deletions(-) diff --git a/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts b/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts index 87e8bfd19e..c4105705a6 100644 --- a/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts @@ -1,5 +1,7 @@ import { MasterNodeRegTestContainer } from '@defichain/testcontainers/dist/index' import { ContainerAdapterClient } from '../../container_adapter_client' +import { AddressType } from '../../../src/category/wallet' +import { RpcApiError } from '@defichain/jellyfish-api-core' describe('Masternode', () => { const container = new MasterNodeRegTestContainer() @@ -14,8 +16,8 @@ describe('Masternode', () => { await container.stop() }) - it('should updateMasternode', async () => { - const ownerAddress1 = await container.getNewAddress() + it('should updateMasternode with bech32 address', async () => { + const ownerAddress1 = await client.wallet.getNewAddress() const masternodeId = await client.masternode.createMasternode(ownerAddress1) await container.generate(20) @@ -23,12 +25,12 @@ describe('Masternode', () => { const masternodesBefore = await client.masternode.listMasternodes() const masternodesLengthBefore = Object.keys(masternodesBefore).length - const ownerAddress2 = await container.getNewAddress() + const ownerAddress2 = await client.wallet.getNewAddress() await client.masternode.updateMasternode(masternodeId, { ownerAddress: ownerAddress2 }) - await container.generate(60) + await container.generate(70) const masternodesAfter = await client.masternode.listMasternodes() const masternodesLengthAfter = Object.keys(masternodesAfter).length @@ -51,7 +53,113 @@ describe('Masternode', () => { mintedBlocks: expect.any(Number), ownerIsMine: expect.any(Boolean), localMasternode: expect.any(Boolean), - operatorIsMine: expect.any(Boolean) + operatorIsMine: expect.any(Boolean), + targetMultipliers: expect.any(Object) }) }) + + it('should updateMasternode with legacy address', async () => { + const ownerAddress1 = await client.wallet.getNewAddress('', AddressType.LEGACY) + const masternodeId = await client.masternode.createMasternode(ownerAddress1) + + await container.generate(20) + + const masternodesBefore = await client.masternode.listMasternodes() + const masternodesLengthBefore = Object.keys(masternodesBefore).length + + const ownerAddress2 = await client.wallet.getNewAddress('', AddressType.LEGACY) + await client.masternode.updateMasternode(masternodeId, { + ownerAddress: ownerAddress2 + }) + + await container.generate(70) + + const masternodesAfter = await client.masternode.listMasternodes() + const masternodesLengthAfter = Object.keys(masternodesAfter).length + expect(masternodesLengthAfter).toStrictEqual(masternodesLengthBefore) + + const mn = masternodesAfter[masternodeId] + if (mn === undefined) { + throw new Error('should not reach here') + } + + expect(mn).toStrictEqual({ + operatorAuthAddress: ownerAddress1, + ownerAuthAddress: ownerAddress2, + creationHeight: expect.any(Number), + resignHeight: expect.any(Number), + resignTx: expect.any(String), + collateralTx: expect.any(String), + rewardAddress: expect.any(String), + state: expect.any(String), + mintedBlocks: expect.any(Number), + ownerIsMine: expect.any(Boolean), + localMasternode: expect.any(Boolean), + operatorIsMine: expect.any(Boolean), + targetMultipliers: expect.any(Object) + }) + }) + + it('should updateMasternode with utxos', async () => { + const balance = await container.call('getbalance') + expect(balance >= 2).toBeTruthy() + + const ownerAddress1 = await client.wallet.getNewAddress() + const masternodeId = await client.masternode.createMasternode(ownerAddress1) + + await container.generate(20) + + const ownerAddress2 = await client.wallet.getNewAddress() + await container.fundAddress(ownerAddress2, 10) + + await container.generate(1) + + const utxos = await container.call('listunspent') + const utxo = utxos.find((utxo: { address: string }) => utxo.address === ownerAddress2) + + const updateTxId = await client.masternode.updateMasternode( + masternodeId, + { ownerAddress: ownerAddress2 }, + [{ txid: utxo.txid, vout: utxo.vout }] + ) + + await container.generate(1) + + const rawtx = await container.call('getrawtransaction', [updateTxId, true]) + expect(rawtx.vin[0].txid).toStrictEqual(utxo.txid) + }) + + it('should be failed as p2sh address is not allowed', async () => { + const ownerAddress = await client.wallet.getNewAddress() + const masternodeId = await client.masternode.createMasternode(ownerAddress) + + await container.generate(1) + + { + const ownerAddressNew = await client.wallet.getNewAddress('', AddressType.P2SH_SEGWIT) + const promise = client.masternode.updateMasternode(masternodeId, { + ownerAddress: ownerAddressNew + }) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toThrow(`ownerAddress (${ownerAddressNew}) does not refer to a P2PKH or P2WPKH address`) + } + + { + const operatorAddress = await client.wallet.getNewAddress('', AddressType.P2SH_SEGWIT) + const promise = client.masternode.updateMasternode(masternodeId, { + operatorAddress + }) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toThrow(`operatorAddress (${operatorAddress}) does not refer to a P2PKH or P2WPKH address`) + } + + { + const rewardAddress = await client.wallet.getNewAddress('', AddressType.P2SH_SEGWIT) + const promise = client.masternode.updateMasternode(masternodeId, { + rewardAddress + }) + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toThrow(`rewardAddress (${rewardAddress}) does not refer to a P2PKH or P2WPKH address`) + } + }) }) diff --git a/packages/testcontainers/src/containers/DeFiDContainer.ts b/packages/testcontainers/src/containers/DeFiDContainer.ts index a7eca2268c..2e873a1277 100644 --- a/packages/testcontainers/src/containers/DeFiDContainer.ts +++ b/packages/testcontainers/src/containers/DeFiDContainer.ts @@ -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:HEAD-49fba65ce' + return 'defi/defichain:epic-grandcentral-bfb0eedb7' } public static readonly DefaultStartOptions = { diff --git a/packages/testcontainers/src/containers/RegTestContainer/index.ts b/packages/testcontainers/src/containers/RegTestContainer/index.ts index 1d9daaccbf..9ac383eb79 100644 --- a/packages/testcontainers/src/containers/RegTestContainer/index.ts +++ b/packages/testcontainers/src/containers/RegTestContainer/index.ts @@ -40,6 +40,7 @@ export class RegTestContainer extends DeFiDContainer { '-fortcanningspringheight=13', '-fortcanninggreatworldheight=14', '-fortcanningepilogueheight=15', + '-grandcentralheight=16', '-regtest-skip-loan-collateral-validation' ] From cc0f82832d6fadf11c613cea8a5413333f131e5f Mon Sep 17 00:00:00 2001 From: Mark Tan Date: Wed, 2 Nov 2022 14:46:29 +0800 Subject: [PATCH 03/64] Undo update config that was accidentally committed --- packages/testcontainers/src/containers/DeFiDContainer.ts | 2 +- .../testcontainers/src/containers/RegTestContainer/index.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/testcontainers/src/containers/DeFiDContainer.ts b/packages/testcontainers/src/containers/DeFiDContainer.ts index 2e873a1277..a7eca2268c 100644 --- a/packages/testcontainers/src/containers/DeFiDContainer.ts +++ b/packages/testcontainers/src/containers/DeFiDContainer.ts @@ -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:epic-grandcentral-bfb0eedb7' + return 'defi/defichain:HEAD-49fba65ce' } public static readonly DefaultStartOptions = { diff --git a/packages/testcontainers/src/containers/RegTestContainer/index.ts b/packages/testcontainers/src/containers/RegTestContainer/index.ts index 9ac383eb79..1d9daaccbf 100644 --- a/packages/testcontainers/src/containers/RegTestContainer/index.ts +++ b/packages/testcontainers/src/containers/RegTestContainer/index.ts @@ -40,7 +40,6 @@ export class RegTestContainer extends DeFiDContainer { '-fortcanningspringheight=13', '-fortcanninggreatworldheight=14', '-fortcanningepilogueheight=15', - '-grandcentralheight=16', '-regtest-skip-loan-collateral-validation' ] From b995da14f811a8da2168f719aea9754d77081ae6 Mon Sep 17 00:00:00 2001 From: Mark Tan Date: Tue, 15 Nov 2022 14:42:52 +0800 Subject: [PATCH 04/64] Update testcases --- .../masternode/updatemasternode.test.ts | 115 +++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts b/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts index c4105705a6..227bd2ff78 100644 --- a/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts +++ b/packages/jellyfish-api-core/__tests__/category/masternode/updatemasternode.test.ts @@ -16,7 +16,7 @@ describe('Masternode', () => { await container.stop() }) - it('should updateMasternode with bech32 address', async () => { + it('should updateMasternode ownerAddress with bech32 address', async () => { const ownerAddress1 = await client.wallet.getNewAddress() const masternodeId = await client.masternode.createMasternode(ownerAddress1) @@ -58,7 +58,49 @@ describe('Masternode', () => { }) }) - it('should updateMasternode with legacy address', async () => { + it('should updateMasternode operatorAddress with bech32 address', async () => { + const ownerAddress1 = await client.wallet.getNewAddress() + const masternodeId = await client.masternode.createMasternode(ownerAddress1) + + await container.generate(20) + + const masternodesBefore = await client.masternode.listMasternodes() + const masternodesLengthBefore = Object.keys(masternodesBefore).length + + const ownerAddress2 = await client.wallet.getNewAddress() + await client.masternode.updateMasternode(masternodeId, { + operatorAddress: ownerAddress2 + }) + + await container.generate(70) + + const masternodesAfter = await client.masternode.listMasternodes() + const masternodesLengthAfter = Object.keys(masternodesAfter).length + expect(masternodesLengthAfter).toStrictEqual(masternodesLengthBefore) + + const mn = masternodesAfter[masternodeId] + if (mn === undefined) { + throw new Error('should not reach here') + } + + expect(mn).toStrictEqual({ + operatorAuthAddress: ownerAddress2, + ownerAuthAddress: ownerAddress1, + creationHeight: expect.any(Number), + resignHeight: expect.any(Number), + resignTx: expect.any(String), + collateralTx: expect.any(String), + rewardAddress: expect.any(String), + state: expect.any(String), + mintedBlocks: expect.any(Number), + ownerIsMine: expect.any(Boolean), + localMasternode: expect.any(Boolean), + operatorIsMine: expect.any(Boolean), + targetMultipliers: expect.any(Object) + }) + }) + + it('should updateMasternode ownerAddress with legacy address', async () => { const ownerAddress1 = await client.wallet.getNewAddress('', AddressType.LEGACY) const masternodeId = await client.masternode.createMasternode(ownerAddress1) @@ -100,6 +142,48 @@ describe('Masternode', () => { }) }) + it('should updateMasternode operatorAddress with legacy address', async () => { + const ownerAddress1 = await client.wallet.getNewAddress('', AddressType.LEGACY) + const masternodeId = await client.masternode.createMasternode(ownerAddress1) + + await container.generate(20) + + const masternodesBefore = await client.masternode.listMasternodes() + const masternodesLengthBefore = Object.keys(masternodesBefore).length + + const ownerAddress2 = await client.wallet.getNewAddress('', AddressType.LEGACY) + await client.masternode.updateMasternode(masternodeId, { + operatorAddress: ownerAddress2 + }) + + await container.generate(70) + + const masternodesAfter = await client.masternode.listMasternodes() + const masternodesLengthAfter = Object.keys(masternodesAfter).length + expect(masternodesLengthAfter).toStrictEqual(masternodesLengthBefore) + + const mn = masternodesAfter[masternodeId] + if (mn === undefined) { + throw new Error('should not reach here') + } + + expect(mn).toStrictEqual({ + operatorAuthAddress: ownerAddress2, + ownerAuthAddress: ownerAddress1, + creationHeight: expect.any(Number), + resignHeight: expect.any(Number), + resignTx: expect.any(String), + collateralTx: expect.any(String), + rewardAddress: expect.any(String), + state: expect.any(String), + mintedBlocks: expect.any(Number), + ownerIsMine: expect.any(Boolean), + localMasternode: expect.any(Boolean), + operatorIsMine: expect.any(Boolean), + targetMultipliers: expect.any(Object) + }) + }) + it('should updateMasternode with utxos', async () => { const balance = await container.call('getbalance') expect(balance >= 2).toBeTruthy() @@ -162,4 +246,31 @@ describe('Masternode', () => { await expect(promise).rejects.toThrow(`rewardAddress (${rewardAddress}) does not refer to a P2PKH or P2WPKH address`) } }) + + it('should be failed as invalid address is not allowed', async () => { + const ownerAddress = await client.wallet.getNewAddress() + const masternodeId = await client.masternode.createMasternode(ownerAddress) + + await container.generate(20) + + { + const invalidAddress = 'INVALID_ADDRESS' + const promise = client.masternode.updateMasternode(masternodeId, { + ownerAddress: invalidAddress + }) + + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toThrow(`RpcApiError: 'ownerAddress (${invalidAddress}) does not refer to a P2PKH or P2WPKH address', code: -8, method: updatemasternode`) + } + + { + const invalidAddress = 'INVALID_ADDRESS' + const promise = client.masternode.updateMasternode(masternodeId, { + operatorAddress: invalidAddress + }) + + await expect(promise).rejects.toThrow(RpcApiError) + await expect(promise).rejects.toThrow(`RpcApiError: 'operatorAddress (${invalidAddress}) does not refer to a P2PKH or P2WPKH address', code: -8, method: updatemasternode`) + } + }) }) From bc30eb94c2b89ec16c22917e15e7e4f29f68036a Mon Sep 17 00:00:00 2001 From: Mark Tan Date: Wed, 16 Nov 2022 10:20:05 +0800 Subject: [PATCH 05/64] Update image version --- packages/testcontainers/src/containers/DeFiDContainer.ts | 2 +- .../testcontainers/src/containers/RegTestContainer/index.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/testcontainers/src/containers/DeFiDContainer.ts b/packages/testcontainers/src/containers/DeFiDContainer.ts index a7eca2268c..5d5a8e2ca5 100644 --- a/packages/testcontainers/src/containers/DeFiDContainer.ts +++ b/packages/testcontainers/src/containers/DeFiDContainer.ts @@ -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:HEAD-49fba65ce' + return 'defi/defichain:HEAD-453b1c948' } public static readonly DefaultStartOptions = { diff --git a/packages/testcontainers/src/containers/RegTestContainer/index.ts b/packages/testcontainers/src/containers/RegTestContainer/index.ts index 1d9daaccbf..9ac383eb79 100644 --- a/packages/testcontainers/src/containers/RegTestContainer/index.ts +++ b/packages/testcontainers/src/containers/RegTestContainer/index.ts @@ -40,6 +40,7 @@ export class RegTestContainer extends DeFiDContainer { '-fortcanningspringheight=13', '-fortcanninggreatworldheight=14', '-fortcanningepilogueheight=15', + '-grandcentralheight=16', '-regtest-skip-loan-collateral-validation' ] From bb069455c0423c1acc70464947c8ff2a1f8202f7 Mon Sep 17 00:00:00 2001 From: Mark Tan Date: Wed, 16 Nov 2022 14:14:23 +0800 Subject: [PATCH 06/64] Update image version --- apps/rich-list-api/docker-compose.yml | 3 ++- apps/whale-api/docker-compose.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/rich-list-api/docker-compose.yml b/apps/rich-list-api/docker-compose.yml index d7e556c4f2..c5bee40ba1 100644 --- a/apps/rich-list-api/docker-compose.yml +++ b/apps/rich-list-api/docker-compose.yml @@ -13,7 +13,7 @@ services: POSTGRES_DB: defichainrichlist defi-blockchain: - image: defi/defichain:HEAD-49fba65ce + image: defi/defichain:HEAD-453b1c948 ports: - "19554:19554" command: > @@ -47,4 +47,5 @@ services: -fortcanningspringheight=13 -fortcanninggreatworldheight=14 -fortcanningepilogueheight=15 + -grandcentralheight=16 -regtest-skip-loan-collateral-validation diff --git a/apps/whale-api/docker-compose.yml b/apps/whale-api/docker-compose.yml index 57c6151e88..ba817ccd88 100644 --- a/apps/whale-api/docker-compose.yml +++ b/apps/whale-api/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.7' services: defi-blockchain: - image: defi/defichain:HEAD-49fba65ce + image: defi/defichain:master-527a20001 ports: - "19554:19554" command: > @@ -36,6 +36,7 @@ services: -fortcanningspringheight=13 -fortcanninggreatworldheight=14 -fortcanningepilogueheight=15 + -grandcentralheight=16 -regtest-skip-loan-collateral-validation defi-whale: From 1673e3585c4e524e796305bf46f08140f2d32f8f Mon Sep 17 00:00:00 2001 From: Mark Tan Date: Fri, 18 Nov 2022 12:22:15 +0800 Subject: [PATCH 07/64] add dftx (WIP) --- .../src/script/dftx/dftx.ts | 2 ++ .../src/script/dftx/dftx_masternode.ts | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/packages/jellyfish-transaction/src/script/dftx/dftx.ts b/packages/jellyfish-transaction/src/script/dftx/dftx.ts index 9107da7928..bb171187fb 100644 --- a/packages/jellyfish-transaction/src/script/dftx/dftx.ts +++ b/packages/jellyfish-transaction/src/script/dftx/dftx.ts @@ -225,6 +225,8 @@ export class CDfTx extends ComposableBuffer> { return compose(CAutoAuthPrep.OP_NAME, () => new CAutoAuthPrep()) case CCreateMasternode.OP_CODE: return compose(CCreateMasternode.OP_NAME, d => new CCreateMasternode(d)) + case CUpdateMasternode.OP_CODE: + return compose(CUpdateMasternode.OP_NAME, d => new CUpdateMasternode(d)) case CResignMasternode.OP_CODE: return compose(CResignMasternode.OP_NAME, d => new CResignMasternode(d)) case CSetGovernance.OP_CODE: diff --git a/packages/jellyfish-transaction/src/script/dftx/dftx_masternode.ts b/packages/jellyfish-transaction/src/script/dftx/dftx_masternode.ts index e4ba86499b..8980d2010c 100644 --- a/packages/jellyfish-transaction/src/script/dftx/dftx_masternode.ts +++ b/packages/jellyfish-transaction/src/script/dftx/dftx_masternode.ts @@ -59,3 +59,27 @@ export class CResignMasternode extends ComposableBuffer { ] } } + +/** + * UpdateMasternode DeFi Transaction + */ +export interface UpdateMasternode { + nodeId: string // --------------------------------| VarUInt{32 bytes} + // updates: +} + +/** + * Composable UpdateMasternode, C stands for Composable. + * Immutable by design, bi-directional fromBuffer, toBuffer deep composer. + */ +export class CUpdateMasternode extends ComposableBuffer { + static OP_CODE = 0x6D // 'm' + static OP_NAME = 'OP_DEFI_TX_UPDATE_MASTER_NODE' + + composers (cmn: UpdateMasternode): BufferComposer[] { + return [ + ComposableBuffer.hexBEBufferLE(32, () => cmn.nodeId, v => cmn.nodeId = v) + + ] + } +} From 9fa64e0a213176196f8af2ea9cb6b9b5f8779a7b Mon Sep 17 00:00:00 2001 From: Kven Ho Date: Fri, 18 Nov 2022 14:16:36 +0800 Subject: [PATCH 08/64] Add mapping --- packages/jellyfish-transaction/src/script/mapping.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/jellyfish-transaction/src/script/mapping.ts b/packages/jellyfish-transaction/src/script/mapping.ts index 0761d967c4..4364515020 100644 --- a/packages/jellyfish-transaction/src/script/mapping.ts +++ b/packages/jellyfish-transaction/src/script/mapping.ts @@ -123,7 +123,7 @@ import { CICXClaimDFCHTLC, ICXClaimDFCHTLC } from './dftx/dftx_icxorderbook' -import { CCreateMasternode, CreateMasternode, CResignMasternode, ResignMasternode } from './dftx/dftx_masternode' +import { CCreateMasternode, CreateMasternode, CResignMasternode, ResignMasternode, UpdateMasternode } from './dftx/dftx_masternode' /** * @param num to map as OPCode, 1 byte long @@ -389,6 +389,14 @@ export const OP_CODES = { data: resignMasternode }) }, + OP_DEFI_TX_UPDATE_MASTER_NODE: (updateMasternode: UpdateMasternode): OP_DEFI_TX => { + return new OP_DEFI_TX({ + signature: CDfTx.SIGNATURE, + type: CCreateMasternode.OP_CODE, + name: CCreateMasternode.OP_NAME, + data: updateMasternode + }) + }, OP_DEFI_TX_SET_GOVERNANCE: (setGovernance: SetGovernance) => { return new OP_DEFI_TX({ signature: CDfTx.SIGNATURE, From 0ed853b6b3fea3bfa4d2e5d907ad36e432855d7b Mon Sep 17 00:00:00 2001 From: Kven Ho Date: Sat, 19 Nov 2022 23:01:49 +0800 Subject: [PATCH 09/64] WIP --- .../src/script/dftx/dftx.ts | 4 +-- .../src/script/dftx/dftx_masternode.ts | 29 +++++++++++++++---- .../src/script/mapping.ts | 6 ++-- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/packages/jellyfish-transaction/src/script/dftx/dftx.ts b/packages/jellyfish-transaction/src/script/dftx/dftx.ts index bb171187fb..dfd46a8982 100644 --- a/packages/jellyfish-transaction/src/script/dftx/dftx.ts +++ b/packages/jellyfish-transaction/src/script/dftx/dftx.ts @@ -12,7 +12,7 @@ import { CUtxosToAccount, CSetFutureSwap } from './dftx_account' -import { CCreateMasternode, CreateMasternode, CResignMasternode, ResignMasternode } from './dftx_masternode' +import { CCreateMasternode, CreateMasternode, CResignMasternode, ResignMasternode, CUpdateMasternode, UpdateMasternode } from './dftx_masternode' import { CAutoAuthPrep } from './dftx_misc' import { CPoolAddLiquidity, @@ -226,7 +226,7 @@ export class CDfTx extends ComposableBuffer> { case CCreateMasternode.OP_CODE: return compose(CCreateMasternode.OP_NAME, d => new CCreateMasternode(d)) case CUpdateMasternode.OP_CODE: - return compose(CUpdateMasternode.OP_NAME, d => new CUpdateMasternode(d)) + return compose(CUpdateMasternode.OP_NAME, d => new CUpdateMasternode(d)) case CResignMasternode.OP_CODE: return compose(CResignMasternode.OP_NAME, d => new CResignMasternode(d)) case CSetGovernance.OP_CODE: diff --git a/packages/jellyfish-transaction/src/script/dftx/dftx_masternode.ts b/packages/jellyfish-transaction/src/script/dftx/dftx_masternode.ts index 8980d2010c..b8997baadc 100644 --- a/packages/jellyfish-transaction/src/script/dftx/dftx_masternode.ts +++ b/packages/jellyfish-transaction/src/script/dftx/dftx_masternode.ts @@ -1,5 +1,7 @@ import { SmartBuffer } from 'smart-buffer' import { BufferComposer, ComposableBuffer } from '@defichain/jellyfish-buffer' +import { Script } from '../../tx' +import { CScript } from '../../tx_composer' /** * CreateMasternode DeFi Transaction @@ -63,9 +65,16 @@ export class CResignMasternode extends ComposableBuffer { /** * UpdateMasternode DeFi Transaction */ +// export interface UpdateMasternodeValues { +// ownerAddress?: string +// operatorAddress?: string +// rewardAddress?: string +// } export interface UpdateMasternode { nodeId: string // --------------------------------| VarUInt{32 bytes} - // updates: + ownerAddress?: Script + operatorAddress?: Script + rewardAddress?: Script } /** @@ -76,10 +85,20 @@ export class CUpdateMasternode extends ComposableBuffer { static OP_CODE = 0x6D // 'm' static OP_NAME = 'OP_DEFI_TX_UPDATE_MASTER_NODE' - composers (cmn: UpdateMasternode): BufferComposer[] { - return [ - ComposableBuffer.hexBEBufferLE(32, () => cmn.nodeId, v => cmn.nodeId = v) - + composers (umn: UpdateMasternode): BufferComposer[] { + let { ownerAddress, operatorAddress, rewardAddress } = umn + const bufferComposer = [ + ComposableBuffer.hexBEBufferLE(32, () => umn.nodeId, v => umn.nodeId = v) ] + if (typeof ownerAddress !== 'undefined') { + bufferComposer.push(ComposableBuffer.single