mirror of
https://github.com/OffchainLabs/prysm.git
synced 2026-01-08 04:54:05 -05:00
<!-- Thanks for sending a PR! Before submitting: 1. If this is your first PR, check out our contribution guide here https://docs.prylabs.network/docs/contribute/contribution-guidelines You will then need to sign our Contributor License Agreement (CLA), which will show up as a comment from a bot in this pull request after you open it. We cannot review code without a signed CLA. 2. Please file an associated tracking issue if this pull request is non-trivial and requires context for our team to understand. All features and most bug fixes should have an associated issue with a design discussed and decided upon. Small bug fixes and documentation improvements don't need issues. 3. New features and bug fixes must have tests. Documentation may need to be updated. If you're unsure what to update, send the PR, and we'll discuss in review. 4. Note that PRs updating dependencies and new Go versions are not accepted. Please file an issue instead. 5. A changelog entry is required for user facing issues. --> **What type of PR is this?** Design Doc **What does this PR do? Why is it needed?** This PR adds a design doc for adding graffiti. The idea is to have it populated judiciously so that we can get proper information about the EL, CL and their corresponding version info. At the same time being flexible enough with the user input. **Which issues(s) does this PR fix?** Fixes # **Other notes for review** **Acknowledgements** - [x] I have read [CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md). - [x] I have included a uniquely named [changelog fragment file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd). - [x] I have added a description to this PR with sufficient context for reviewers to understand this PR.
3.5 KiB
3.5 KiB
Graffiti Version Info Implementation
Summary
Add automatic EL+CL version info to block graffiti following ethereum/execution-apis#517. Uses the flexible standard to pack client info into leftover space after user graffiti.
More details: https://github.com/ethereum/execution-apis/blob/main/src/engine/identification.md
Implementation
Core Component: GraffitiInfo Struct
Thread-safe struct holding version information:
const clCode = "PR"
type GraffitiInfo struct {
mu sync.RWMutex
userGraffiti string // From --graffiti flag (set once at startup)
clCommit string // From version.GetCommitPrefix() helper function
elCode string // From engine_getClientVersionV1
elCommit string // From engine_getClientVersionV1
}
Flow
- Startup: Parse flags, create GraffitiInfo with user graffiti and CL info.
- Wiring: Pass struct to both execution service and RPC validator server
- Runtime: Execution service goroutine periodically calls
engine_getClientVersionV1and updates EL fields - Block Proposal: RPC validator server calls
GenerateGraffiti()to get formatted graffiti
Flexible Graffiti Format
Packs as much client info as space allows (after user graffiti):
| Available Space | Format | Example |
|---|---|---|
| ≥12 bytes | EL(2)+commit(4)+CL(2)+commit(4)+user |
GE168dPR63afBob |
| 8-11 bytes | EL(2)+commit(2)+CL(2)+commit(2)+user |
GE16PR63my node here |
| 4-7 bytes | EL(2)+CL(2)+user |
GEPRthis is my graffiti msg |
| 2-3 bytes | EL(2)+user |
GEalmost full graffiti message |
| <2 bytes | user only | full 32 byte user graffiti here |
func (g *GraffitiInfo) GenerateGraffiti() [32]byte {
available := 32 - len(userGraffiti)
if elCode == "" {
elCommit2 = elCommit4 = ""
}
switch {
case available >= 12:
return elCode + elCommit4 + clCode + clCommit4 + userGraffiti
case available >= 8:
return elCode + elCommit2 + clCode + clCommit2 + userGraffiti
case available >= 4:
return elCode + clCode + userGraffiti
case available >= 2:
return elCode + userGraffiti
default:
return userGraffiti
}
}
Update Logic
Single testable function in execution service:
func (s *Service) updateGraffitiInfo() {
versions, err := s.GetClientVersion(ctx)
if err != nil {
return // Keep last good value
}
if len(versions) == 1 {
s.graffitiInfo.UpdateFromEngine(versions[0].Code, versions[0].Commit)
}
}
Goroutine calls this on slot % 8 == 4 timing (4 times per epoch, avoids slot boundaries).
Files Changes Required
New:
beacon-chain/execution/graffiti_info.go- The struct and methodsbeacon-chain/execution/graffiti_info_test.go- Unit testsruntime/version/version.go- AddGetCommitPrefix()helper that extracts first 4 hex chars from the git commit injected via Bazel ldflags at build time
Modified:
beacon-chain/execution/service.go- Add goroutine + updateGraffitiInfo()beacon-chain/execution/engine_client.go- Add GetClientVersion() method that does engine callbeacon-chain/rpc/.../validator/proposer.go- Call GenerateGraffiti()beacon-chain/node/node.go- Wire GraffitiInfo to services
Testing Strategy
- Unit test GraffitiInfo methods (priority logic, thread safety)
- Unit test updateGraffitiInfo() with mocked engine client