# launchTestNode in 0.94.0 causes "Address already in use" errors and more

**URL:** https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488
**Category:** TypeScript SDK
**Created:** [August 20, 2024, 7:48am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488 "2024-08-20T07:48:22Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![xpluscal](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/xpluscal/32/3337_2.png) [@xpluscal](https://forum.fuel.network/u/xpluscal)
#### Post date: [August 20, 2024, 7:48am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/1 "2024-08-20T07:48:22Z")

</div>

Migrated to TS SDK 0.94.0 and now all tests start failing with the following logs:

```auto
FuelError: 2024-08-20T07:45:17.400811Z INFO new{name=fuel-core}:initialize_loop{service="SyncTask"}: fuel_core_services::service: 286: The service SyncTask is shut down
2024-08-20T07:45:17.400879Z INFO new{name=fuel-core}:initialize_loop{service="ImportTask"}: fuel_core_services::service: 286: The service ImportTask is shut down
2024-08-20T07:45:17.401027Z INFO new{name=fuel-core}:initialize_loop{service="GraphQL_Off_Chain_Worker"}: fuel_core_services::service: 286: The service GraphQL_Off_Chain_Worker is shut down
Error: Address already in use (os error 48)

```

I went through the Migration Log, but couldn’t find any required changes to the behaviour other than renaming the TTL param for provider.

Help appreciated.

---

<div class="post-metadata">

### Author: ![nedsalk](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/nedsalk/32/1867_2.png) [@nedsalk](https://forum.fuel.network/u/nedsalk)
#### Post date: [August 20, 2024, 7:53am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/2 "2024-08-20T07:53:37Z")

</div>

Hi @xpluscal, thanks for the reports!

It would be ideal if you could share a test or two for us to see how it looks like. Are you perhaps specifying a `nodeOptions.port` value in your tests?

```auto
using launched = await launchTestNode({ nodeOptions: { port: "4000" }})`

```

This field was previously ignored but is now taken into consideration and, if you have it set, you can remove it and the tests should be unblocked from that aspect.

---

<div class="post-metadata">

### Author: ![xpluscal](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/xpluscal/32/3337_2.png) [@xpluscal](https://forum.fuel.network/u/xpluscal)
#### Post date: [August 20, 2024, 8:01am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/3 "2024-08-20T08:01:39Z")

</div>

Sure, this is my setup function:

```auto
export async function setup(): Promise<
    {
        wallet1: WalletUnlocked;
        wallet2: WalletUnlocked;
        wallet3: WalletUnlocked;
        wallet4: WalletUnlocked;
        provider: Provider;
        feeSplitterContract: PropsFeeSplitterContract;
    }
> {
  const assets = TestAssetId.random(2);
  const message = new TestMessage({ amount: 1000 });

  const launched = await launchTestNode({
    walletsConfig: {
      count: 4, // Number of wallets to create
      assets, // Assets to use
      coinsPerAsset: 1, // Number of coins per asset
      amountPerCoin: 1_000_000, // Amount per coin
      messages: [message], // Initial messages
    },
    nodeOptions: {
      port: "4000",
    },
    launchNodeServerPort: "4000",
  });

  // Destructure the launched object to get wallets and contracts
  const {
    contracts: [],
    wallets: [wallet1, wallet2, wallet3, wallet4],
    provider,
  } = launched;

  console.log("PROVIDER: ", provider);

  const address = Address.fromDynamicInput(wallet1.address);
  const addressInput = { bits: address.toB256() };
  const addressIdentityInput = { Address: addressInput };

  const { waitForResult } =
    await PropsFeeSplitterContractFactory.deploy(
      wallet1,
      {
        salt: "0x0000000000000000000000000000000000000000000000000000000000000000" as BytesLike,
      }
    );

  const { contract: feeSplitterContract, transactionResult } =
    await waitForResult();

  // Initialize the Fee Splitter Contract
  const { waitForResult: waitForFeeSplitterConstructorResult } =
    await feeSplitterContract.functions
      .constructor(addressIdentityInput)
      .call();

  await waitForFeeSplitterConstructorResult();

  // Log hash of deployed fee splitter contract
  const feeSplitterContractId = feeSplitterContract.id;
  // console.log(
  // "Props Fee Splitter Contract deployed at:",
  // feeSplitterContractId.toB256()
  // );

  // Deploy Props Registry Contract
  const { waitForResult: waitForPropsRegistryResult } =
    await PropsRegistryContractFactory.deploy(
      wallet1,
      {
        salt: "0x0000000000000000000000000000000000000000000000000000000000000000" as BytesLike,
      }
    );

  const { contract: propsRegistryContract } =
    await waitForPropsRegistryResult();

  // Initialize the Props Registry Contract
  const { waitForResult: waitForPropsRegistryConstructorResult } =
    await propsRegistryContract.functions
      .constructor(addressIdentityInput)
      .call();

  await waitForPropsRegistryConstructorResult();

  // Log hash of deployed registry contract
  const registryContractId = propsRegistryContract.id;
  // console.log(
  // "Props Registry Contract deployed at:",
  // registryContractId.toB256()
  // );

  return { wallet1, wallet2, wallet3, wallet4, provider, feeSplitterContract };
}

```

Here’s a sample test:

```auto

  it("should create an edition instance", () => {
    expect(edition).toBeInstanceOf(Edition);
    expect(edition.id).toBe("edition-id");
    expect(edition.metadata?.name).toBe("Test Edition");
  });

  it("should connect an account to the edition", () => {
    edition.connect(wallets[1]);
    expect(edition.account).toBe(wallets[1]);
  });

```

---

<div class="post-metadata">

### Author: ![xpluscal](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/xpluscal/32/3337_2.png) [@xpluscal](https://forum.fuel.network/u/xpluscal)
#### Post date: [August 20, 2024, 8:02am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/4 "2024-08-20T08:02:13Z")

</div>

@nedsalk will try removing that port now.

---

<div class="post-metadata">

### Author: ![xpluscal](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/xpluscal/32/3337_2.png) [@xpluscal](https://forum.fuel.network/u/xpluscal)
#### Post date: [August 20, 2024, 8:07am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/5 "2024-08-20T08:07:55Z")

</div>

@nedsalk has anything changed regarding addContracts?  
Getting contract not in inputs now, but running against frontend works fine.

---

<div class="post-metadata">

### Author: ![nedsalk](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/nedsalk/32/1867_2.png) [@nedsalk](https://forum.fuel.network/u/nedsalk)
#### Post date: [August 20, 2024, 8:09am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/6 "2024-08-20T08:09:45Z")

</div>

Did you update your `forc` version to `0.63.1` and `fuel-core` to `0.33.0`?

---

<div class="post-metadata">

### Author: ![xpluscal](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/xpluscal/32/3337_2.png) [@xpluscal](https://forum.fuel.network/u/xpluscal)
#### Post date: [August 20, 2024, 8:10am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/7 "2024-08-20T08:10:08Z")

</div>

Assuming that needs to be done manually since there’s no nightly yet for that right?

---

<div class="post-metadata">

### Author: ![xpluscal](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/xpluscal/32/3337_2.png) [@xpluscal](https://forum.fuel.network/u/xpluscal)
#### Post date: [August 20, 2024, 8:10am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/8 "2024-08-20T08:10:39Z")

</div>

That’s my current toolchain:

nightly-x86\_64-apple-darwin (default)

**forc** : 0.63.1+nightly.20240820.169f91ae0a

- **forc-client**

- **forc-deploy** : 0.63.1+nightly.20240820.169f91ae0a

- **forc-run** : 0.63.1+nightly.20240820.169f91ae0a

- **forc-crypto** : 0.63.1+nightly.20240820.169f91ae0a

- **forc-debug** : 0.63.1+nightly.20240820.169f91ae0a

- **forc-doc** : 0.63.1+nightly.20240820.169f91ae0a

- **forc-fmt** : 0.63.1+nightly.20240820.169f91ae0a

- **forc-lsp** : 0.63.1+nightly.20240820.169f91ae0a

- **forc-tx** : 0.63.1+nightly.20240820.169f91ae0a

- **forc-wallet** : 0.9.0+nightly.20240820.29d9b25c2c

**fuel-core** : 0.32.1+nightly.20240816.a2d8d2dc62

**fuel-core-keygen** : not found

---

<div class="post-metadata">

### Author: ![nedsalk](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/nedsalk/32/1867_2.png) [@nedsalk](https://forum.fuel.network/u/nedsalk)
#### Post date: [August 20, 2024, 8:12am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/9 "2024-08-20T08:12:09Z")

</div>

`forc 0.63.1` and `fuel-core 0.33.0` have been released so you can add them, best to do it via a custom toolchain as of now because the `testnet` toolchain hasn’t been updated yet.

`fuelup toolchain new custom && fuelup component add forc@0.63.1 && fuelup component add fuel-core@0.33.0`.

---

<div class="post-metadata">

### Author: ![xpluscal](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/xpluscal/32/3337_2.png) [@xpluscal](https://forum.fuel.network/u/xpluscal)
#### Post date: [August 20, 2024, 8:18am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/10 "2024-08-20T08:18:27Z")

</div>

Thanks, all updated, similar issue.  
I’m basically just passing the created contract directly back as input for the next call.

Could this be an issue with UTXO of the launchTestNode or anything else?

```typescript
const salt: BytesLike = randomBytes(32);
const { waitForResult } =
  await EditionContractFactory.deploy(
    owner,
    {
      configurableConstants,
      salt,
    }
  );

const { contract } = await waitForResult();

const registryContract = new RegistryContract(
  registryContractAddress,
  owner
);

const { waitForResult: waitForResultConstructor } =
  await registryContract.functions
    .init_edition(
      { bits: contract.id.toB256() }
    )
    .addContracts([contract])
    .call();

```

---

<div class="post-metadata">

### Author: ![nedsalk](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/nedsalk/32/1867_2.png) [@nedsalk](https://forum.fuel.network/u/nedsalk)
#### Post date: [August 20, 2024, 8:53am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/11 "2024-08-20T08:53:18Z")

</div>

Where do you get the `registryContractAddress` from? You need to deploy the `RegistryContract` via `launchTestNode` as well. That error happens when you try to execute a transaction with a non-existing contract.

---

<div class="post-metadata">

### Author: ![nedsalk](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.fuel.network/nedsalk/32/1867_2.png) [@nedsalk](https://forum.fuel.network/u/nedsalk)
#### Post date: [August 20, 2024, 9:20am UTC](https://forum.fuel.network/t/launchtestnode-in-0-94-0-causes-address-already-in-use-errors-and-more/6488/12 "2024-08-20T09:20:00Z")

</div>

Also, it seems to me that you’re not using the `launchTestNode` utility as intended, especially because you’re not returning a `cleanup` function anywhere, which means that you’re going to be having `fuel-core` nodes staying on even after tests are finished. I did a bit of a refactor based on my understanding of the code as well and the defaults as well besides adding a `cleanup` field in the return.

Two things to note:

1. cleanup is returned
2. contracts are directly deployed via the `contractsConfigs` field

```ts
export async function setup(): Promise<
    {
        wallet1: WalletUnlocked;
        wallet2: WalletUnlocked;
        wallet3: WalletUnlocked;
        wallet4: WalletUnlocked;
        provider: Provider;
        feeSplitterContract: PropsFeeSplitterContract;
        cleanup: () => void;
    }
> {

  const message = new TestMessage({ amount: 1000 });

  const launched = await launchTestNode({
    walletsConfig: {
      count: 4, // Number of wallets to create
      messages: [message], // Initial messages
    },
    contractsConfigs: [
        { factory: PropsFeeSplitterContractFactory },
        { factory: PropsRegistryContractFactory }
    ]
  });

  // Destructure the launched object to get wallets and contracts
  const {
    contracts: [feeSplitterContract, propsRegistryContract],
    wallets: [wallet1, wallet2, wallet3, wallet4],
    provider,
    cleanup
  } = launched;

  console.log("PROVIDER: ", provider);

  const addressIdentityInput = { Address: wallet1.address.toB56() };

  // Initialize the Fee Splitter Contract
  const { waitForResult: waitForFeeSplitterConstructorResult } =
    await feeSplitterContract.functions
      .constructor(addressIdentityInput)
      .call();

  await waitForFeeSplitterConstructorResult();

  // Log hash of deployed fee splitter contract
  const feeSplitterContractId = feeSplitterContract.id;
  // console.log(
  // "Props Fee Splitter Contract deployed at:",
  // feeSplitterContractId.toB256()
  // );

  // Initialize the Props Registry Contract
  const { waitForResult: waitForPropsRegistryConstructorResult } =
    await propsRegistryContract.functions
      .constructor(addressIdentityInput)
      .call();

  await waitForPropsRegistryConstructorResult();

  // Log hash of deployed registry contract
  const registryContractId = propsRegistryContract.id;
  // console.log(
  // "Props Registry Contract deployed at:",
  // registryContractId.toB256()
  // );

  return { wallet1, wallet2, wallet3, wallet4, provider, feeSplitterContract, cleanup };
}

```

And then you have to call `cleanup` at the end of each test:

```ts
const { cleanup, ...rest } = await setup();
// do stuff in test
// done with node?
cleanup();

```

If you want to make it `using`-compatible, you can do this to the return:

```ts
const returnObj = { wallet1, wallet2, wallet3, wallet4, provider, feeSplitterContract, cleanup };
return Object.assign(returnObj, {[Symbol.disposable]: cleanup});

```

and then you can write your tests like this:

```ts
using launched = await setup();
// do testing
// when launched variable goes out of scope,
// the cleanup function will be called automagically

```
