2022-04-12 06:08:16 +00:00
|
|
|
import { Registry, Account, createBid } from './index';
|
2022-04-11 12:43:08 +00:00
|
|
|
import { getConfig } from './testing/helper';
|
|
|
|
|
|
|
|
jest.setTimeout(30 * 60 * 1000);
|
|
|
|
|
2022-04-12 10:54:26 +00:00
|
|
|
const { chainId, restEndpoint, gqlEndpoint, privateKey, fee } = getConfig();
|
2022-04-11 12:43:08 +00:00
|
|
|
|
|
|
|
const auctionTests = (numBidders = 3) => {
|
|
|
|
let registry: Registry;
|
|
|
|
|
2022-04-12 06:08:16 +00:00
|
|
|
const accounts: { address: string, privateKey: string, bid?: any }[] = [];
|
2022-04-11 12:43:08 +00:00
|
|
|
|
|
|
|
let auctionId: string;
|
|
|
|
let authorityName: string;
|
|
|
|
|
|
|
|
beforeAll(async () => {
|
|
|
|
console.log('Running auction tests with num bidders', numBidders);
|
|
|
|
|
2022-12-09 08:55:13 +00:00
|
|
|
registry = new Registry(gqlEndpoint, restEndpoint, chainId);
|
2022-04-11 12:43:08 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
test('Setup bidder accounts', async () => {
|
|
|
|
for (let i = 0; i < numBidders; i++) {
|
|
|
|
const mnenonic = Account.generateMnemonic();
|
|
|
|
const account = await Account.generateFromMnemonic(mnenonic);
|
|
|
|
const bidderAddress = account.formattedCosmosAddress;
|
2022-04-12 10:54:26 +00:00
|
|
|
await registry.sendCoins({ denom: 'aphoton', amount: '1000000000', destinationAddress: bidderAddress }, privateKey, fee);
|
2022-04-11 12:43:08 +00:00
|
|
|
accounts.push({ address: bidderAddress, privateKey: account.privateKey.toString('hex') });
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
test('Reserve authority.', async () => {
|
2022-09-28 19:20:15 +00:00
|
|
|
authorityName = `laconic-${Date.now()}`;
|
2022-04-12 10:54:26 +00:00
|
|
|
await registry.reserveAuthority({ name: authorityName }, accounts[0].privateKey, fee);
|
2022-04-11 12:43:08 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
test('Authority should be under auction.', async () => {
|
|
|
|
const [record] = await registry.lookupAuthorities([authorityName], true);
|
|
|
|
expect(record.ownerAddress).toEqual('');
|
|
|
|
expect(record.height).toBeDefined();
|
|
|
|
expect(record.status).toEqual('auction');
|
|
|
|
|
|
|
|
expect(record.auction.id).toBeDefined();
|
|
|
|
expect(record.auction.status).toEqual('commit');
|
|
|
|
|
|
|
|
auctionId = record.auction.id;
|
|
|
|
});
|
2022-04-12 06:08:16 +00:00
|
|
|
|
|
|
|
test('Commit bids.', async () => {
|
|
|
|
for (let i = 0; i < numBidders; i++) {
|
|
|
|
accounts[i].bid = await createBid(chainId, auctionId, accounts[i].address, `${10000000 + (i * 500)}aphoton`);
|
2022-04-12 10:54:26 +00:00
|
|
|
await registry.commitBid({ auctionId, commitHash: accounts[i].bid.commitHash }, accounts[i].privateKey, fee);
|
2022-04-12 06:08:16 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
test('Check bids are committed', async () => {
|
|
|
|
const [record] = await registry.lookupAuthorities([authorityName], true);
|
|
|
|
expect(record.auction.id).toBeDefined();
|
|
|
|
expect(record.auction.status).toEqual('commit');
|
|
|
|
expect(record.auction.bids).toHaveLength(accounts.length);
|
|
|
|
|
|
|
|
record.auction.bids.forEach((bid: any) => {
|
|
|
|
expect(bid.status).toEqual('commit');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('Wait for reveal phase.', (done) => {
|
|
|
|
setTimeout(done, 60 * 1000);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('Reveal bids.', async () => {
|
|
|
|
const [auction] = await registry.getAuctionsByIds([auctionId]);
|
|
|
|
expect(auction.status).toEqual('reveal');
|
|
|
|
|
|
|
|
for (let i = 0; i < numBidders; i++) {
|
2022-04-12 10:54:26 +00:00
|
|
|
await registry.revealBid({ auctionId, reveal: accounts[i].bid.revealString }, accounts[i].privateKey, fee);
|
2022-04-12 06:08:16 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
test('Check bids are revealed', async () => {
|
|
|
|
const [auction] = await registry.getAuctionsByIds([auctionId]);
|
|
|
|
expect(auction.status).toEqual('reveal');
|
|
|
|
|
|
|
|
auction.bids.forEach((bid: any) => {
|
|
|
|
expect(bid.status).toEqual('reveal');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
test('Wait for auction completion.', (done) => {
|
|
|
|
setTimeout(done, 60 * 1000);
|
|
|
|
});
|
|
|
|
|
|
|
|
test('Check auction winner, authority owner and status.', async () => {
|
|
|
|
const [auction] = await registry.getAuctionsByIds([auctionId]);
|
|
|
|
expect(auction.status).toEqual('completed');
|
|
|
|
|
|
|
|
const highestBidder = accounts[accounts.length - 1];
|
|
|
|
const secondHighestBidder = (accounts.length > 1 ? accounts[accounts.length - 2] : highestBidder);
|
|
|
|
|
|
|
|
expect(auction.winnerAddress).toEqual(highestBidder.address);
|
|
|
|
expect(highestBidder.bid.reveal.bidAmount).toEqual(`${auction.winnerBid.quantity}${auction.winnerBid.type}`);
|
|
|
|
expect(secondHighestBidder.bid.reveal.bidAmount).toEqual(`${auction.winnerPrice.quantity}${auction.winnerPrice.type}`);
|
|
|
|
|
|
|
|
const [record] = await registry.lookupAuthorities([authorityName], true);
|
|
|
|
expect(record.ownerAddress).toEqual(highestBidder.address);
|
|
|
|
expect(record.height).toBeDefined();
|
|
|
|
expect(record.status).toEqual('active');
|
|
|
|
});
|
2022-04-11 12:43:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const withNumBidders = (numBidders: number) => () => auctionTests(numBidders);
|
|
|
|
|
2022-04-19 10:24:41 +00:00
|
|
|
if (!process.env.TEST_AUCTIONS_ENABLED) {
|
2022-04-11 12:43:08 +00:00
|
|
|
// Required as jest complains if file has no tests.
|
|
|
|
test('skipping auction tests', () => {});
|
|
|
|
} else {
|
|
|
|
/**
|
2022-09-28 19:20:15 +00:00
|
|
|
Running these tests requires name auctions enabled. In laconicd repo run:
|
2022-04-11 12:43:08 +00:00
|
|
|
|
2022-04-18 11:27:37 +00:00
|
|
|
TEST_AUCTION_ENABLED=true ./init.sh
|
2022-04-11 12:43:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
Run tests:
|
|
|
|
|
|
|
|
yarn test:auctions
|
|
|
|
*/
|
|
|
|
describe('Auction (1 bidder)', withNumBidders(1));
|
2022-04-12 10:54:26 +00:00
|
|
|
describe('Auction (2 bidders)', withNumBidders(2));
|
|
|
|
describe('Auction (4 bidders)', withNumBidders(4));
|
2022-04-11 12:43:08 +00:00
|
|
|
}
|