Tags: 0xPolygon/polygon-cli
Tags
fix(p2p/sensor): avoid shadowing err in deferred Close Rename the inner err in the deferred db.Close() (sensor.go) and the test's Close check to cerr so `shadow` (go vet) stops flagging them. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(docker): install arm64 target libc headers for the cross build (#964 ) * fix(docker): install arm64 target libc headers for the cross build The slim golang image ships gcc-aarch64-linux-gnu's runtime libs but not the arm64 libc dev headers, so the CGO cross-compile failed with `bits/libc-header-start.h: No such file`. Add libc6-dev-arm64-cross, which provides the aarch64 sysroot headers. Verified by reproducing the amd64->arm64 cross-compile under emulation (fails without, CROSS_OK with). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(docker): sort apt package names alphanumerically Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat: publish a polycli container image to GHCR on tag (#963) * feat: publish a polycli container image to GHCR on tag Add a Dockerfile and a GitHub Actions workflow that builds and pushes a multi-arch (linux/amd64, linux/arm64) polycli image to ghcr.io/0xPolygon/polygon-cli on every tag, mirroring the panoptichain setup. CGO is enabled (vectorized-poseidon-gold has no pure-Go path); buildx builds each platform natively under QEMU. Runtime is distroless/base (glibc). Enables running `polycli p2p sensor` as a container (e.g. the sensor VMs on Container-Optimized OS), removing the build-from-source/ansible step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * build(docker): use the Makefile build target for version stamping Dockerfile now runs `make build` instead of a bare `go build`, so the image binary is version-stamped the same as a local build (git describe / commit / date) rather than reporting "dev". Requires make in the builder and fetch-depth: 0 in the publish workflow so `git describe --tags` sees the tags. Verified: `docker run <img> version` -> "Polygon CLI Version v0.1.115-9-g...". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * build(docker): cross-compile static image, fix nonroot /data writes - Cross-compile on the native BUILDPLATFORM (mirroring the release `make cross` setup) instead of per-platform QEMU builds, via a new `docker-build` Makefile target that reuses VERSION_FLAGS. Ship the fully static binary on distroless/static (~119MB -> ~59MB). - Own the /data working dir as the nonroot uid (65532) so the sensor can write its nodes.json discovery cache. - Restrict the publish trigger to v* tags so ad-hoc tags can't move `latest`; drop the now-unneeded QEMU setup; share Go build/module cache mounts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(p2p/sensor): validate block signer before rebroadcast (#946) * feat(p2p/sensor): validate block signer before rebroadcast When block rebroadcasting is enabled, the sensor now only rebroadcasts blocks whose recovered signer is in the current Heimdall validator set. Blocks from unknown signers are still persisted and their bodies are still requested; they are simply not propagated to peers. - Add ValidatorSet (p2p/validators.go): fetches /stake/validators-set from Heimdall, blocking initial load + periodic refresh, IsAuthorized. - Add Conns.IsKnownSigner to gate rebroadcast by recovered signer. - Gate handleNewBlock; defer block-hash rebroadcast from handleNewBlockHashes to handleBlockHeaders so the fetched header can be validated first (body requests stay ungated). - Consolidate util.Ecrecover to take *types.Header. - Add --heimdall-url and --validator-set-refresh sensor flags. * chore: go fmt * feat(p2p/sensor): add validate/cache flags and gate serving by signer Refine the block signer validation feature: - Rename SignerSet -> ValidatorSet and IsAuthorized -> HasSigner; add RecoverSigner which returns the recovered address so skip paths can log it. - Add --validate-block-signer (default true) to toggle signer validation. - Add --cache-only-validated-blocks (default true): unknown-signer blocks are still recorded to the database but are no longer retained in or served from the in-memory cache (GetBlockHeaders/GetBlockBodies/RPC), and cannot evict legitimate blocks. - Make block-hash rebroadcast conditional: immediate when validation is off, deferred to handleBlockHeaders (validate first) when on. - Emit rich debug logs (signer, peer, block info) when a block is not rebroadcast. * refactor(p2p): reduce cognitive complexity of block handlers Extract helpers to bring handleBlockHeaders, handleBlockBodies, and handleNewBlock under the SonarQube cognitive-complexity threshold, without changing behavior: - cacheAndAnnounceHeader: per-header caching + deferred hash rebroadcast. - buildBlockBody: RLP decode/re-encode of a block body. - cacheFullBlock: validated full-block cache store + first-seen write. * fix(p2p): retain block body across header/body response reordering Under --cache-only-validated-blocks, the body was cached only if a header was already present, so a body response arriving before its header (eth does not guarantee ordering) was dropped and never re-fetched — leaving a header-only entry even for valid-validator blocks, which then couldn't be served on GetBlockBodies. - handleBlockBodies: retain the body whenever a cache entry exists (the announcement marker), holding a body-first response provisionally instead of dropping it. - cacheAndAnnounceHeader: evict the entry when the header's signer is unknown, dropping any provisionally-held body. - handleGetBlockBodies: serve a body only when its (validated) header is also cached, so provisional bodies are never served before validation. DB persistence is unchanged; bodies are still written for every block. * fix(p2p): re-fetch announced blocks until the full block is obtained handleNewBlockHashes deduped on any cache marker, so only the first peer to announce a hash triggered getBlockData. If that peer never served the header/body there was no retry — leaving a permanent hash-only marker that the block-latency report counts as "missing", even though other peers were announcing the same block. Skip only when we already hold the full block; otherwise re-fetch from the announcing peer. First-seen/event writes stay first-announcer-only; getBlockData requests just the missing parts, and it self-bounds once the block is complete. Add p2p handler/validator tests (new p2p/protocol_test.go, p2p/validators_test.go): - re-fetch on re-announce until complete - body-before-header reorder retains the body - GetBlockBodies serves only complete (header+body) entries - ValidatorSet start/refresh/HasSigner and Conns.RecoverSigner
ci: build and publish macOS release binaries (#947) Add a cross-darwin Makefile target and a macos-release workflow job that builds darwin binaries natively on macOS runners. A CGO-only transitive dependency (vectorized-poseidon-gold) prevents cross-compiling darwin from the linux runner, so each architecture is built on its own runner: macos-13 (Intel/amd64) and macos-14 (Apple Silicon/arm64). Co-authored-by: Cursor <cursoragent@cursor.com>
fix: skip fetching transactions already in cache (#919) Filter out transaction hashes that are already cached before sending GetPooledTransactions requests. This avoids redundant network fetches when multiple peers announce the same transactions.
fix(p2p/sensor): improve transaction writing consistency (#909) * fix: improve p2p sensor transaction writing consistency - Change handleNewPooledTransactionHashes condition from || to && so transactions are requested when either --write-txs or --write-tx-events is enabled (previously required both) - Preserve earliest TimeFirstSeen for transactions by checking existing records before writing, matching block behavior - Skip writing transactions that already exist with earlier timestamp - Add --write-first-tx-event flag for write-first-event-only behavior - Add SensorFirstSeen field to DatastoreTransaction for sensor attribution * feat: add worker pool for transaction writes and cache-first deduplication - Add fixed worker pool (default 100 workers) for transaction and transaction event writes using unbounded linked list queue - Check transaction cache before writing to deduplicate across peers - Add Close() method to Database interface for graceful shutdown - Add --write-workers flag to configure worker count - Keep semaphore pattern for block writes (lower volume) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: revert to semaphore pattern for transaction writes Remove the worker pool implementation and revert to the original semaphore pattern for database writes. The cache-first transaction deduplication (added in previous commit) should significantly reduce write volume, making the simpler semaphore pattern sufficient. Changes: - Remove worker pool types, queue, and worker goroutines from datastore.go - Remove WriteWorkers from DatastoreOptions - Remove --write-workers flag from sensor command - Keep using runAsync() semaphore pattern for all database writes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: go fmt * fix: reduce indexes * refactor: remove unused Close() method from Database interface The Close() method was added for the worker pool implementation but is no longer needed after reverting to the semaphore pattern. With the semaphore pattern, in-flight goroutines complete on their own without needing explicit shutdown coordination. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: extract processTransactions helper to reduce duplication - Extract common transaction processing logic into processTransactions() - Consolidates duplicate code from handleTransactions and handlePooledTransactions - Remove orphaned comment about Close() method - Remove duplicate WriteTransactions comment Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
fix: pos exit proof non power of 2 merkle (#908) * fix(pos exit-proof): pad merkle leaves to power of 2 Polygon's matic-js MerkleTree (and the pos-contracts / pos-portal test helpers it mirrors) builds a complete fixed-depth binary tree by padding the leaf layer with zero hashes to the next power of 2. The on-chain verifier (pos-contracts/contracts/common/lib/Merkle.sol checkMembership) requires that exact shape — it asserts index < 2^proofHeight and walks a fixed-depth tree. merkleProof was instead duplicating the last node per layer when an odd count was reached. That coincidentally matches matic-js when the leaf count is already a power of 2 (mainnet's 128-block checkpoints), so the bug never surfaced in production. On a fast-cadence devnet validators sometimes submit checkpoint ranges that aren't powers of 2 (e.g. 40 blocks), and the resulting tree root differs from L1's stored headerRoot — startExitWithBurntTokens then reverts with WITHDRAW_BLOCK_NOT_A_PART_OF_SUBMITTED_HEADER. Pad once at the leaf layer to the next power of 2 with zero hashes, then build cleanly. Adds cmd_test.go with an independent reproduction of the on-chain verifier and a regression case at 40 leaves. * chore(pos exit-proof): drop merkle test file
chore: bump google.golang.org/api from 0.274.0 to 0.275.0 (#898) Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.274.0 to 0.275.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](googleapis/google-api-go-client@v0.274.0...v0.275.0) --- updated-dependencies: - dependency-name: google.golang.org/api dependency-version: 0.275.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
chore: bump github.com/ethereum/go-ethereum from 1.16.8 to 1.17.0 in … …the go_modules group across 1 directory (#857) * chore: bump github.com/ethereum/go-ethereum Bumps the go_modules group with 1 update in the / directory: [github.com/ethereum/go-ethereum](https://github.com/ethereum/go-ethereum). Updates `github.com/ethereum/go-ethereum` from 1.16.8 to 1.17.0 - [Release notes](https://github.com/ethereum/go-ethereum/releases) - [Commits](ethereum/go-ethereum@v1.16.8...v1.17.0) --- updated-dependencies: - dependency-name: github.com/ethereum/go-ethereum dependency-version: 1.17.0 dependency-type: direct:production dependency-group: go_modules ... Signed-off-by: dependabot[bot] <support@github.com> * fix: update p2p package for go-ethereum 1.17.0 RawList API changes go-ethereum 1.17.0 changed eth protocol types to use rlp.RawList for lazy decoding optimization: - BlockHeadersPacket.List replaces BlockHeadersRequest - BlockBodiesPacket.List replaces BlockBodiesResponse - PooledTransactionsPacket.List replaces PooledTransactionsResponse - BlockBody fields now use rlp.RawList instead of slices - TransactionsPacket embeds rlp.RawList Updated all p2p code to use .Len() instead of len(), .Items() for decoding, and rlp.EncodeToRawList() for encoding. --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Minh Vu <mvu@polygon.technology>
PreviousNext