Skip to content

N2CProvider Connection Fails with TUI Mode Enabled #142

@Mercurial

Description

@Mercurial

Bug Report: N2CProvider Connection Fails with TUI Mode Enabled

Description

When using Argus.Sync with TUI mode enabled, the N2CProvider fails with "Writing is not allowed after writer was completed" error when trying to establish a connection to a Cardano node via Unix socket.

Environment

  • Argus.Sync Version: 0.3.16-alpha
  • Chrysalis Version: 0.7.18
  • .NET Version: 9.0
  • OS: Linux (WSL2)
  • Cardano Network: Mainnet
  • Connection Type: Unix Socket

Steps to Reproduce

  1. Create a new .NET project with Argus.Sync package
  2. Configure appsettings.json with:
    {
      "CardanoNodeConnection": {
        "ConnectionType": "UnixSocket",
        "UnixSocket": {
          "Path": "/path/to/node.socket"
        },
        "NetworkMagic": 764824073
      },
      "Sync": {
        "Dashboard": {
          "TuiMode": true,
          "RefreshInterval": 5000,
          "DisplayType": "sync"
        }
      }
    }
  3. Run the application with dotnet run

Expected Behavior

The application should connect to the Cardano node and start syncing blocks while displaying the TUI dashboard.

Actual Behavior

The application fails with the following error:

fail: Argus.Sync.Workers.CardanoIndexWorker[0]
      Error occurred while syncing reducer BlockReducer
      System.InvalidOperationException: Writing is not allowed after writer was completed.
         at System.IO.Pipelines.ThrowHelper.ThrowInvalidOperationException_NoWritingAllowed()
         at System.IO.Pipelines.Pipe.GetSpan(Int32 sizeHint)
         at Chrysalis.Network.Multiplexer.AgentChannel.EnqueueChunkAsync(ReadOnlySequence`1 chunk, CancellationToken cancellationToken)
         at Chrysalis.Network.Multiplexer.ChannelBuffer.SendFullMessageAsync[T](T message, CancellationToken cancellationToken)
         at Chrysalis.Network.MiniProtocols.ChainSync.FindIntersectionAsync(IEnumerable`1 points, CancellationToken cancellationToken)
         at Argus.Sync.Providers.N2CProvider.StartChainSyncAsync(IEnumerable`1 intersections, UInt64 networkMagic, Nullable`1 stoppingToken)+MoveNext()

Workaround

Setting "TuiMode": false in the configuration resolves the issue.

Root Cause Analysis

The issue appears to be caused by concurrent operations on a shared NodeClient connection in N2CProvider:

  1. CardanoIndexWorker starts multiple concurrent tasks:

    • StartInitialTipQueryAsync() - queries chain tip periodically
    • StartReducerChainSyncAsync() - syncs blocks from the chain
  2. Both operations use the same N2CProvider instance which maintains a shared _sharedClient

  3. When both operations try to use the same connection concurrently, the Chrysalis multiplexer's internal pipe/channel gets into an invalid state

  4. One operation completes and closes the pipe writer while another is still trying to write to it

Additional Information

  • The same intersection point and socket work perfectly when using Chrysalis directly without Argus
  • The issue only occurs when TUI mode is enabled (which triggers the tip query task)
  • With TUI disabled, block syncing works correctly

Suggested Fix

Consider one of these approaches:

  1. Create separate NodeClient instances for different operations instead of sharing
  2. Implement proper synchronization to prevent concurrent access to the shared client
  3. Use separate providers for tip queries and chain sync operations

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions