May 23, 1-2 PM (6)
May 23, 2-3 PM (5)
May 23, 3-4 PM (5)
May 23, 4-5 PM (4)
May 23, 5-6 PM (0)
May 23, 6-7 PM (3)
May 23, 7-8 PM (23)
May 23, 8-9 PM (1)
May 23, 9-10 PM (9)
May 23, 10-11 PM (21)
May 23, 11-12 AM (27)
May 24, 12-1 AM (9)
May 24, 1-2 AM (0)
May 24, 2-3 AM (1)
May 24, 3-4 AM (1)
May 24, 4-5 AM (0)
May 24, 5-6 AM (3)
May 24, 6-7 AM (1)
May 24, 7-8 AM (2)
May 24, 8-9 AM (2)
May 24, 9-10 AM (4)
May 24, 10-11 AM (4)
May 24, 11-12 PM (1)
May 24, 12-1 PM (7)
May 24, 1-2 PM (46)
May 24, 2-3 PM (5)
May 24, 3-4 PM (3)
May 24, 4-5 PM (18)
May 24, 5-6 PM (2)
May 24, 6-7 PM (4)
May 24, 7-8 PM (13)
May 24, 8-9 PM (10)
May 24, 9-10 PM (15)
May 24, 10-11 PM (34)
May 24, 11-12 AM (42)
May 25, 12-1 AM (9)
May 25, 1-2 AM (5)
May 25, 2-3 AM (6)
May 25, 3-4 AM (1)
May 25, 4-5 AM (6)
May 25, 5-6 AM (14)
May 25, 6-7 AM (17)
May 25, 7-8 AM (17)
May 25, 8-9 AM (32)
May 25, 9-10 AM (43)
May 25, 10-11 AM (64)
May 25, 11-12 PM (33)
May 25, 12-1 PM (43)
May 25, 1-2 PM (40)
May 25, 2-3 PM (20)
May 25, 3-4 PM (27)
May 25, 4-5 PM (16)
May 25, 5-6 PM (6)
May 25, 6-7 PM (7)
May 25, 7-8 PM (11)
May 25, 8-9 PM (12)
May 25, 9-10 PM (16)
May 25, 10-11 PM (44)
May 25, 11-12 AM (26)
May 26, 12-1 AM (12)
May 26, 1-2 AM (11)
May 26, 2-3 AM (8)
May 26, 3-4 AM (11)
May 26, 4-5 AM (6)
May 26, 5-6 AM (9)
May 26, 6-7 AM (26)
May 26, 7-8 AM (43)
May 26, 8-9 AM (39)
May 26, 9-10 AM (42)
May 26, 10-11 AM (45)
May 26, 11-12 PM (59)
May 26, 12-1 PM (34)
May 26, 1-2 PM (50)
May 26, 2-3 PM (50)
May 26, 3-4 PM (18)
May 26, 4-5 PM (20)
May 26, 5-6 PM (13)
May 26, 6-7 PM (20)
May 26, 7-8 PM (12)
May 26, 8-9 PM (15)
May 26, 9-10 PM (15)
May 26, 10-11 PM (35)
May 26, 11-12 AM (30)
May 27, 12-1 AM (16)
May 27, 1-2 AM (8)
May 27, 2-3 AM (9)
May 27, 3-4 AM (5)
May 27, 4-5 AM (32)
May 27, 5-6 AM (9)
May 27, 6-7 AM (49)
May 27, 7-8 AM (65)
May 27, 8-9 AM (38)
May 27, 9-10 AM (74)
May 27, 10-11 AM (83)
May 27, 11-12 PM (30)
May 27, 12-1 PM (50)
May 27, 1-2 PM (39)
May 27, 2-3 PM (53)
May 27, 3-4 PM (37)
May 27, 4-5 PM (11)
May 27, 5-6 PM (18)
May 27, 6-7 PM (21)
May 27, 7-8 PM (25)
May 27, 8-9 PM (17)
May 27, 9-10 PM (15)
May 27, 10-11 PM (29)
May 27, 11-12 AM (27)
May 28, 12-1 AM (9)
May 28, 1-2 AM (3)
May 28, 2-3 AM (5)
May 28, 3-4 AM (2)
May 28, 4-5 AM (9)
May 28, 5-6 AM (34)
May 28, 6-7 AM (31)
May 28, 7-8 AM (84)
May 28, 8-9 AM (33)
May 28, 9-10 AM (54)
May 28, 10-11 AM (50)
May 28, 11-12 PM (21)
May 28, 12-1 PM (46)
May 28, 1-2 PM (50)
May 28, 2-3 PM (23)
May 28, 3-4 PM (43)
May 28, 4-5 PM (86)
May 28, 5-6 PM (13)
May 28, 6-7 PM (31)
May 28, 7-8 PM (43)
May 28, 8-9 PM (34)
May 28, 9-10 PM (17)
May 28, 10-11 PM (36)
May 28, 11-12 AM (32)
May 29, 12-1 AM (12)
May 29, 1-2 AM (13)
May 29, 2-3 AM (4)
May 29, 3-4 AM (3)
May 29, 4-5 AM (0)
May 29, 5-6 AM (2)
May 29, 6-7 AM (5)
May 29, 7-8 AM (16)
May 29, 8-9 AM (37)
May 29, 9-10 AM (34)
May 29, 10-11 AM (69)
May 29, 11-12 PM (25)
May 29, 12-1 PM (44)
May 29, 1-2 PM (66)
May 29, 2-3 PM (60)
May 29, 3-4 PM (25)
May 29, 4-5 PM (26)
May 29, 5-6 PM (79)
May 29, 6-7 PM (11)
May 29, 7-8 PM (19)
May 29, 8-9 PM (9)
May 29, 9-10 PM (8)
May 29, 10-11 PM (27)
May 29, 11-12 AM (7)
May 30, 12-1 AM (8)
May 30, 1-2 AM (1)
May 30, 2-3 AM (1)
May 30, 3-4 AM (3)
May 30, 4-5 AM (2)
May 30, 5-6 AM (11)
May 30, 6-7 AM (0)
May 30, 7-8 AM (2)
May 30, 8-9 AM (11)
May 30, 9-10 AM (13)
May 30, 10-11 AM (10)
May 30, 11-12 PM (5)
May 30, 12-1 PM (8)
May 30, 1-2 PM (1)
3,689 commits this week May 23, 2026 - May 30, 2026
Sender-side idempotency via etcd Txn on mod_revision
Wraps each broadcast 'put' in a Txn:

  compare mod_revision(msg-<host>) == lastModRev
  success: put(msg-<host>, value)
  failure: range(msg-<host>)

A retry whose original committed server-side (which happens when the
original 'put' returned GrpcDeadlineExceeded to the client but had
already been processed) hits the failure branch — mod_revision has
advanced past lastModRev — so no second put runs, and the watcher on
each peer never sees a duplicate revision. The range result lets us
adopt the actual mod_revision as our new baseline and move on.

A legitimately new logical broadcast (same key, possibly even same
content) presents a new compare attempt against the up-to-date
lastModRev, the success branch runs, and a new revision is created
exactly once.

Single key per peer; no etcd disk-space regression versus master.

Previous attempts at this:
- Receiver-side content dedup: wrong because Hydra legitimately
  re-broadcasts identical content for resubmits (e.g. 'can submit a
  timed tx' in hydra-cluster).
- Unique-per-cycle key with createRevision==0 CAS: correct but grew
  the etcd keyspace unboundedly.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
feat(trp): populate reference script expression in TRP UTxO mapping
`into_tx3_utxo` previously hardcoded `script: None`, so reference scripts
attached to resolved UTxOs never reached the tx3 compiler. The raw UTxO
CBOR already carries the reference script, so decode it via
`MultiEraOutput::script_ref()` and map it to `Expression::Bytes`.

The full tagged `ScriptRef` CBOR (`[tag, body]`) is preserved so the
compiler can read the script's Plutus language directly from the tag;
storing only the inner script body would drop the language tag.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Sender-side idempotency for etcd put retries
broadcastMessages used to write each peer's outbound message to a single
fixed key (msg-<host>) and unconditionally retry on GrpcDeadlineExceeded.
Under heavy packet loss, the original put often committed server-side
before the deadline expired, so the retry produced a second etcd
revision with identical content. The watcher delivered the message
twice; HeadLogic processed it twice; the second pass emitted TxInvalid
with "All inputs are spent. Transaction has probably already been
included" — surfacing as numberOfInvalidTxs > 0 in the bench harness
under pumba 90% loss.

A receiver-side content dedup is fundamentally wrong: Hydra
legitimately re-broadcasts identical content (e.g.
'can submit a timed tx' resubmits after the validity window opens), and
those repeats are indistinguishable from transport retries at the watch
layer.

This fix moves dedup to the sender. Each broadcastMessages instance
picks a per-process nonce from POSIX time at startup, plus a sequence
counter. Each cycle writes msg-<host>-<nonce>-<seq>, and uses an etcd
Txn conditioned on createRevision(key) == 0. Retries within a cycle
reuse the same (nonce, seq) pair, so the second put becomes a CAS
no-op — no new revision, no duplicate watch event. Distinct cycles get
distinct seqs and deliver normally. The nonce keeps a restarted node
from colliding with keys it wrote in a previous lifetime that still
live in etcd.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
fix(generate-release-changelog-links): replace turtle with plain IO
turtle ^>= 1.6.x requires optparse-applicative < 0.19, conflicting with
the rest of the project. allow-newer would satisfy the solver but turtle
1.6.x fails to compile against 0.19 because of the breaking Doc type
change (ansi-wl-pprint -> prettyprinter).

Replace turtle usage with standard IO:
- Shell monad -> plain list IO with mapM/concat
- options/optPath/argPath/argText -> execParser/strOption/argument directly
- Pattern URL parser -> Text.breakOn/stripPrefix in Maybe monad
- printf/format -> Text concatenation and hPutStrLn stderr
- die -> exitFailure helper

Also drops foldl and prettyprinter which were only needed via turtle.
chore(deps): Bump google.golang.org/api from 0.267.0 to 0.282.0
Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.267.0 to 0.282.0.
- [Release notes](https://github.com/googleapis/google-api-go-client/releases)
- [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md)
- [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.267.0...v0.282.0)

---
updated-dependencies:
- dependency-name: google.golang.org/api
  dependency-version: 0.274.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): Bump go.opentelemetry.io/otel/sdk from 1.40.0 to 1.43.0
Bumps [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) from 1.40.0 to 1.43.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.40.0...v1.43.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/sdk
  dependency-version: 1.43.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): Bump github.com/go-playground/validator/v10
