Add methods for creating auctions and add auction tests #28

Merged
nabarun merged 32 commits from deep-stack/registry-sdk:iv-create-auction-test into main 2024-09-25 13:21:05 +00:00
5 changed files with 32 additions and 55 deletions
Showing only changes of commit 5659864611 - Show all commits

View File

@ -1,6 +1,7 @@
import { Registry, Account, createBid, INVALID_BID_ERROR, RELEASE_FUNDS_ERROR, OWNER_MISMATCH_ERROR } from './index'; import { Registry, Account, createBid } from './index';
import { checkAccountBalance, createTestAccounts, getConfig } from './testing/helper'; import { createTestAccounts, getConfig } from './testing/helper';
import { DENOM } from './constants'; import { DENOM } from './constants';
import { INVALID_BID_ERROR, OWNER_MISMATCH_ERROR, RELEASE_FUNDS_ERROR } from './types/cerc/auction/message';
jest.setTimeout(30 * 60 * 1000); jest.setTimeout(30 * 60 * 1000);
const { chainId, rpcEndpoint, gqlEndpoint, privateKey, fee } = getConfig(); const { chainId, rpcEndpoint, gqlEndpoint, privateKey, fee } = getConfig();
@ -105,13 +106,9 @@ const auctionTests = () => {
// Check that the bid amounts are locked after reveal phase // Check that the bid amounts are locked after reveal phase
for (let i = 0; i < numBidders; i++) { for (let i = 0; i < numBidders; i++) {
const { type, quantity } = await checkAccountBalance(registry, bidderAccounts[i].address);
const actualBalance = parseInt(quantity);
// The bid amount, commit fee, reveal fee and tx fees (for commit and reveal txs) will be deducted from the bidder's acoount // The bid amount, commit fee, reveal fee and tx fees (for commit and reveal txs) will be deducted from the bidder's acoount
const expectedBalance = bidderInitialBalance - parseInt(bidAmounts[i]) - (2 * txFees) - parseInt(commitFee) - parseInt(revealFee); const expectedBalance = bidderInitialBalance - parseInt(bidAmounts[i]) - (2 * txFees) - parseInt(commitFee) - parseInt(revealFee);
expect(actualBalance).toBe(expectedBalance); await checkAccountBalance(registry, bidderAccounts[i].address, expectedBalance);
expect(type).toBe(DENOM);
} }
}); });
@ -137,12 +134,9 @@ const auctionTests = () => {
const winningPriceAmount = parseInt(auction.winnerPrice.quantity); const winningPriceAmount = parseInt(auction.winnerPrice.quantity);
const { type, quantity } = await checkAccountBalance(registry, highestBidder.address);
const actualBalance = parseInt(quantity);
// The winning price will get deducted after auction completion // The winning price will get deducted after auction completion
expect(actualBalance).toBe(bidderInitialBalance - winningPriceAmount - (2 * txFees) - parseInt(commitFee)); const expectedBalance = bidderInitialBalance - winningPriceAmount - (2 * txFees) - parseInt(commitFee);
expect(type).toBe(DENOM); await checkAccountBalance(registry, highestBidder.address, expectedBalance);
}); });
}; };
@ -201,14 +195,9 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number
auctionId = auction.auction?.id || ''; auctionId = auction.auction?.id || '';
expect(auction.auction?.status).toEqual('commit'); expect(auction.auction?.status).toEqual('commit');
// Check that the total locked amount is deducted from the creator's account
const { type, quantity } = await checkAccountBalance(registry, auctionCreatorAccount.address);
const actualBalance = parseInt(quantity);
// The locked amount and tx fees are deducted from the auction creator's account // The locked amount and tx fees are deducted from the auction creator's account
const expectedBalance = creatorInitialBalance - (maxPrice * numProviders) - txFees; const expectedBalance = creatorInitialBalance - (maxPrice * numProviders) - txFees;
expect(actualBalance).toBe(expectedBalance); await checkAccountBalance(registry, auctionCreatorAccount.address, expectedBalance);
expect(type).toBe(DENOM);
}); });
test('Commit bids.', async () => { test('Commit bids.', async () => {
@ -301,14 +290,10 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number
const expectedWinningPrice = winningBidders[numWinners - 1].bid.reveal.bidAmount; const expectedWinningPrice = winningBidders[numWinners - 1].bid.reveal.bidAmount;
expect(`${auction.winnerPrice.quantity}${auction.winnerPrice.type}`).toEqual(expectedWinningPrice); expect(`${auction.winnerPrice.quantity}${auction.winnerPrice.type}`).toEqual(expectedWinningPrice);
const { type, quantity } = await checkAccountBalance(registry, auctionCreatorAccount.address);
const actualBalance = parseInt(quantity);
// The total winning amount will get deducted and the leftover locked amount is returned // The total winning amount will get deducted and the leftover locked amount is returned
const totalWinningAmount = parseInt(auction.winnerPrice.quantity) * winningBidders.length; const totalWinningAmount = parseInt(auction.winnerPrice.quantity) * winningBidders.length;
const expectedCreatorBalance = creatorInitialBalance - totalWinningAmount - txFees; const expectedCreatorBalance = creatorInitialBalance - totalWinningAmount - txFees;
expect(actualBalance).toBe(expectedCreatorBalance); await checkAccountBalance(registry, auctionCreatorAccount.address, expectedCreatorBalance);
expect(type).toBe(DENOM);
// Funds should not be given to winners on auction completion // Funds should not be given to winners on auction completion
for (let i = 0; i < winningBidders.length; i++) { for (let i = 0; i < winningBidders.length; i++) {
@ -317,12 +302,8 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number
expect(auction.winnerAddresses[i]).toEqual(bidWinner.address); expect(auction.winnerAddresses[i]).toEqual(bidWinner.address);
expect(`${auction.winnerBids[i].quantity}${auction.winnerBids[i].type}`).toEqual(bidWinner.bid.reveal.bidAmount); expect(`${auction.winnerBids[i].quantity}${auction.winnerBids[i].type}`).toEqual(bidWinner.bid.reveal.bidAmount);
const { type, quantity } = await checkAccountBalance(registry, bidWinner.address);
const actualBalance = parseInt(quantity);
const expectedBidderBalance = bidderInitialBalance - (2 * txFees) - parseInt(commitFee); const expectedBidderBalance = bidderInitialBalance - (2 * txFees) - parseInt(commitFee);
expect(actualBalance).toBe(expectedBidderBalance); await checkAccountBalance(registry, bidWinner.address, expectedBidderBalance);
expect(type).toBe(DENOM);
} }
}); });
@ -347,25 +328,18 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number
expect(auctionObj.auction?.fundsReleased).toBe(true); expect(auctionObj.auction?.fundsReleased).toBe(true);
// Auction winners get the winning amount after funds are released // Auction winners get the winning amount after funds are released
const expectedBidderBalance = bidderInitialBalance + winningBidAmount - (2 * txFees) - parseInt(commitFee);
for (let i = 0; i < winningBidders.length; i++) { for (let i = 0; i < winningBidders.length; i++) {
const bidWinner = winningBidders[i]; const bidWinner = winningBidders[i];
expect(auction.winnerAddresses[i]).toEqual(bidWinner.address); expect(auction.winnerAddresses[i]).toEqual(bidWinner.address);
expect(`${auction.winnerBids[i].quantity}${auction.winnerBids[i].type}`).toEqual(bidWinner.bid.reveal.bidAmount); expect(`${auction.winnerBids[i].quantity}${auction.winnerBids[i].type}`).toEqual(bidWinner.bid.reveal.bidAmount);
const { type, quantity } = await checkAccountBalance(registry, bidWinner.address); await checkAccountBalance(registry, bidWinner.address, expectedBidderBalance);
const actualBalance = parseInt(quantity);
const expectedBidderBalance = bidderInitialBalance + winningBidAmount - (2 * txFees) - parseInt(commitFee);
expect(actualBalance).toBe(expectedBidderBalance);
expect(type).toBe(DENOM);
} }
// Check balances of non-winners // Check balances of non-winners
for (const bidder of losingBidders) { for (const bidder of losingBidders) {
const { type, quantity } = await checkAccountBalance(registry, bidder.address);
const actualBalance = parseInt(quantity);
let expectedBidderBalance: number; let expectedBidderBalance: number;
if (invalidBidderAddress !== bidder.address) { if (invalidBidderAddress !== bidder.address) {
expectedBidderBalance = bidderInitialBalance - (2 * txFees) - parseInt(commitFee); expectedBidderBalance = bidderInitialBalance - (2 * txFees) - parseInt(commitFee);
@ -374,8 +348,7 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number
expectedBidderBalance = bidderInitialBalance - (2 * txFees) - parseInt(commitFee) - parseInt(revealFee); expectedBidderBalance = bidderInitialBalance - (2 * txFees) - parseInt(commitFee) - parseInt(revealFee);
} }
expect(actualBalance).toBe(expectedBidderBalance); await checkAccountBalance(registry, bidder.address, expectedBidderBalance);
expect(type).toBe(DENOM);
} }
// Funds cannot be released twice // Funds cannot be released twice
@ -387,14 +360,23 @@ const providerAuctionTestsWithBids = (bidAmounts: number[], numProviders: number
}); });
}; };
const checkAccountBalance = async (registry: Registry, address: string, expectedBalance: number): Promise<void> => {
const [winnerAccountObj] = await registry.getAccounts([address]);
const [{ type, quantity }] = winnerAccountObj.balance;
const actualBalance = parseInt(quantity);
expect(actualBalance).toBe(expectedBalance);
expect(type).toBe(DENOM);
};
const providerAuctionTests = () => { const providerAuctionTests = () => {
// With a bid amount greater than the max price // With a bid amount greater than the max price
const bids1 = [10002000, 10009000, 10006000 * 10, 10004000]; const bids = [10002000, 10009000, 10006000 * 10, 10004000];
// Number of providers is less than number of bidders // Number of providers is less than number of bidders
describe('Auction with numProviders < numBidders', () => providerAuctionTestsWithBids(bids1, 3)); describe('Auction with numProviders < numBidders', () => providerAuctionTestsWithBids(bids, 3));
// Number of providers is greater than number of bidders // Number of providers is greater than number of bidders
describe('Auction numProviders > numBidders', () => providerAuctionTestsWithBids(bids1, 5)); describe('Auction numProviders > numBidders', () => providerAuctionTestsWithBids(bids, 5));
}; };
describe('Vickrey Auction', () => auctionTests()); describe('Vickrey Auction', () => auctionTests());

View File

@ -13,8 +13,8 @@ import { Comet38Client } from '@cosmjs/tendermint-rpc';
import { MsgCancelBondEncodeObject, MsgCreateBondEncodeObject, MsgRefillBondEncodeObject, MsgWithdrawBondEncodeObject, bondTypes, typeUrlMsgCancelBond, typeUrlMsgCreateBond, typeUrlMsgRefillBond, typeUrlMsgWithdrawBond } from './types/cerc/bond/message'; import { MsgCancelBondEncodeObject, MsgCreateBondEncodeObject, MsgRefillBondEncodeObject, MsgWithdrawBondEncodeObject, bondTypes, typeUrlMsgCancelBond, typeUrlMsgCreateBond, typeUrlMsgRefillBond, typeUrlMsgWithdrawBond } from './types/cerc/bond/message';
import { Coin } from './proto/cosmos/base/v1beta1/coin'; import { Coin } from './proto/cosmos/base/v1beta1/coin';
import { MsgAssociateBondEncodeObject, MsgDeleteNameEncodeObject, MsgDissociateBondEncodeObject, MsgDissociateRecordsEncodeObject, MsgReassociateRecordsEncodeObject, MsgReserveAuthorityEncodeObject, MsgSetAuthorityBondEncodeObject, MsgSetNameEncodeObject, MsgSetRecordEncodeObject, registryTypes, typeUrlMsgAssociateBond, typeUrlMsgDeleteName, typeUrlMsgDissociateBond, typeUrlMsgDissociateRecords, typeUrlMsgReassociateRecords, typeUrlMsgReserveAuthority, typeUrlMsgSetAuthorityBond, typeUrlMsgSetName, typeUrlMsgSetRecord, NAMESERVICE_ERRORS } from './types/cerc/registry/message'; import { MsgAssociateBondEncodeObject, MsgDeleteNameEncodeObject, MsgDissociateBondEncodeObject, MsgDissociateRecordsEncodeObject, MsgReassociateRecordsEncodeObject, MsgReserveAuthorityEncodeObject, MsgSetAuthorityBondEncodeObject, MsgSetNameEncodeObject, MsgSetRecordEncodeObject, registryTypes, typeUrlMsgAssociateBond, typeUrlMsgDeleteName, typeUrlMsgDissociateBond, typeUrlMsgDissociateRecords, typeUrlMsgReassociateRecords, typeUrlMsgReserveAuthority, typeUrlMsgSetAuthorityBond, typeUrlMsgSetName, typeUrlMsgSetRecord, NAMESERVICE_ERRORS } from './types/cerc/registry/message';
import { MsgCommitBidEncodeObject, MsgCreateAuctionEncodeObject, MsgReleaseFundsEncodeObject, MsgRevealBidEncodeObject, auctionTypes, typeUrlMsgCommitBid, typeUrlMsgCreateAuction, typeUrlMsgReleaseFunds, typeUrlMsgRevealBid } from './types/cerc/auction/message'; import { AUCTION_ERRORS, MsgCommitBidEncodeObject, MsgCreateAuctionEncodeObject, MsgReleaseFundsEncodeObject, MsgRevealBidEncodeObject, auctionTypes, typeUrlMsgCommitBid, typeUrlMsgCreateAuction, typeUrlMsgReleaseFunds, typeUrlMsgRevealBid } from './types/cerc/auction/message';
import { INVALID_BID_ERROR, MsgOnboardParticipantEncodeObject, ONBOARDING_DISABLED_ERROR, onboardingTypes, OWNER_MISMATCH_ERROR, RELEASE_FUNDS_ERROR, typeUrlMsgOnboardParticipant } from './types/cerc/onboarding/message'; import { MsgOnboardParticipantEncodeObject, ONBOARDING_DISABLED_ERROR, onboardingTypes, typeUrlMsgOnboardParticipant } from './types/cerc/onboarding/message';
import { MsgAssociateBondResponse, MsgDeleteNameResponse, MsgDissociateBondResponse, MsgDissociateRecordsResponse, MsgReassociateRecordsResponse, MsgReserveAuthorityResponse, MsgSetAuthorityBondResponse, MsgSetNameResponse, MsgSetRecordResponse, Payload } from './proto/cerc/registry/v1/tx'; import { MsgAssociateBondResponse, MsgDeleteNameResponse, MsgDissociateBondResponse, MsgDissociateRecordsResponse, MsgReassociateRecordsResponse, MsgReserveAuthorityResponse, MsgSetAuthorityBondResponse, MsgSetNameResponse, MsgSetRecordResponse, Payload } from './proto/cerc/registry/v1/tx';
import { Record, Signature } from './proto/cerc/registry/v1/registry'; import { Record, Signature } from './proto/cerc/registry/v1/registry';
import { Account } from './account'; import { Account } from './account';
@ -383,7 +383,7 @@ export class LaconicClient extends SigningStargateClient {
} }
processWriteError (error: string) { processWriteError (error: string) {
const errorMessage = [...NAMESERVICE_ERRORS, ONBOARDING_DISABLED_ERROR, INVALID_BID_ERROR, RELEASE_FUNDS_ERROR, OWNER_MISMATCH_ERROR].find(message => error.includes(message)); const errorMessage = [...NAMESERVICE_ERRORS, ...AUCTION_ERRORS, ONBOARDING_DISABLED_ERROR].find(message => error.includes(message));
if (!errorMessage) { if (!errorMessage) {
console.error(error); console.error(error);

View File

@ -48,10 +48,3 @@ export const createTestAccounts = async (numAccounts: number): Promise<Account[]
return accounts; return accounts;
}; };
export const checkAccountBalance = async (registry: Registry, address: string): Promise<{ type: string, quantity: string }> => {
const [winnerAccountObj] = await registry.getAccounts([address]);
const [{ type, quantity }] = winnerAccountObj.balance;
return { type, quantity };
};

View File

@ -42,6 +42,11 @@ export interface MsgReleaseFundsEncodeObject extends EncodeObject {
readonly value: Partial<MsgReleaseFunds>; readonly value: Partial<MsgReleaseFunds>;
} }
export const INVALID_BID_ERROR = 'Bid is higher than max price';
export const RELEASE_FUNDS_ERROR = 'Auction funds already released';
export const OWNER_MISMATCH_ERROR = 'Only auction owner can release funds';
export const AUCTION_ERRORS = [INVALID_BID_ERROR, RELEASE_FUNDS_ERROR, OWNER_MISMATCH_ERROR];
export interface MessageMsgCommitBid { export interface MessageMsgCommitBid {
auctionId: string, auctionId: string,
commitHash: string, commitHash: string,

View File

@ -16,9 +16,6 @@ export interface MsgOnboardParticipantEncodeObject extends EncodeObject {
} }
export const ONBOARDING_DISABLED_ERROR = 'Onboarding is disabled'; export const ONBOARDING_DISABLED_ERROR = 'Onboarding is disabled';
export const INVALID_BID_ERROR = 'Bid is higher than max price';
export const RELEASE_FUNDS_ERROR = 'Auction funds already released';
export const OWNER_MISMATCH_ERROR = 'Only auction owner can release funds';
interface ethPayload { interface ethPayload {
address: string address: string