From 3994c8bdf9ed2bfd1ef2ba0790239b505f9b1916 Mon Sep 17 00:00:00 2001 From: lukas Date: Mon, 9 Sep 2024 14:47:53 +0200 Subject: [PATCH] fix: optimize fleet creation --- src/main/basedbot/basedbot.ts | 45 +++++++++--- .../fleet-strategies/get-fleet-strategy.ts | 4 +- .../basedbot/lib/sage/act/create-fleet.ts | 73 ++++++++++++++++--- src/main/basedbot/lib/sage/act/load-cargo.ts | 4 +- .../basedbot/lib/sage/ix/add-ship-to-fleet.ts | 2 +- 5 files changed, 98 insertions(+), 30 deletions(-) diff --git a/src/main/basedbot/basedbot.ts b/src/main/basedbot/basedbot.ts index 78100ce3..4da06994 100644 --- a/src/main/basedbot/basedbot.ts +++ b/src/main/basedbot/basedbot.ts @@ -2,6 +2,7 @@ import { getAssociatedTokenAddressSync, TOKEN_PROGRAM_ID, } from '@solana/spl-token' +import { PublicKey } from '@solana/web3.js' import { getParsedTokenAccountsByOwner } from '@staratlas/data-source' import { Fleet, Game } from '@staratlas/sage' import BN from 'bn.js' @@ -16,7 +17,7 @@ import { keyPair } from '../../service/wallet' import { getFleetStrategy } from './fleet-strategies/get-fleet-strategy' import { StrategyConfig } from './fleet-strategies/strategy-config' import { createInfoStrategy } from './fsm/info' -import { createFleet } from './lib/sage/act/create-fleet' +import { createFleet, FleetShip } from './lib/sage/act/create-fleet' import { depositCargo } from './lib/sage/act/deposit-cargo' import { ensureShips } from './lib/sage/act/deposit-ship' import { sageGame } from './lib/sage/state/game' @@ -122,8 +123,34 @@ const ensureFleets = async ( logger.info('Creating fleets:', neededFleets) } + const neededShips = new Map() + + neededFleets.forEach((fleetName) => { + const fleetStrategy = fleetStrategies.map.get(fleetName)! + + fleetStrategy.fleet?.forEach((fleetShip) => { + const curr = neededShips.get(fleetShip.shipMint.toBase58()) ?? 0 + + neededShips.set( + fleetShip.shipMint.toBase58(), + curr + fleetShip.count, + ) + }) + }) + + const shipMints = Array.from(neededShips.keys()) + .map((mint) => [ + { + count: neededShips.get(mint) ?? 0, + shipMint: new PublicKey(mint), + } as FleetShip, + ]) + .flat() + + await ensureShips(player, game, player.homeStarbase, shipMints) + await Promise.all( - neededFleets.map(async (fleetName) => { + neededFleets.map((fleetName) => { const fleetStrategy = fleetStrategies.map.get(fleetName)! if (!fleetStrategy.fleet) { @@ -131,19 +158,13 @@ const ensureFleets = async ( return Promise.resolve() } - await ensureShips( + + return createFleet( player, game, player.homeStarbase, - fleetStrategy.fleet, - ).then(() => - createFleet( - player, - game, - player.homeStarbase, - fleetStrategy.fleet!, - fleetName, - ), + fleetStrategy.fleet!, + fleetName, ) }), ) diff --git a/src/main/basedbot/fleet-strategies/get-fleet-strategy.ts b/src/main/basedbot/fleet-strategies/get-fleet-strategy.ts index 794fa65e..7589b148 100644 --- a/src/main/basedbot/fleet-strategies/get-fleet-strategy.ts +++ b/src/main/basedbot/fleet-strategies/get-fleet-strategy.ts @@ -29,8 +29,8 @@ export const getFleetStrategy = ( // return atlasnetFcStrategy(5)(map, player, game) return disbandAllStrategy(map, player, game) case '34ghznSJCYEMrS1aC55UYZZUuxfuurA9441aKnigmYyz': - return atlasnetFcStrategy(1)(map, player, game) - // return disbandAllStrategy(map, player, game) + // return atlasnetFcStrategy(5)(map, player, game) + return disbandAllStrategy(map, player, game) default: throw new Error('Unknown strategy') } diff --git a/src/main/basedbot/lib/sage/act/create-fleet.ts b/src/main/basedbot/lib/sage/act/create-fleet.ts index f2ae1f0d..8a59cc70 100644 --- a/src/main/basedbot/lib/sage/act/create-fleet.ts +++ b/src/main/basedbot/lib/sage/act/create-fleet.ts @@ -2,11 +2,13 @@ import { PublicKey } from '@solana/web3.js' import { InstructionReturn, ixReturnsToIxs } from '@staratlas/data-source' import { Game, + Ship, Starbase, StarbasePlayer, WrappedShipEscrow, } from '@staratlas/sage' +import { logger } from '../../../../../logger' import { sendAndConfirmInstructions } from '../../../../../service/sol/send-and-confirm-tx' import { programs } from '../../programs' import { addShipToFleetIx } from '../ix/add-ship-to-fleet' @@ -36,6 +38,11 @@ const getShipEscrowIndex = ( return index } +type ShipMintMap = { + mint: PublicKey + ship: Ship +} + export const createFleet = async ( player: Player, game: Game, @@ -45,14 +52,48 @@ export const createFleet = async ( ): Promise => { const instructions: InstructionReturn[] = [] - const [head, ...tail] = fleetShips + const shipMints = ( + await Promise.all( + fleetShips.map(async (fleetShip) => { + return { + mint: fleetShip.shipMint, + ship: await getShipByMint( + fleetShip.shipMint, + game, + programs, + ), + } as ShipMintMap + }), + ) + ).reduce( + (acc, curr) => acc.set(curr.mint.toBase58(), curr.ship), + new Map(), + ) + + const [starbasePlayer, [cargoStatsDefinition]] = await Promise.all([ + getStarbasePlayer(player, starbase, programs), + getCargoStatsDefinition(), + ]) - const [starbasePlayer, headShip, [cargoStatsDefinition]] = - await Promise.all([ - getStarbasePlayer(player, starbase, programs), - getShipByMint(head.shipMint, game, programs), - getCargoStatsDefinition(), - ]) + const [head, ...tail] = fleetShips.sort( + (a, b) => + getShipEscrowIndex( + starbasePlayer, + shipMints.get(a.shipMint.toBase58())!.key, + ) - + getShipEscrowIndex( + starbasePlayer, + shipMints.get(b.shipMint.toBase58())!.key, + ), + ) + + const shipKey = shipMints.get(head.shipMint.toBase58())?.key + + if (!shipKey) throw new Error('No ship found') + + const escrowIndex = getShipEscrowIndex(starbasePlayer, shipKey) + + logger.info(`Escrow index ${escrowIndex} for ${head.shipMint.toBase58()}`) const createFleetReturn = createFleetIx( player, @@ -60,17 +101,25 @@ export const createFleet = async ( starbase, starbasePlayer, programs, - headShip.key, + shipKey, cargoStatsDefinition.key, head.count, name, - getShipEscrowIndex(starbasePlayer, headShip.key), + escrowIndex, ) instructions.push(createFleetReturn.instructions) for (const fleetShip of tail) { - const ship = await getShipByMint(fleetShip.shipMint, game, programs) + const shipKey2 = shipMints.get(fleetShip.shipMint.toBase58())?.key + + if (!shipKey2) throw new Error('No ship found') + + const escrowIndex2 = getShipEscrowIndex(starbasePlayer, shipKey2) + + logger.info( + `Escrow index ${escrowIndex2} for ${fleetShip.shipMint.toBase58()}`, + ) instructions.push( addShipToFleetIx( @@ -80,9 +129,9 @@ export const createFleet = async ( starbasePlayer, programs, createFleetReturn.fleetKey[0], - ship.key, + shipKey2, fleetShip.count, - getShipEscrowIndex(starbasePlayer, ship.key), + escrowIndex2, ), ) } diff --git a/src/main/basedbot/lib/sage/act/load-cargo.ts b/src/main/basedbot/lib/sage/act/load-cargo.ts index da0bdcbd..e2d2452f 100644 --- a/src/main/basedbot/lib/sage/act/load-cargo.ts +++ b/src/main/basedbot/lib/sage/act/load-cargo.ts @@ -74,9 +74,7 @@ export const loadCargo = async ( cargoTokenAccount.delegatedAmount.toString(), ) - if (!cargoTokenAccount) { - throw new Error('Cargo not found at origin Starbase') - } + if (fuelAmountAtOrigin.lt(new BN(amount))) { throw new Error('Not enough cargo available at origin Starbase') } diff --git a/src/main/basedbot/lib/sage/ix/add-ship-to-fleet.ts b/src/main/basedbot/lib/sage/ix/add-ship-to-fleet.ts index 6c5f970c..bf2cbedc 100644 --- a/src/main/basedbot/lib/sage/ix/add-ship-to-fleet.ts +++ b/src/main/basedbot/lib/sage/ix/add-ship-to-fleet.ts @@ -31,6 +31,6 @@ export const addShipToFleetIx = ( shipAmount, shipEscrowIndex, keyIndex: 0, - fleetShipInfoIndex: 0, + fleetShipInfoIndex: null, }, )