Bumps [github.com/go-playground/validator/v10](https://github.com/go-playground/validator) from 10.30.1 to 10.30.3.
- [Release notes](https://github.com/go-playground/validator/releases)
- [Commits](https://github.com/go-playground/validator/compare/v10.30.1...v10.30.3)

---
updated-dependencies:
- dependency-name: github.com/go-playground/validator/v10
  dependency-version: 10.30.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): Bump docker/build-push-action from 7.0.0 to 7.2.0
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 7.0.0 to 7.2.0.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/d08e5c354a6adb9ed34480a06d141179aa583294...f9f3042f7e2789586610d6e8b85c8f03e5195baf)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: 7.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
chore(deps): Bump actions/github-script from 8.0.0 to 9.0.0 (#484)
Bumps [actions/github-script](https://github.com/actions/github-script) from 8.0.0 to 9.0.0.
- [Release notes](https://github.com/actions/github-script/releases)
- [Commits](https://github.com/actions/github-script/compare/ed597411d8f924073f98dfc5c65a23a2325f34cd...3a2844b7e9c422d3c10d287c895573f7108da1b3)

---
updated-dependencies:
- dependency-name: actions/github-script
  dependency-version: 9.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
chore(deps): Bump go.opentelemetry.io/otel from 1.40.0 to 1.41.0 (#487)
Bumps [go.opentelemetry.io/otel](https://github.com/open-telemetry/opentelemetry-go) from 1.40.0 to 1.41.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.40.0...v1.41.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel
  dependency-version: 1.41.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
chore(deps): Bump webiny/action-conventional-commits from 1.3.1 to 1.4.2 (#488)
Bumps [webiny/action-conventional-commits](https://github.com/webiny/action-conventional-commits) from 1.3.1 to 1.4.2.
- [Release notes](https://github.com/webiny/action-conventional-commits/releases)
- [Commits](https://github.com/webiny/action-conventional-commits/compare/faccb24fc2550dd15c0390d944379d2d8ed9690e...7f91b1595ca1951cdb671ddc9f07a49081ec5b69)

---
updated-dependencies:
- dependency-name: webiny/action-conventional-commits
  dependency-version: 1.4.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
chore(deps): Bump github.com/blinklabs-io/gouroboros (#480)
Bumps [github.com/blinklabs-io/gouroboros](https://github.com/blinklabs-io/gouroboros) from 0.160.3 to 0.179.0.
- [Release notes](https://github.com/blinklabs-io/gouroboros/releases)
- [Changelog](https://github.com/blinklabs-io/gouroboros/blob/main/RELEASE_NOTES.md)
- [Commits](https://github.com/blinklabs-io/gouroboros/compare/v0.160.3...v0.179.0)

---
updated-dependencies:
- dependency-name: github.com/blinklabs-io/gouroboros
  dependency-version: 0.163.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
build(deps): bump github.com/blinklabs-io/gouroboros (#198)
Bumps [github.com/blinklabs-io/gouroboros](https://github.com/blinklabs-io/gouroboros) from 0.170.1 to 0.179.0.
- [Release notes](https://github.com/blinklabs-io/gouroboros/releases)
- [Changelog](https://github.com/blinklabs-io/gouroboros/blob/main/RELEASE_NOTES.md)
- [Commits](https://github.com/blinklabs-io/gouroboros/compare/v0.170.1...v0.179.0)

---
updated-dependencies:
- dependency-name: github.com/blinklabs-io/gouroboros
  dependency-version: 0.171.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>