diff --git a/BAPs/BAP-578.md b/BAPs/BAP-578.md new file mode 100644 index 00000000..c22e8c30 --- /dev/null +++ b/BAPs/BAP-578.md @@ -0,0 +1,610 @@ +``` +BAP: 578 +Title: Non-Fungible Agent (NFA) Token Standard +Status: Draft +Type: Application +Created: 2025-05-27 +``` + +# BAP-578: Non-Fungible Agent (NFA) Token Standard + +- [BAP-578: Non-Fungible Agent (NFA) Token Standard] + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [3.1 The Need for Standardization](#31-the-need-for-standardization) + - [3.2 Current Ecosystem Challenges](#32-current-ecosystem-challenges) + - [3.3 Hybrid Architecture Benefits](#33-hybrid-architecture-benefits) + - [4. Specification](#4-specification) + - [4.1 Core Interface](#41-core-interface) + - [4.2 Agent State Management](#42-agent-state-management) + - [4.3 Enhanced Metadata Schema](#43-enhanced-metadata-schema) + - [4.4 Learning Module System](#44-learning-module-system) + - [4.5 Memory Module Registry](#45-memory-module-registry) + - [4.6 Vault Permission System](#46-vault-permission-system) + - [4.7 Security Mechanisms](#47-security-mechanisms) + - [4.8 Agent Templates](#48-agent-templates) + - [4.9 Dual-Path Architecture](#49-dual-path-architecture) + - [5. Rationale](#5-rationale) + - [6. Backwards Compatibility](#6-backwards-compatibility) + - [7. Test Cases](#7-test-cases) + - [8. Implementation](#8-implementation) + - [9. Security Considerations](#9-security-considerations) + - [10. License](#10-license) + +## 1. Summary + +This BNB Chain Application (BAP) proposal, BAP-578, introduces the Non-Fungible Agent (NFA) token standard, extending ERC-721 to enable autonomous, intelligent digital entities with optional learning capabilities on BNB Chain. The standard provides a dual-path architecture supporting both traditional static agents and advanced learning-enabled agents, ensuring broad adoption while enabling cutting-edge AI capabilities. + +A reference implementation is available [here](https://github.com/ChatAndBuild/non-fungible-agents-BAP-578) + +## 2. Abstract + +BAP-578 defines a standardized framework for Non-Fungible Agents (NFAs) - intelligent, autonomous digital entities that combine the ownership guarantees of NFTs with the adaptive capabilities of artificial intelligence. This standard merges the uniqueness of NFTs with autonomous functionality, positioning BNB Chain as the home for decentralized automation. + +The standard addresses the critical gap between traditional NFTs (which provide uniqueness and ownership) and the need for standardized interfaces that enable autonomous behavior and cross-platform agent interactions. BAP-578 provides a complete framework for creating, managing, and governing autonomous agent tokens with optional learning capabilities that allow agents to evolve and improve over time. + + + +Key features include: +- **Dual-Path Architecture**: Support for both JSON Light Memory (simple agents) and Merkle Tree Learning (evolving agents) + +- **Cryptographically verfiable learning through Merkle Proofs**: +- NFAs employ a **method-agnostic architecture** that enables cryptographically verifiable learning through Merkle tree structures. +- When users interact with an NFA, learning data, including preferences, patterns, confidence scores, and outcomes, is organized into a hierarchical tree structure. +- This data progresses through a systematic process: interaction → learning extraction → tree building → Merkle root calculation → on-chain update. +- Only the 32-byte Merkle root is stored on-chain, providing tamper-proof verification while preserving privacy and minimizing storage costs. +- The **flexible learning module architecture** allows developers to implement various AI optimization methods. +- Whether using **RAG**(leveraging off-chain vaults to retrieve past interactions), **MCP** (integrating with different AI providers through logic contracts), **fine-tuning, reinforcement learning, or hybrid approaches**, the BAP-578 standard provides the infrastructure without prescribing specific implementations. + +- **Standardized Agent Lifecycle**: Comprehensive lifecycle management from creation through evolution +- **Hybrid Storage Model**: On-chain security with off-chain flexibility for rich experiences +- **Composable Intelligence**: Agents can interact and collaborate while maintaining individual identity +- **Comprehensive Security**: Multi-layer security framework with circuit breakers and access controls +- **Backward Compatibility**: Full compatibility with existing ERC-721 infrastructure + +## 3. Motivation + +### 3.1 The Need for Standardization + +While traditional NFTs (BEP-721) provide uniqueness and ownership, they lack the standardized interfaces needed for autonomous behavior and cross-platform agent interactions. The current blockchain ecosystem lacks standardization for intelligent, autonomous digital entities, creating several critical challenges that BAP-578 addresses. + +#### 3.1.1 Consistent Agent Interfaces +BAP-578 defines standardized methods for action execution, state management, and logic upgrades that enable predictable interactions across platforms. Without this standardization, every intelligent token implementation requires custom integration work, forcing developers to learn new APIs and build specialized infrastructure for each project. + +#### 3.1.2 Interoperability Framework +The standard establishes common patterns for how agents interact with other contracts, services, and each other, creating an ecosystem where agents from different developers can work together. This prevents the creation of isolated ecosystems that limit user choice and prevent network effects that drive innovation. + +#### 3.1.3 Hybrid On-Chain/Off-Chain Architecture +BAP-578 provides clear separation between on-chain identity and permissions versus off-chain extended memory and complex behaviors, optimizing for both gas efficiency and rich functionality. This hybrid approach ensures that critical security and identity information is secured by blockchain consensus while keeping gas costs reasonable for agent operations. + +#### 3.1.4 Optional Learning System +The standard includes standardized interfaces for agent learning and evolution, allowing developers to choose between simple static agents or sophisticated learning agents. This addresses the lack of learning standardization that has made it impossible for agents to share knowledge or for the ecosystem to benefit from collective intelligence. + +#### 3.1.5 Security Boundaries +BAP-578 establishes standardized circuit breaker patterns, permission systems, and access controls that protect users and their assets, replacing the patchwork of security models that are difficult to audit and trust. + +### 3.2 Current Ecosystem Challenges + +#### 3.2.1 Integration Complexity +Every intelligent token implementation requires custom integration work, significantly increasing development costs and time-to-market. Developers must learn new APIs and build specialized infrastructure for each project, preventing the ecosystem from benefiting from shared infrastructure. + +#### 3.2.2 Limited Interoperability +Agents created on one platform cannot easily interact with agents from other platforms, creating isolated ecosystems that limit user choice and prevent network effects that drive innovation. + +#### 3.2.3 Inconsistent Security Models +Each implementation uses different approaches to permissions and security, creating a patchwork of security models that are difficult to audit and trust. + +#### 3.2.4 User Lock-in +Users become locked into specific platforms, unable to migrate their intelligent agents or leverage their accumulated learning across different applications. + +#### 3.2.5 Lack of Learning Portability +There has been no standardized approach to enabling agents to learn and evolve, making it impossible for agents to carry their knowledge and experience across different platforms and applications. + +### 3.3 Hybrid Architecture Benefits + +BAP-578 carefully balances which components belong on-chain versus off-chain to optimize for security, cost-effectiveness, and functionality: + +| Component | Storage | Rationale | +|-----------|---------|-----------| +| Agent Identity | On-chain | Core identity must be immutable and universally accessible | +| Ownership & Permissions | On-chain | Security and access control require consensus verification | +| Basic Metadata | On-chain | Essential for marketplace display and basic interactions | +| Logic Address | On-chain | Determines how the agent behaves when actions are executed | +| Learning Tree Root | On-chain | Cryptographic proof of learning state (32 bytes only) | +| Extended Memory | Off-chain (with hash verification) | Rich memory would be prohibitively expensive on-chain | +| Learning Tree Data | Off-chain (with Merkle verification) | Detailed learning data with cryptographic integrity | +| Complex Behaviors | Off-chain | Advanced AI behaviors require off-chain computation | +| Voice/Animation | Off-chain (with URI reference) | Media assets are too large for on-chain storage | + +This hybrid approach ensures that: +- Critical security and identity information is secured by blockchain consensus +- Gas costs remain reasonable for agent operations +- Rich agent experiences can evolve without blockchain limitations +- Learning capabilities are cryptographically verifiable yet cost-efficient + +BAP-578 addresses these challenges by providing: +- **Universal Compatibility**: Standardized interfaces that work across all platforms +- **User Ownership**: True ownership of intelligent agents and their accumulated knowledge +- **Ecosystem Interoperability**: Agents that maintain consistent behavior across applications +- **Innovation Acceleration**: Shared infrastructure that enables focus on unique value creation +- **Future-Ready Design**: Architecture that supports both current needs and future AI advances + +## 4. Specification + +### 4.1 Core Interface + +![BAP-578 Non-Fungible Agents](https://raw.githubusercontent.com/christelbuchanan/bap-578-non-fungible-agents-nfa/52c17583d32ddbb24d4dcadedafc1a2516f1015b/BAP-578.jpg) + +The BAP-578 standard extends ERC-721 with agent-specific functionality: + +```solidity +interface IBAP578 { + enum Status { Active, Paused, Terminated } + + struct State { + uint256 balance; + Status status; + address owner; + address logicAddress; + uint256 lastActionTimestamp; + } + + struct AgentMetadata { + string persona; // JSON-encoded character traits + string experience; // Agent's role/purpose summary + string voiceHash; // Audio profile reference + string animationURI; // Animation/avatar URI + string vaultURI; // Extended data storage URI + bytes32 vaultHash; // Vault content verification hash + } + + // Events + event ActionExecuted(address indexed agent, bytes result); + event LogicUpgraded(address indexed agent, address oldLogic, address newLogic); + event AgentFunded(address indexed agent, address indexed funder, uint256 amount); + event StatusChanged(address indexed agent, Status newStatus); + event MetadataUpdated(uint256 indexed tokenId, string metadataURI); + + // Core Functions + function executeAction(uint256 tokenId, bytes calldata data) external; + function setLogicAddress(uint256 tokenId, address newLogic) external; + function fundAgent(uint256 tokenId) external payable; + function getState(uint256 tokenId) external view returns (State memory); + function getAgentMetadata(uint256 tokenId) external view returns (AgentMetadata memory); + function updateAgentMetadata(uint256 tokenId, AgentMetadata memory metadata) external; + + // Lifecycle Management + function pause(uint256 tokenId) external; + function unpause(uint256 tokenId) external; + function terminate(uint256 tokenId) external; +} +``` + +### 4.2 Agent State Management + +Agents maintain state information that tracks their operational status, balance, and activity: + +```solidity +struct State { + uint256 balance; // BNB balance for gas fees + Status status; // Current operational status + address owner; // Agent owner address + address logicAddress; // Logic contract address + uint256 lastActionTimestamp; // Last action execution time +} +``` + +**Status Management:** +- `Active`: Agent can execute actions and interact normally +- `Paused`: Agent is temporarily suspended but can be resumed +- `Terminated`: Agent is permanently disabled with balance returned to owner + +### 4.3 Enhanced Metadata Schema + +BAP-578 extends standard ERC-721 metadata with agent-specific fields to support both simple and learning agents: + +#### 4.3.1 Core Agent Metadata +```solidity +struct AgentMetadata { + string persona; // JSON-encoded character traits, style, tone + string experience; // Short summary of agent's role/purpose + string voiceHash; // Reference ID to stored audio profile + string animationURI; // URI to video or animation file + string vaultURI; // URI to agent's vault (extended data storage) + bytes32 vaultHash; // Hash of vault contents for verification +} +``` + +#### 4.3.2 Enhanced Learning Metadata (Optional Extension) +```solidity +struct EnhancedAgentMetadata { + // Core fields (inherited from AgentMetadata) + string persona; + string experience; + string voiceHash; + string animationURI; + string vaultURI; + bytes32 vaultHash; + + // Learning-specific fields + bool learningEnabled; // Learning capability flag + address learningModule; // Learning module contract address + bytes32 learningTreeRoot; // Merkle root of learning tree + uint256 learningVersion; // Learning implementation version + uint256 lastLearningUpdate; // Timestamp of last learning update +} +``` + +### 4.4 Learning Module System + +The learning module system provides standardized interfaces for implementing different learning algorithms: + +#### 4.4.1 Learning Module Interface +```solidity +interface ILearningModule { + struct LearningMetrics { + uint256 totalInteractions; // Total user interactions + uint256 learningEvents; // Significant learning updates + uint256 lastUpdateTimestamp; // Last learning update time + uint256 learningVelocity; // Learning rate (scaled by 1e18) + uint256 confidenceScore; // Overall confidence (scaled by 1e18) + } + + struct LearningUpdate { + bytes32 previousRoot; // Previous Merkle root + bytes32 newRoot; // New Merkle root + bytes32 proof; // Merkle proof for update + bytes32 metadata; // Encoded learning data + } + + function updateLearning(uint256 tokenId, LearningUpdate calldata update) external; + function verifyLearning(uint256 tokenId, bytes32 claim, bytes32[] calldata proof) external view returns (bool); + function getLearningMetrics(uint256 tokenId) external view returns (LearningMetrics memory); + function getLearningRoot(uint256 tokenId) external view returns (bytes32); + function isLearningEnabled(uint256 tokenId) external view returns (bool); + function getVersion() external pure returns (string memory); + function recordInteraction(uint256 tokenId, string calldata interactionType, bool success) external; +} +``` + +#### 4.4.2 Merkle Tree Learning Implementation +Learning data is organized in a hierarchical tree structure with on-chain verification: + +- **On-Chain Storage**: Only the Merkle root (32 bytes) is stored on-chain +- **Off-Chain Storage**: Full learning tree stored in user-controlled vaults +- **Cryptographic Verification**: All learning claims verified through Merkle proofs +- **Gas Efficiency**: Minimal on-chain storage with full verification capabilities + +### 4.5 Memory Module Registry + +The memory module registry allows agents to register external memory sources: + +```solidity +interface IMemoryModuleRegistry { + struct MemoryModule { + address moduleAddress; + string metadata; + bytes32 metadataHash; + uint256 registrationTime; + bool isActive; + } + + function registerModule( + uint256 tokenId, + address moduleAddress, + string memory metadata, + bytes memory signature + ) external; + + function verifyModule( + uint256 tokenId, + address moduleAddress, + bytes32 expectedHash + ) external view returns (bool); + + function getModule(uint256 tokenId, address moduleAddress) + external view returns (MemoryModule memory); +} +``` + +### 4.6 Vault Permission System + +The vault permission system manages access to off-chain agent data: + +```solidity +interface IVaultPermissionManager { + enum PermissionLevel { READ_ONLY, WRITE, ADMIN, FULL_CONTROL } + + struct Permission { + address delegate; + PermissionLevel level; + uint256 expiryTime; + bool isActive; + } + + function delegateAccess( + uint256 tokenId, + address delegate, + PermissionLevel level, + uint256 expiryTime, + bytes memory signature + ) external; + + function revokeAccess(uint256 tokenId, address delegate) external; + function verifyAccess(uint256 tokenId, address accessor, PermissionLevel requiredLevel) + external view returns (bool); +} +``` + +### 4.7 Security Mechanisms + +#### 4.7.1 Circuit Breaker System +```solidity +interface ICircuitBreaker { + function pauseGlobally() external; + function pauseContract(address contractAddress) external; + function pauseAgent(uint256 tokenId) external; + function unpauseGlobally() external; + function unpauseContract(address contractAddress) external; + function unpauseAgent(uint256 tokenId) external; + + function isGloballyPaused() external view returns (bool); + function isContractPaused(address contractAddress) external view returns (bool); + function isAgentPaused(uint256 tokenId) external view returns (bool); +} +``` + +#### 4.7.2 Access Control +- **Owner-Only Operations**: Critical functions restricted to agent owner +- **Governance Controls**: System-wide parameters managed by governance +- **Time-Based Permissions**: Temporary access delegation with automatic expiry +- **Cryptographic Verification**: Signature-based verification for sensitive operations + +#### 4.7.3 Gas Limits +```solidity +uint256 public constant MAX_GAS_FOR_DELEGATECALL = 3000000; +uint256 public constant MAX_GAS_FOR_LEARNING_UPDATE = 500000; +``` + +### 4.8 Agent Templates + +BAP-578 includes a template system for specialized agent types: + +#### 4.8.1 Template Interface +```solidity +interface IAgentTemplate { + function getTemplateInfo() external view returns ( + string memory name, + string memory description, + uint256 version, + bytes32 codeHash + ); + + function initialize(uint256 tokenId, bytes memory initData) external; + function getCapabilities() external view returns (string[] memory); +} +``` + +#### 4.8.2 Available Templates +- **DeFiAgent**: Specialized for DeFi operations and trading +- **GameAgent**: Optimized for gaming and virtual world interactions +- **DAOAgent**: Designed for governance and DAO participation +- **CreatorAgent**: Focused on content creation and artistic endeavors +- **StrategicAgent**: Built for analysis and strategic decision-making + +### 4.9 Dual-Path Architecture + +BAP-578 offers two development paths to accommodate different use cases and developer preferences: + +#### 4.9.1 Path 1: JSON Light Memory (Default) +Perfect for most developers and immediate deployment: +- **Simple**: Familiar JSON metadata approach (like standard NFTs) +- **Fast**: Deploy agents immediately with no complexity +- **Compatible**: Works with all existing NFT infrastructure +- **Cost-effective**: Minimal gas costs for basic operations + +#### 4.9.2 Path 2: Merkle Tree Learning (Optional) +For advanced developers wanting truly evolving agents: +- **Evolving**: Agents that genuinely learn and improve over time +- **Provable**: Cryptographically verifiable learning history +- **Efficient**: Only 32-byte Merkle roots stored on-chain +- **Advanced**: Cutting-edge AI agent capabilities from day 1 + +#### 4.9.3 Key Benefits +- **Backward Compatibility**: All existing agents continue working unchanged +- **Optional Adoption**: Choose your complexity level +- **Upgrade Path**: Simple agents can enable learning later +- **Gas Optimized**: Learning data stored off-chain with on-chain verification +- **Future-Proof**: Architecture supports advanced AI developments + +## 5. Rationale + +### 5.1 Design Decisions + +#### 5.1.1 Dual-Path Architecture +The dual-path approach (JSON Light Memory vs. Merkle Tree Learning) ensures broad adoption by providing immediate utility while enabling advanced capabilities for users ready to embrace AI features. This design allows developers to start simple and upgrade to learning capabilities when needed. + +#### 5.1.2 Hybrid Storage Model +Storing critical identity on-chain while keeping detailed data off-chain optimizes for both security and cost-effectiveness. This approach ensures that essential security and identity information is secured by blockchain consensus while keeping gas costs reasonable for agent operations. + +#### 5.1.3 Modular Learning System +Pluggable learning modules allow for different algorithms and future upgrades without breaking existing functionality. This modularity enables the ecosystem to evolve and adopt new learning techniques as they become available. + +#### 5.1.4 Merkle Tree Learning +Using Merkle trees for learning data provides cryptographic verification while minimizing on-chain storage costs. This approach enables verifiable learning with only 32 bytes of on-chain storage per agent. + +#### 5.1.5 Standardization Focus +The emphasis on standardization addresses the critical gap in the current ecosystem where every intelligent token implementation requires custom integration work, preventing ecosystem-wide benefits and interoperability. + +### 5.2 Alternative Approaches Considered + +#### 5.2.1 Full On-Chain Storage +Rejected due to prohibitive gas costs for rich agent data and learning information. The hybrid approach provides the security benefits of on-chain storage for critical data while maintaining cost-effectiveness. + +#### 5.2.2 Centralized Learning +Rejected to maintain decentralization and user ownership principles. The Merkle tree approach provides verifiable learning while maintaining user control over their agent's data. + +#### 5.2.3 Single-Path Architecture +Rejected to ensure broad adoption across different user comfort levels with AI technology. The dual-path approach accommodates both simple use cases and advanced AI capabilities. + +#### 5.2.4 Custom Integration Approach +Rejected in favor of standardization to prevent ecosystem fragmentation and enable universal compatibility across platforms and applications. + +## 6. Backwards Compatibility + +BAP-578 is fully backwards compatible with ERC-721: +- All ERC-721 functions remain unchanged +- Existing NFT marketplaces can list BAP-578 tokens +- Standard NFT wallets can hold and transfer BAP-578 tokens +- Additional functionality is opt-in and doesn't affect basic operations +- Simple agents using JSON Light Memory work exactly like traditional NFTs +- Learning capabilities can be enabled later without breaking existing functionality + +## 7. Test Cases + +### 7.1 Basic Agent Operations +```solidity +// Test agent creation +function testAgentCreation() public { + uint256 tokenId = bap578.createAgent( + user, + logicAddress, + "ipfs://metadata", + basicMetadata + ); + + assertEq(bap578.ownerOf(tokenId), user); + assertEq(bap578.getState(tokenId).status, Status.Active); +} + +// Test action execution +function testActionExecution() public { + bytes memory data = abi.encodeWithSignature("performAction()"); + bap578.executeAction(tokenId, data); + + // Verify action was executed + assertTrue(actionExecuted); +} +``` + +### 7.2 Learning Agent Operations +```solidity +// Test learning update +function testLearningUpdate() public { + LearningUpdate memory update = LearningUpdate({ + previousRoot: currentRoot, + newRoot: newRoot, + proof: merkleProof, + metadata: learningData + }); + + learningModule.updateLearning(tokenId, update); + + assertEq(learningModule.getLearningRoot(tokenId), newRoot); +} + +// Test learning enablement +function testEnableLearning() public { + bytes32 initialRoot = keccak256("initial_learning_data"); + + bap578Enhanced.enableLearning(tokenId, learningModule.address, initialRoot); + + assertTrue(bap578Enhanced.isLearningEnabled(tokenId)); +} +``` + +### 7.3 Security Tests +```solidity +// Test unauthorized access prevention +function testUnauthorizedAccess() public { + vm.prank(unauthorizedUser); + vm.expectRevert("BAP578: caller is not agent owner"); + bap578.executeAction(tokenId, data); +} + +// Test circuit breaker +function testCircuitBreaker() public { + circuitBreaker.pauseGlobally(); + + vm.expectRevert("BAP578: global pause active"); + bap578.executeAction(tokenId, data); +} +``` + +### 7.4 Dual-Path Compatibility Tests +```solidity +// Test simple agent compatibility +function testSimpleAgentCompatibility() public { + // Create simple agent + uint256 simpleTokenId = bap578.createAgent(user, logicAddress, "ipfs://metadata", basicMetadata); + + // Verify it works like standard NFT + assertEq(bap578.ownerOf(simpleTokenId), user); + assertFalse(bap578Enhanced.isLearningEnabled(simpleTokenId)); +} + +// Test learning upgrade path +function testLearningUpgradePath() public { + // Start with simple agent + uint256 tokenId = bap578.createAgent(user, logicAddress, "ipfs://metadata", basicMetadata); + + // Enable learning later + bytes32 initialRoot = keccak256("initial_learning_data"); + bap578Enhanced.enableLearning(tokenId, learningModule.address, initialRoot); + + // Verify learning is now enabled + assertTrue(bap578Enhanced.isLearningEnabled(tokenId)); +} +``` + +## 8. Implementation + +A reference implementation is available at: https://github.com/ChatAndBuild/non-fungible-agents-BAP-578 + +The implementation includes: +- Core BAP-578 contract with full specification compliance +- Enhanced BAP-578 contract with learning capabilities +- Learning module implementations (Merkle tree, federated learning) +- Memory module registry +- Vault permission manager +- Circuit breaker system +- Agent factory for streamlined deployment +- Multiple agent templates for different use cases +- Dual-path architecture supporting both simple and learning agents +- Migration tools for upgrading simple agents to learning agents + +## 9. Security Considerations + +### 9.1 Smart Contract Security +- **Reentrancy Protection**: All fund-handling functions use ReentrancyGuard +- **Access Control**: Strict permissions for sensitive operations +- **Gas Limits**: Prevent out-of-gas attacks on delegatecall operations +- **Circuit Breakers**: Emergency pause mechanisms for rapid incident response + +### 9.2 Learning Security +- **Rate Limiting**: Prevent spam and gaming of learning systems (maximum 50 learning updates per day per agent) +- **Cryptographic Verification**: All learning claims must be provable through Merkle proofs +- **Module Approval**: Only governance-approved learning modules allowed +- **Privacy Protection**: Learning data access is controlled and auditable +- **Tamper-Proof History**: Learning history cannot be falsified due to cryptographic verification + +### 9.3 Economic Security +- **Agent Funding**: Agents must maintain balance for gas fees +- **Owner Controls**: Only owners can modify critical agent parameters +- **Governance Oversight**: System parameters controlled by decentralized governance + +### 9.4 Data Security +- **Vault Permissions**: Granular access control for off-chain data +- **Signature Verification**: Cryptographic verification for sensitive operations +- **Hash Verification**: Content integrity verification for off-chain data +- **Time-Based Access**: Delegated permissions with automatic expiry + +### 9.5 Dual-Path Security +- **Backward Compatibility**: Simple agents maintain all existing security guarantees +- **Optional Complexity**: Learning features are opt-in and don't affect simple agent security +- **Upgrade Safety**: Enabling learning on existing agents doesn't compromise existing functionality + +## 10. License + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BAPs/README.md b/BAPs/README.md new file mode 100644 index 00000000..8c49d9c4 --- /dev/null +++ b/BAPs/README.md @@ -0,0 +1,29 @@ +# BNB Chain Application Proposals (BAPs) + +- [BNB Chain Application Proposals (BAPs)](#bnb-chain-application-proposals-baps) + - [What is a BAP?](#what-is-a-bap) + - [BAP Workflow](#bap-workflow) + - [BAP Format](#bap-format) + - [Numbering and File Naming](#numbering-and-file-naming) + +## What is a BAP? + +BNB Chain Application Proposals (BAPs) are community-driven design documents that specify application-level standards, conventions, and best practices for the BNB Chain ecosystem. BAPs aim to improve interoperability and user experience across dApps, wallets, services, and tooling. + +- Scope includes: token and NFT standards, wallet interaction flows, RPC/ABI conventions, indexer/query schemas, cross-dApp messaging, off-chain service interfaces, and other app-layer norms. +- BAPs are distinct from BEPs (BNB Chain Evolution Proposals), which target protocol/consensus or node-level changes. + +## BAP Workflow + +BAP workflow follows the process described in [BEP-1](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP1.md#4--bep-workflow). +![overall workflow](../BEPs/assets/bep-1/workflow.png) + +The **Review** stage is central to BAPs and requires feedback from the community, especially from relevant ecosystem partners. Feedback can be provided in this repository or on the [BNB Chain Forum](https://forum.bnbchain.org/). PR status is maintained by the BAP editors, primarily the maintainers of this GitHub repository. + +## BAP Format +The BAP format follows the [BEP format](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP1.md#5--bep-format). Providing reference implementations is strongly recommended to clarify interface definitions. + +### Numbering and File Naming + +- Provisional PRs may use `BAP-xxxx.md`; a concrete number is assigned upon Acceptance. +- Place the file at `BAPs/BAP-.md` with a clear, descriptive title. diff --git a/BEPs/BEP-299.md b/BEPs/BEP-299.md index afb6dc2c..e49cb357 100644 --- a/BEPs/BEP-299.md +++ b/BEPs/BEP-299.md @@ -1,7 +1,7 @@
   BEP: 299
   Title: Token Migration after BC Fusion
-  Status: Candidate
+  Status: Enabled
   Type: Standards
   Created: 2023-10-16
 
diff --git a/BEPs/BEP-336.md b/BEPs/BEP-336.md index cfd3bcd8..dcf59f15 100644 --- a/BEPs/BEP-336.md +++ b/BEPs/BEP-336.md @@ -1,7 +1,7 @@
   BEP: 336
   Title: Implement EIP-4844: Shard Blob Transactions
-  Status: Candidate
+  Status: Enabled
   Type: Standards
   Created: 2023-12-04
 
diff --git a/BEPs/BEP-342.md b/BEPs/BEP-342.md index 9d10fdcf..71b41ed8 100644 --- a/BEPs/BEP-342.md +++ b/BEPs/BEP-342.md @@ -1,7 +1,7 @@
   BEP: 342
   Title: Implement EIP-5656: MCOPY
-  Status: Candidate
+  Status: Enabled
   Type: Standards
   Created: 2024-01-15
 
@@ -9,7 +9,7 @@ # BEP-342: Implement EIP-5656: MCOPY -- [BEP-342: Implement Implement EIP-5656: MCOPY](#bep-342-implement-eip-5656-mcopy) +- [BEP-342: Implement EIP-5656: MCOPY](#bep-342-implement-eip-5656-mcopy) - [1. Summary](#1-summary) - [2. Abstract](#2-abstract) - [3. Motivation](#3-motivation) diff --git a/BEPs/BEP-343.md b/BEPs/BEP-343.md index dee6cd1d..1e4f52f0 100644 --- a/BEPs/BEP-343.md +++ b/BEPs/BEP-343.md @@ -1,7 +1,7 @@
   BEP: 343
   Title: Implement EIP-1153: Transient storage opcodes
-  Status: Candidate
+  Status: Enabled
   Type: Standards
   Created: 2024-01-15
 
diff --git a/BEPs/BEP-344.md b/BEPs/BEP-344.md index 942b5a64..879e6355 100644 --- a/BEPs/BEP-344.md +++ b/BEPs/BEP-344.md @@ -1,7 +1,7 @@
   BEP: 344
   Title: Implement EIP-6780: SELFDESTRUCT only in same transaction
-  Status: Candidate
+  Status: Enabled
   Type: Standards
   Created: 2024-01-15
 
diff --git a/BEPs/BEP-345.md b/BEPs/BEP-345.md index d6d5877e..c86922d0 100644 --- a/BEPs/BEP-345.md +++ b/BEPs/BEP-345.md @@ -1,7 +1,7 @@
   BEP: 345
   Title: Implement EIP-7516: BLOBBASEFEE opcode
-  Status: Candidate
+  Status: Enabled
   Type: Standards
   Created: 2024-01-15
 
diff --git a/BEPs/BEP-363.md b/BEPs/BEP-363.md index b7cfd963..77b32da6 100644 --- a/BEPs/BEP-363.md +++ b/BEPs/BEP-363.md @@ -21,10 +21,11 @@ - [4.1.5 Relayer Fee](#415-relayer-fee) - [4.1.6 Execution Order](#416-execution-order) - [4.2 GreenfieldExecutor](#42-greenfieldexecutor) - - [4.2.1 API](#421-api) - - [4.2.2 Error Handling](#422-error-handling) - - [4.2.3 Execution Order](#423-execution-order) - - [4.2.4 Pros and Cons](#424-pros-and-cons) + - [4.2.1 Support Msgs](#421-support-msgs) + - [4.2.2 API](#422-api) + - [4.2.3 Error Handling](#423-error-handling) + - [4.2.4 Execution Order](#424-execution-order) + - [4.2.5 Pros and Cons](#425-pros-and-cons) - [5. License](#5-license) ## 1. Summary diff --git a/BEPs/BEP-364.md b/BEPs/BEP-364.md index f8cc464d..5d622b11 100644 --- a/BEPs/BEP-364.md +++ b/BEPs/BEP-364.md @@ -14,6 +14,14 @@ - [2. Motivation](#2-motivation) - [3. Status](#3-status) - [4. Specification](#4-specification) + - [4.1 APIs](#41-apis) + - [4.1.1 SP APIs](#411-sp-apis) + - [SDK](#sdk) + - [4.1.2 Greenfield Chain New Messages](#412-greenfield-chain-new-messages) + - [4.2 New workflow for object creation/update on Greenfield](#42-new-workflow-for-object-creationupdate-on-greenfield) + - [4.2.1 Users](#421-users) + - [4.2.2 SP](#422-sp) + - [4.3 Security](#43-security) - [5. License](#5-license) diff --git a/BEPs/BEP-366.md b/BEPs/BEP-366.md index 058ac371..82405cc8 100644 --- a/BEPs/BEP-366.md +++ b/BEPs/BEP-366.md @@ -12,17 +12,18 @@ -- [BEP-366: Greenfield Atomic Object Update](#bep-greenfield-atomic-object-update) +- [BEP-366: Greenfield Atomic Object Update](#bep-366-greenfield-atomic-object-update) - [1. Summary](#1-summary) - [2. Motivation](#2-motivation) - [3. Status](#3-status) - [4. Specification](#4-specification) - [4.1 Requirements](#41-requirements) - [4.2 Implementation](#42-implementation) - - [4.2.1 Change To Current Model](#421-change-to-current-model) - - [4.2.2 New Model And Message](#422-new-model-and-message) - - [4.3 Workflow](#43-workflow) - - [4.4 Fees & User Charges](#44-fees-&-user-charges) + - [4.2.1. Change To Current Model](#421-change-to-current-model) + - [4.2.1. New Model And Message](#421-new-model-and-message) + - [4.3 Workflow](#43-workflow) + - [4.4 Fees \& User Charges](#44-fees--user-charges) + - [5. License](#5-license) ## 1. Summary diff --git a/BEPs/BEP-381.md b/BEPs/BEP-381.md index 713f937e..e088f68f 100644 --- a/BEPs/BEP-381.md +++ b/BEPs/BEP-381.md @@ -12,7 +12,7 @@ -- [BEP-381: Precompile for secp256r1 Curve Support](#bep-precompile-for-secp256r1-curve-support) +- [BEP-381: Precompile for secp256r1 Curve Support](#bep-381-precompile-for-secp256r1-curve-support) - [1. Summary](#1-summary) - [2. Motivation](#2-motivation) - [3. Status](#3-status) @@ -23,10 +23,10 @@ - [4.3 Precompiled Contract Specification](#43-precompiled-contract-specification) - [4.4 Precompiled Contract Gas Usage](#44-precompiled-contract-gas-usage) - [5. Rationale](#5-rationale) - - [6. Backwards Compatibility](#6-backwards-compatibily) + - [6. Backwards Compatibility](#6-backwards-compatibility) - [7. Test Cases](#7-test-cases) - [8. Reference Implementation](#8-reference-implementation) - - [9. Security Considerations](#8-security-consideration) + - [9. Security Considerations](#9-security-considerations) - [10. Copyright](#10-copyright) diff --git a/BEPs/BEP-402.md b/BEPs/BEP-402.md index 2e14b0d0..b545922e 100644 --- a/BEPs/BEP-402.md +++ b/BEPs/BEP-402.md @@ -1,7 +1,7 @@
   BEP: 402
   Title: Complete Missing Fields in Block Header to Generate Signature
-  Status: Candidate
+  Status: Enabled
   Type: Standards
   Created: 2024-06-28
 
diff --git a/BEPs/BEP-404.md b/BEPs/BEP-404.md index 9f192956..5d9cfbfb 100644 --- a/BEPs/BEP-404.md +++ b/BEPs/BEP-404.md @@ -1,7 +1,7 @@
   BEP: 404
   Title: Clear Miner History when Switching Validators Set
-  Status: Candidate
+  Status: Enabled
   Type: Standards
   Created: 2024-07-01
 
diff --git a/BEPs/BEP-414.md b/BEPs/BEP-414.md index 7ac47380..5f68a842 100644 --- a/BEPs/BEP-414.md +++ b/BEPs/BEP-414.md @@ -8,6 +8,21 @@ # BEP-414: Paymaster API Spec for EOA Wallets +- [BEP-414: Paymaster API Spec for EOA Wallets](#bep-414-paymaster-api-spec-for-eoa-wallets) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Status](#3-status) + - [4. Motivation](#4-motivation) + - [5. Specification](#5-specification) + - [5.1 Definitions](#51-definitions) + - [5.2 Workflow](#52-workflow) + - [5.3 Wallet Interaction](#53-wallet-interaction) + - [5.4 Paymaster API Spec](#54-paymaster-api-spec) + - [`pm_isSponsorable`](#pm_issponsorable) + - [`eth_sendrawtransaction`](#eth_sendrawtransaction) + - [5.5 Sponsor Policy \&\& Fee Charge](#55-sponsor-policy--fee-charge) + - [6 License](#6-license) + ## 1. Summary Unlike the paymaster defined in EIP-4337, this proposal introduces a paymaster solution specifically tailored for EOA (Externally Owned Account) wallets, along with standardized paymaster APIs. With minimal modifications, wallets can integrate paymasters that implement these API standards, enabling users to send transactions with zero gas fees. @@ -172,4 +187,5 @@ Paymasters have complete autonomy in defining sponsor policies, which can be imp Paymasters also enjoy flexibility in their fee collection methods. Charges can be directly deducted from the sponsor's credit card, or sponsors can pre-deposit cryptocurrency to the paymaster platform, from which the balance is then charged. ## 6 License -The content is licensed under CC0. + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-439.md b/BEPs/BEP-439.md index b51dd86d..c24b1610 100644 --- a/BEPs/BEP-439.md +++ b/BEPs/BEP-439.md @@ -1,7 +1,7 @@
   BEP: 439
   Title: Implement EIP-2537: Precompile for BLS12-381 curve operations
-  Status: Review
+  Status: Enabled
   Type: Standards
   Created: 2024-09-23
   Description: Adds operation on BLS12-381 curve as a precompile in a set necessary to efficiently perform operations such as BLS signature verification.
@@ -25,10 +25,8 @@
       - [Behavior on empty inputs:](#behavior-on-empty-inputs)
     - [ABI for operations](#abi-for-operations)
       - [ABI for G1 addition](#abi-for-g1-addition)
-      - [ABI for G1 multiplication](#abi-for-g1-multiplication)
       - [ABI for G1 MSM](#abi-for-g1-msm)
       - [ABI for G2 addition](#abi-for-g2-addition)
-      - [ABI for G2 multiplication](#abi-for-g2-multiplication)
       - [ABI for G2 MSM](#abi-for-g2-msm)
       - [ABI for pairing check](#abi-for-pairing-check)
       - [ABI for mapping Fp element to G1 point](#abi-for-mapping-fp-element-to-g1-point)
@@ -41,6 +39,8 @@
       - [G2 addition](#g2-addition)
       - [G2 multiplication](#g2-multiplication)
       - [G1/G2 MSM](#g1g2-msm)
+        - [G1 discounts](#g1-discounts)
+        - [G2 discounts](#g2-discounts)
       - [Pairing check operation](#pairing-check-operation)
       - [Fp-to-G1 mapping operation](#fp-to-g1-mapping-operation)
       - [Fp2-to-G2 mapping operation](#fp2-to-g2-mapping-operation)
@@ -49,6 +49,7 @@
         - [Gas schedule clarifications for pairing](#gas-schedule-clarifications-for-pairing)
   - [Rationale](#rationale)
     - [MSM as a separate call](#msm-as-a-separate-call)
+    - [No dedicated MUL call](#no-dedicated-mul-call)
   - [Backwards Compatibility](#backwards-compatibility)
     - [Subgroup checks](#subgroup-checks)
     - [Field to curve mapping](#field-to-curve-mapping)
@@ -63,7 +64,7 @@
 
 Add functionality to efficiently perform operations over the BLS12-381 curve, including those for BLS signature verification.
 
-Along with the curve arithmetic, multiexponentiation operations are included to efficiently aggregate public keys or individual signer's signatures during BLS signature verification.
+Along with the curve arithmetic, multi-scalar-multiplication operations are included to efficiently aggregate public keys or individual signer's signatures during BLS signature verification.
 
 ## Motivation
 
@@ -75,28 +76,23 @@ The motivation of this precompile is to add a cryptographic primitive that allow
 
 | Name                | Value | Comment            |
 |---------------------|-------|--------------------|
-| `FORK_TIMESTAMP`    | *TBD* | Mainnet            |
 | BLS12_G1ADD         | 0x0b  | precompile address |
-| BLS12_G1MUL         | 0x0c  | precompile address |
-| BLS12_G1MSM         | 0x0d  | precompile address |
-| BLS12_G2ADD         | 0x0e  | precompile address |
-| BLS12_G2MUL         | 0x0f  | precompile address |
-| BLS12_G2MSM         | 0x10  | precompile address |
-| BLS12_PAIRING_CHECK | 0x11  | precompile address |
-| BLS12_MAP_FP_TO_G1  | 0x12  | precompile address |
-| BLS12_MAP_FP2_TO_G2 | 0x13  | precompile address |
-
-If `block.timestamp >= FORK_TIMESTAMP` we introduce *nine* separate precompiles to perform the following operations:
-
-- BLS12_G1ADD - to perform point addition in G1 (curve over base prime field) with a gas cost of `500` gas
-- BLS12_G1MUL - to perform point multiplication in G1 (curve over base prime field) with a gas cost of `12000` gas
+| BLS12_G1MSM         | 0x0c  | precompile address |
+| BLS12_G2ADD         | 0x0d  | precompile address |
+| BLS12_G2MSM         | 0x0e  | precompile address |
+| BLS12_PAIRING_CHECK | 0x0f  | precompile address |
+| BLS12_MAP_FP_TO_G1  | 0x10  | precompile address |
+| BLS12_MAP_FP2_TO_G2 | 0x11  | precompile address |
+
+We introduce *seven* separate precompiles to perform the following operations:
+
+- BLS12_G1ADD - to perform point addition in G1 (curve over base prime field) with a gas cost of `375` gas
 - BLS12_G1MSM - to perform multi-scalar-multiplication (MSM) in G1 (curve over base prime field) with a gas cost formula defined in the corresponding section
-- BLS12_G2ADD - to perform point addition in G2 (curve over quadratic extension of the base prime field) with a gas cost of `800` gas
-- BLS12_G2MUL - to perform point multiplication in G2 (curve over quadratic extension of the base prime field) with a gas cost of `45000` gas
+- BLS12_G2ADD - to perform point addition in G2 (curve over quadratic extension of the base prime field) with a gas cost of `600` gas
 - BLS12_G2MSM - to perform multi-scalar-multiplication (MSM) in G2 (curve over quadratic extension of the base prime field) with a gas cost formula defined in the corresponding section
 - BLS12_PAIRING_CHECK - to perform a pairing operations between a set of *pairs* of (G1, G2) points a gas cost formula defined in the corresponding section
 - BLS12_MAP_FP_TO_G1 - maps base field element into the G1 point with a gas cost of `5500` gas
-- BLS12_MAP_FP2_TO_G2 - maps extension field element into the G2 point with a gas cost of `75000` gas
+- BLS12_MAP_FP2_TO_G2 - maps extension field element into the G2 point with a gas cost of `23800` gas
 
 A mapping functions specification is included as a separate [document](./assets/bep-439/field_to_curve.md). This mapping function does NOT perform mapping of the byte string into a field element (as it can be implemented in many different ways and can be efficiently performed in EVM), but only does field arithmetic to map a field element into a curve point. Such functionality is required for signature schemes.
 
@@ -194,17 +190,6 @@ Note:
 
 There is no subgroup check for the G1 addition precompile.
 
-#### ABI for G1 multiplication
-
-G1 multiplication call expects `160` bytes as an input that is interpreted as byte concatenation of encoding of a G1 point (`128` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of the multiplication operation result - a single G1 point (`128` bytes).
-
-Error cases:
-
-- Invalid coordinate encoding
-- An input is neither a point on the G1 elliptic curve nor the infinity point
-- An input is on the G1 elliptic curve but not in the correct subgroup
-- Input has invalid length
-
 #### ABI for G1 MSM
 
 G1 MSM call expects `160*k` (`k` being a **positive** integer) bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of a G1 point (`128` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of MSM operation result - a single G1 point (`128` bytes).
@@ -230,17 +215,6 @@ Note:
 
 There is no subgroup check for the G2 addition precompile.
 
-#### ABI for G2 multiplication
-
-G2 multiplication call expects `288` bytes as an input that is interpreted as byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of multiplication operation result - single G2 point (`256` bytes).
-
-Error cases:
-
-- Invalid coordinate encoding
-- An input is neither a point on the G2 elliptic curve nor the infinity point
-- An input is on the G2 elliptic curve but not in the correct subgroup
-- Input has invalid length
-
 #### ABI for G2 MSM
 
 G2 MSM call expects `288*k` (`k` being a **positive** integer) bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes). Output is an encoding of MSM operation result - a single G2 point (`256` bytes).
@@ -261,7 +235,7 @@ Pairing check call expects `384*k`  (`k` being a **positive** integer)  bytes as
 
 Each point is expected to be in the subgroup of order `q`.
 
-Output is `32` bytes where first `31` bytes are equal to `0x00` and the last byte is `0x01` if pairing result is equal to the multiplicative identity in a pairing target field and `0x00` otherwise.
+It checks the equation `e(P1, Q1) * e(P2, Q2) * ... * e(Pk, Qk) == 1` in the pairing target field where `e` is the pairing operation. Output is `32` bytes where first `31` bytes are equal to `0x00` and the last byte is either `0x00` (false) or `0x01` (true).
 
 Error cases:
 
@@ -270,9 +244,6 @@ Error cases:
 - An input is on its respective elliptic curve but not in the correct subgroup
 - Input has invalid length
 
-Note:
-
-If any input is the infinity point, pairing result will be 1. Protocols may want to check and reject infinity points prior to calling the precompile.
 
 #### ABI for mapping Fp element to G1 point
 
@@ -302,11 +273,11 @@ A sane implementation of this EIP *should not* contain potential infinite loops
 
 ### Gas schedule
 
-Assuming a constant `30 MGas/second`, the following prices are suggested.
+Assuming `EcRecover` precompile as a baseline.
 
 #### G1 addition
 
-`500` gas
+`375` gas
 
 #### G1 multiplication
 
@@ -314,29 +285,43 @@ Assuming a constant `30 MGas/second`, the following prices are suggested.
 
 #### G2 addition
 
-`800` gas
+`600` gas
 
 #### G2 multiplication
 
-`45000` gas
+`22500` gas
 
 #### G1/G2 MSM
 
 MSMs are expected to be performed by Pippenger's algorithm (we can also say that it **must** be performed by Pippenger's algorithm to have a speedup that results in a discount over naive implementation by multiplying each pair separately and adding the results). For this case there was a table prepared for discount in case of `k <= 128` points in the MSM with a discount cap `max_discount` for `k > 128`.
 
-To avoid non-integer arithmetic, the call cost is calculated as `(k * multiplication_cost * discount) / multiplier` where `multiplier = 1000`, `k` is a number of (scalar, point) pairs for the call, `multiplication_cost` is a corresponding single multiplication call cost for G1/G2.
+The call cost is calculated as `(k * multiplication_cost * discount) // multiplier` where `multiplier = 1000`, `k` is a number of (scalar, point) pairs for the call, `multiplication_cost` is a corresponding G1/G2 multiplication cost presented above and `//` is an integer division.
+
+G1 and G2 are priced separately, each having their own discount table and `max_discount`.
+
+##### G1 discounts
 
-Discounts table as a vector of pairs `[k, discount]`:
+Discounts table for G1 MSM as a vector of pairs `[k, discount]`:
 
 ```
-[[1, 1200], [2, 888], [3, 764], [4, 641], [5, 594], [6, 547], [7, 500], [8, 453], [9, 438], [10, 423], [11, 408], [12, 394], [13, 379], [14, 364], [15, 349], [16, 334], [17, 330], [18, 326], [19, 322], [20, 318], [21, 314], [22, 310], [23, 306], [24, 302], [25, 298], [26, 294], [27, 289], [28, 285], [29, 281], [30, 277], [31, 273], [32, 269], [33, 268], [34, 266], [35, 265], [36, 263], [37, 262], [38, 260], [39, 259], [40, 257], [41, 256], [42, 254], [43, 253], [44, 251], [45, 250], [46, 248], [47, 247], [48, 245], [49, 244], [50, 242], [51, 241], [52, 239], [53, 238], [54, 236], [55, 235], [56, 233], [57, 232], [58, 231], [59, 229], [60, 228], [61, 226], [62, 225], [63, 223], [64, 222], [65, 221], [66, 220], [67, 219], [68, 219], [69, 218], [70, 217], [71, 216], [72, 216], [73, 215], [74, 214], [75, 213], [76, 213], [77, 212], [78, 211], [79, 211], [80, 210], [81, 209], [82, 208], [83, 208], [84, 207], [85, 206], [86, 205], [87, 205], [88, 204], [89, 203], [90, 202], [91, 202], [92, 201], [93, 200], [94, 199], [95, 199], [96, 198], [97, 197], [98, 196], [99, 196], [100, 195], [101, 194], [102, 193], [103, 193], [104, 192], [105, 191], [106, 191], [107, 190], [108, 189], [109, 188], [110, 188], [111, 187], [112, 186], [113, 185], [114, 185], [115, 184], [116, 183], [117, 182], [118, 182], [119, 181], [120, 180], [121, 179], [122, 179], [123, 178], [124, 177], [125, 176], [126, 176], [127, 175], [128, 174]]
+[[1, 1000], [2, 949], [3, 848], [4, 797], [5, 764], [6, 750], [7, 738], [8, 728], [9, 719], [10, 712], [11, 705], [12, 698], [13, 692], [14, 687], [15, 682], [16, 677], [17, 673], [18, 669], [19, 665], [20, 661], [21, 658], [22, 654], [23, 651], [24, 648], [25, 645], [26, 642], [27, 640], [28, 637], [29, 635], [30, 632], [31, 630], [32, 627], [33, 625], [34, 623], [35, 621], [36, 619], [37, 617], [38, 615], [39, 613], [40, 611], [41, 609], [42, 608], [43, 606], [44, 604], [45, 603], [46, 601], [47, 599], [48, 598], [49, 596], [50, 595], [51, 593], [52, 592], [53, 591], [54, 589], [55, 588], [56, 586], [57, 585], [58, 584], [59, 582], [60, 581], [61, 580], [62, 579], [63, 577], [64, 576], [65, 575], [66, 574], [67, 573], [68, 572], [69, 570], [70, 569], [71, 568], [72, 567], [73, 566], [74, 565], [75, 564], [76, 563], [77, 562], [78, 561], [79, 560], [80, 559], [81, 558], [82, 557], [83, 556], [84, 555], [85, 554], [86, 553], [87, 552], [88, 551], [89, 550], [90, 549], [91, 548], [92, 547], [93, 547], [94, 546], [95, 545], [96, 544], [97, 543], [98, 542], [99, 541], [100, 540], [101, 540], [102, 539], [103, 538], [104, 537], [105, 536], [106, 536], [107, 535], [108, 534], [109, 533], [110, 532], [111, 532], [112, 531], [113, 530], [114, 529], [115, 528], [116, 528], [117, 527], [118, 526], [119, 525], [120, 525], [121, 524], [122, 523], [123, 522], [124, 522], [125, 521], [126, 520], [127, 520], [128, 519]]
 ```
 
-`max_discount = 174`
+`max_discount = 519`
+
+##### G2 discounts
+
+Discounts table for G2 MSM as a vector of pairs `[k, discount]`:
+
+```
+[[1, 1000], [2, 1000], [3, 923], [4, 884], [5, 855], [6, 832], [7, 812], [8, 796], [9, 782], [10, 770], [11, 759], [12, 749], [13, 740], [14, 732], [15, 724], [16, 717], [17, 711], [18, 704], [19, 699], [20, 693], [21, 688], [22, 683], [23, 679], [24, 674], [25, 670], [26, 666], [27, 663], [28, 659], [29, 655], [30, 652], [31, 649], [32, 646], [33, 643], [34, 640], [35, 637], [36, 634], [37, 632], [38, 629], [39, 627], [40, 624], [41, 622], [42, 620], [43, 618], [44, 615], [45, 613], [46, 611], [47, 609], [48, 607], [49, 606], [50, 604], [51, 602], [52, 600], [53, 598], [54, 597], [55, 595], [56, 593], [57, 592], [58, 590], [59, 589], [60, 587], [61, 586], [62, 584], [63, 583], [64, 582], [65, 580], [66, 579], [67, 578], [68, 576], [69, 575], [70, 574], [71, 573], [72, 571], [73, 570], [74, 569], [75, 568], [76, 567], [77, 566], [78, 565], [79, 563], [80, 562], [81, 561], [82, 560], [83, 559], [84, 558], [85, 557], [86, 556], [87, 555], [88, 554], [89, 553], [90, 552], [91, 552], [92, 551], [93, 550], [94, 549], [95, 548], [96, 547], [97, 546], [98, 545], [99, 545], [100, 544], [101, 543], [102, 542], [103, 541], [104, 541], [105, 540], [106, 539], [107, 538], [108, 537], [109, 537], [110, 536], [111, 535], [112, 535], [113, 534], [114, 533], [115, 532], [116, 532], [117, 531], [118, 530], [119, 530], [120, 529], [121, 528], [122, 528], [123, 527], [124, 526], [125, 526], [126, 525], [127, 524], [128, 524]]
+```
+
+`max_discount = 524`
 
 #### Pairing check operation
 
-The cost of the pairing check operation is `43000*k + 65000` where `k` is a number of pairs.
+The cost of the pairing check operation is `32600*k + 37700` where `k` is a number of pairs.
 
 #### Fp-to-G1 mapping operation
 
@@ -344,7 +329,7 @@ Fp -> G1 mapping is `5500` gas.
 
 #### Fp2-to-G2 mapping operation
 
-Fp2 -> G2 mapping is `75000` gas
+Fp2 -> G2 mapping is `23800` gas
 
 #### Gas schedule clarifications for the variable-length input
 
@@ -361,7 +346,7 @@ k = floor(len(input) / LEN_PER_PAIR);
 if k == 0 {
   return 0;
 }
-gas_cost = k * multiplication_cost * discount(k) / multiplier;
+gas_cost = k * multiplication_cost * discount(k) // multiplier;
 return gas_cost;
 ```
 
@@ -375,7 +360,7 @@ The following pseudofunction reflects how gas should be calculated:
 
 ```
 k = floor(len(input) / LEN_PER_PAIR);
-gas_cost = 43000*k + 65000;
+gas_cost = 32600*k + 37700;
 return gas_cost;
 ```
 
@@ -389,13 +374,18 @@ The motivation section covers a total motivation to have operations over the BLS
 
 Explicit separate MSM operation that allows one to save execution time (so gas) by both the algorithm used (namely Pippenger's algorithm) and (usually forgotten) by the fact that `CALL` operation in Ethereum is expensive (at the time of writing), so one would have to pay non-negligible overhead if e.g. for MSM of `100` points would have to call the multiplication precompile `100` times and addition for `99` times (roughly `138600` would be saved).
 
+### No dedicated MUL call
+
+Dedicated MUL precompiles which perform single G1/G2 point by scalar multiplication have exactly the same ABI as MSM with `k == 1`.
+MSM has to inspect the input length to reject inputs of invalid lengths. Therefore, it should recognize the case of `k == 1` and invoke the underlying implementation of single point multiplication to avoid the overhead of more complex multi-scalar multiplication algorithm.
+
 ## Backwards Compatibility
 
 There are no backward compatibility questions.
 
 ### Subgroup checks
 
-Scalar multiplications, MSMs and pairings MUST perform a subgroup check.
+MSMs and pairings MUST perform a subgroup check.
 Implementations SHOULD use the optimized subgroup check method detailed in a dedicated [document](./assets/bep-439/fast_subgroup_checks.md).
 On any input that fails the subgroup check, the precompile MUST return an error.
 As endomorphism acceleration requires input on the correct subgroup, implementers MAY use endomorphism acceleration.
diff --git a/BEPs/BEP-440.md b/BEPs/BEP-440.md
index 5a135300..63770e7c 100644
--- a/BEPs/BEP-440.md
+++ b/BEPs/BEP-440.md
@@ -1,7 +1,7 @@
 
   BEP: 440
   Title: Implement EIP-2935: Serve historical block hashes from state
-  Status: Review
+  Status: Enabled
   Type: Standards
   Created: 2024-09-24
   Description: Store and serve last 8192 block hashes as storage slots of a system contract to allow for stateless execution
@@ -25,6 +25,7 @@
     - [Gas costs](#gas-costs)
   - [Rationale](#rationale)
     - [Inserting the parent block hash](#inserting-the-parent-block-hash)
+    - [Size of ring buffers](#size-of-ring-buffers)
   - [Backwards Compatibility](#backwards-compatibility)
   - [Test Cases](#test-cases)
   - [Security Considerations](#security-considerations)
@@ -47,17 +48,16 @@ A side benefit of this approach could be that it allows building/validating proo
 
 | Parameter | Value |
 | - | - |
-| `FORK_TIMESTAMP` | TBD |
-| `BLOCKHASH_SERVE_WINDOW` | `256` |
-| `HISTORY_SERVE_WINDOW` | `8192` |
-| `SYSTEM_ADDRESS` | `0xfffffffffffffffffffffffffffffffffffffffe` |
-| `HISTORY_STORAGE_ADDRESS` | `0x0aae40965e6800cd9b1f4b05ff21581047e3f91e`|
+| `BLOCKHASH_SERVE_WINDOW`  | `256` |
+| `HISTORY_SERVE_WINDOW`    | `8191` |
+| `SYSTEM_ADDRESS`          | `0xfffffffffffffffffffffffffffffffffffffffe` |
+| `HISTORY_STORAGE_ADDRESS` | `0x0000F90827F1C53a10cb7A02335B175320002935` |
 
 This EIP specifies for storing last `HISTORY_SERVE_WINDOW` block hashes in a ring buffer storage of `HISTORY_SERVE_WINDOW` length. Note that `HISTORY_SERVE_WINDOW` > `BLOCKHASH_SERVE_WINDOW` (which remains unchanged).
 
 ### Block processing
 
-At the start of processing any block where `block.timestamp >= FORK_TIMESTAMP` (ie. before processing any transactions), call to `HISTORY_STORAGE_ADDRESS` as `SYSTEM_ADDRESS` with the 32-byte input of `block.parent.hash`, a gas limit of `30_000_000`, and `0` value. This will trigger the `set()` routine of the history contract. This is a system operation following the same convention as [EIP-4788](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4788.md) and therefore:
+At the start of processing any block where this EIP is active (ie. before processing any transactions), call to `HISTORY_STORAGE_ADDRESS` as `SYSTEM_ADDRESS` with the 32-byte input of `block.parent.hash`, a gas limit of `30_000_000`, and `0` value. This will trigger the `set()` routine of the history contract. This is a system operation following the same convention as [EIP-4788](./eip-4788.md) and therefore:
 
 * the call must execute to completion
 * the call does not count against the block's gas limit
@@ -66,7 +66,7 @@ At the start of processing any block where `block.timestamp >= FORK_TIMESTAMP` (
 
 Note: Alternatively clients can choose to directly write to the storage of the contract but EVM calling the contract remains preferred. Refer to the rationale for more info.
 
-Note that, it will take `HISTORY_SERVE_WINDOW` blocks after `FORK_TIMESTAMP` to completely fill up the ring buffer. The contract will only contain the parent hash of the fork block and no hashes prior to that.
+Note that, it will take `HISTORY_SERVE_WINDOW` blocks after the EIP's activation to completely fill up the ring buffer. The contract will only contain the parent hash of the fork block and no hashes prior to that.
 
 
 ### EVM Changes
@@ -82,8 +82,8 @@ The history contract has two operations: `get` and `set`. The `set` operation is
 It is used from the EVM for looking up block hashes.
 
 * Callers provide the block number they are querying in a big-endian encoding.
-* If calldata is bigger than 2^64-1, revert.
-* For any output outside the range of [block.number-`HISTORY_SERVE_WINDOW`, block.number-1] return 0.
+* If calldata is not 32 bytes, revert.
+* For any request outside the range of [block.number-`HISTORY_SERVE_WINDOW`, block.number-1], revert.
 
 #### `set`
 
@@ -95,88 +95,58 @@ It is used from the EVM for looking up block hashes.
 Exact evm assembly that can be used for the history contract:
 
 ```
-// if system call then jump to the set operation
+// https://github.com/lightclient/sys-asm/blob/f1c13e285b6aeef2b19793995e00861bf0f32c9a/src/execution_hash/main.eas
 caller
 push20 0xfffffffffffffffffffffffffffffffffffffffe
 eq
-push1 0x57
+push1 0x46
+jumpi
+push1 0x20
+calldatasize
+sub
+push1 0x42
 jumpi
-
-// check if input > 8 byte value and revert if this isn't the case
-// the check is performed by comparing the biggest 8 byte number with
-// the call data, which is a right-padded 32 byte number.
-push8 0xffffffffffffffff
 push0
 calldataload
-gt
-push1 0x53
-jumpi
-
-// check if input > blocknumber-1 then return 0
-push1 0x1
+push1 0x01
 number
 sub
-push0
-calldataload
+dup2
 gt
-push1 0x4b
+push1 0x42
 jumpi
-
-// check if blocknumber > input + 8192 then return 0, no overflow expected for input of < max 8 byte value
-push0
-calldataload
-push2 0x2000
-add
+push2 0x1fff
+dup2
 number
+sub
 gt
-push1 0x4b
+push1 0x42
 jumpi
-
-// mod 8192 and sload
 push2 0x1fff
-push0
-calldataload
-and
+swap1
+mod
 sload
-
-// load into mem and return 32 bytes
 push0
 mstore
 push1 0x20
 push0
 return
-
-// 0x4b: return 0
-jumpdest
-push0
-push0
-mstore
-push1 0x20
-push0
-return
-
-// 0x53: revert
 jumpdest
 push0
 push0
 revert
-
-// 0x57: set op - sstore the input to number-1 mod 8192
 jumpdest
 push0
 calldataload
 push2 0x1fff
-push1 0x1
+push1 0x01
 number
 sub
-and
+mod
 sstore
-
 stop
 ```
 
-Corresponding bytecode:
-`0x3373fffffffffffffffffffffffffffffffffffffffe1460575767ffffffffffffffff5f3511605357600143035f3511604b575f35612000014311604b57611fff5f3516545f5260205ff35b5f5f5260205ff35b5f5ffd5b5f35611fff60014303165500`
 
 #### Deployment
 
@@ -227,12 +197,17 @@ The latter option is as follows:
 
 ```python
 def process_block_hash_history(block: Block, state: State):
-    if block.timestamp >= FORK_TIMESTAMP:
+    if block.timestamp >= FORK_TIMESTAMP: // FORK_TIMESTAMP should be definied outside of the EIP
         state.insert_slot(HISTORY_STORAGE_ADDRESS, (block.number-1) % HISTORY_SERVE_WINDOW , block.parent.hash)
 ```
 
 The first option is recommended until the Verkle fork, to stay consistent with [EIP-4788](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4788.md) and to issues for misconfigured networks where this EIP is activated but history contract hasn't been deployed. The recommendation may be reconsidered at the Verkle fork if filtering the system contract code chunks is deemed too complex.
 
+### Size of ring buffers
+The ring buffer data structure is sized to hold 8191 hashes. In other system contracts a prime ring buffer size is chosen in because using a prime as the modulus ensures that no value is overwritten until the entire ring buffer has been saturated and thereafter, each value will be updated once per iteration, regardless of if some slot are missing or the slot time changes. However, in this EIP the block number is the value in the modulo operation and it only ever increases by 1 each iteration. Which means we can be confident that the ring buffer will always remain saturated.
+
+For consistency with other system contracts, we have decided to retain the buffer size of 8191. This also gives users plenty of time to make a transaction with a verification against a specific hash and get the transaction included on-chain.
+
 ## Backwards Compatibility
 
 This EIP introduces backwards incompatible changes to the block validation rule set. But neither of these changes break anything related to current user activity and experience.
diff --git a/BEPs/BEP-441.md b/BEPs/BEP-441.md
index a55b1d15..a609ffd9 100644
--- a/BEPs/BEP-441.md
+++ b/BEPs/BEP-441.md
@@ -1,10 +1,10 @@
 
   BEP: 441
   Title: Implement EIP-7702: Set EOA account code
-  Status: Review
+  Status: Enabled
   Type: Standards
   Created: 2024-09-25
-  Description: Add a new tx type that sets the code for an EOA during execution
+  Description: Add a new tx type that permanently sets the code for an EOA
 
@@ -21,6 +21,7 @@ - [Gas Costs](#gas-costs) - [Transaction Origination](#transaction-origination) - [Rationale](#rationale) + - [Cost of Delegation](#cost-of-delegation) - [No initcode](#no-initcode) - [Creation by template](#creation-by-template) - [Lack of instruction prohibition](#lack-of-instruction-prohibition) @@ -29,6 +30,8 @@ - [In-protocol revocation](#in-protocol-revocation) - [Self-sponsoring: allowing `tx.origin` to set code](#self-sponsoring-allowing-txorigin-to-set-code) - [Forward-compatibility with future account abstraction](#forward-compatibility-with-future-account-abstraction) + - [Clearing Delegation Designations](#clearing-delegation-designations) + - [Delegation of code execution only](#delegation-of-code-execution-only) - [Backwards Compatibility](#backwards-compatibility) - [Security Considerations](#security-considerations) - [Secure delegation](#secure-delegation) @@ -36,12 +39,13 @@ - [Sponsored transaction relayers](#sponsored-transaction-relayers) - [Front running initialization](#front-running-initialization) - [Transaction propagation](#transaction-propagation) + - [Storage management](#storage-management) - [Copyright](#copyright) ## Abstract -Add a new transaction type that adds a list of `[chain_id, address, nonce, y_parity, r, s]` authorization tuples. For each tuple, write a delegation designator `(0xef0100 ++ address)` to the signing account's code. All code reading operations must load the code pointed to by the designator. +Add a new transaction type that adds a list of `[chain_id, address, nonce, y_parity, r, s]` authorization tuples. For each tuple, write a delegation designator `(0xef0100 || address)` to the signing account's code. All code executing operations must load the code pointed to by the designator. ## Motivation @@ -49,7 +53,7 @@ There is a lot of interest in adding short-term functionality improvements to EO * **Batching**: allowing multiple operations from the same user in one atomic transaction. One common example is an [ERC-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) approval followed by spending that approval, a common workflow in DEXes that requires two transactions today. Advanced use cases of batching occasionally involve dependencies: the output of the first operation is part of the input to the second operation. * **Sponsorship**: account X pays for a transaction on behalf of account Y. Account X could be paid in some other ERC-20 for this service, or it could be an application operator including the transactions of its users for free. -* **Privilege de-escalation**: users can sign sub-keys, and give them specific permissions that are much weaker than global access to the account. For example, you could imagine a permission to spend ERC-20 tokens but not ETH, or to spend up to 1% of total balance per day, or to interact only with a specific application. +* **Privilege de-escalation**: users can sign sub-keys and give them specific permissions that are much weaker than global access to the account. For example, you could imagine a permission to spend ERC-20 tokens but not ETH, or to spend up to 1% of the total balance per day, or to interact only with a specific application. ## Specification @@ -59,7 +63,7 @@ There is a lot of interest in adding short-term functionality improvements to EO | ------------------------ | ------- | | `SET_CODE_TX_TYPE` | `0x04` | | `MAGIC` | `0x05` | -| `PER_AUTH_BASE_COST` | `2500` | +| `PER_AUTH_BASE_COST` | `12500` | | `PER_EMPTY_ACCOUNT_COST` | `25000` | ### Set Code Transaction @@ -83,7 +87,7 @@ tuple cannot fit within the following bounds: assert auth.chain_id < 2**256 assert auth.nonce < 2**64 assert len(auth.address) == 20 -assert auth.y_parity < 2**256 +assert auth.y_parity < 2**8 assert auth.r < 2**256 assert auth.s < 2**256 ``` @@ -95,23 +99,31 @@ The [EIP-2718](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md) `R At the start of executing the transaction, after incrementing the sender's nonce, for each `[chain_id, address, nonce, y_parity, r, s]` tuple do the following: 1. Verify the chain id is either 0 or the chain's current ID. -2. `authority = ecrecover(keccak(MAGIC || rlp([chain_id, address, nonce])), y_parity, r, s]` -3. Add `authority` to `accessed_addresses` (as defined in [EIP-2929](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2929.md).) -4. Verify the code of `authority` is either empty or already delegated. -5. Verify the nonce of `authority` is equal to `nonce`. -6. Add `PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST` gas to the global refund counter if `authority` exists in the trie. -7. Set the code of `authority` to be `0xef0100 || address`. This is a delegation designation. -8. Increase the nonce of `authority` by one. +2. Verify the `nonce` is less than `2**64 - 1`. +3. `authority = ecrecover(keccak(MAGIC || rlp([chain_id, address, nonce])), y_parity, r, s)` + * `s` value must be less than or equal to `secp256k1n/2`, as specified in [EIP-2](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.md). + * `authority` is not present in the block list defined in the Nano hard fork. +4. Add `authority` to `accessed_addresses` (as defined in [EIP-2929](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2929.md).) +5. Verify the code of `authority` is either empty or already delegated. +6. Verify the nonce of `authority` is equal to `nonce`. In case `authority` does not exist in the trie, verify that `nonce` is equal to `0`. +7. Add `PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST` gas to the global refund counter if `authority` exists in the trie. +8. Set the code of `authority` to be `0xef0100 || address`. This is a delegation designation. + * As a special case, if `address` is `0x0000000000000000000000000000000000000000` do not write the designation. Clear the account's code and reset the account's code hash to the empty hash `0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470`. +9. Increase the nonce of `authority` by one. If any of the above steps fail, immediately stop processing that tuple and continue to the next tuple in the list. It will in the case of multiple tuples for the same authority, set the code using the address in the last valid occurrence. Note that the signer of an authorization tuple may be different than `tx.origin` of the transaction. +If transaction execution results in failure (any exceptional condition or code reverting), setting delegation designations is *not* rolled back. + ##### Delegation Designation -The delegation designation uses the banned opcode `0xef` from [EIP-3541](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3541.md) to designate the code has a special purpose. This designator requires all code retrieving operations follow the address pointer to fill the accounts observable code. The following instructions are impacted: `EXTCODESIZE`, `EXTCODECOPY`, `EXTCODEHASH`, `CALL`, `CALLCODE`, `STATICCALL`, `DELEGATECALL`. +The delegation designation uses the banned opcode `0xef` from [EIP-3541](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3541.md) to designate the code has a special purpose. This designator requires all code executing operations to follow the address pointer to get the account's executable code, and requires all other code reading operations to act only on the delegation designator (`0xef0100 || address`). The following reading instructions are impacted: `EXTCODESIZE`, `EXTCODECOPY`, `EXTCODEHASH`, and the following executing instructions are impacted: `CALL`, `CALLCODE`, `STATICCALL`, `DELEGATECALL`, as well as transactions with `destination` targeting the code with delegation designation. + +For example, `EXTCODESIZE` would return `23` (the size of `0xef0100 || address`), `EXTCODEHASH` would return `keccak256(0xef0100 || address)`, and `CALL` would load the code from `address` and execute it in the context of `authority`. -For example, `EXTCODESIZE` would return the size of the code pointed to by `address` instead of `23` which would represent the delegation designation. `CALL` would similarly load the code from `address` and execute it in the context of `authority`. +In case a delegation designator points to a precompile address, retrieved code is considered empty and `CALL`, `CALLCODE`, `STATICCALL`, `DELEGATECALL` instructions targeting this account will execute empty code, i.e. succeed with no execution given enough gas. In case a delegation designator points to another designator, creating a potential chain or loop of designators, clients must retrieve only the first code and then stop following the designator chain. @@ -125,21 +137,35 @@ If a code reading instruction accesses a cold account during the resolution of d #### Transaction Origination -Modify the restriction put in place by [EIP-3607](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3607.md) to allow EOAs whose code is a valid delegation designation, i.e. `0xef0100 || address`, to continue to originate transactions. Accounts with any other code values may not originate transactions. +Modify the restriction put in place by [EIP-3607](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3607.md) to allow EOAs whose code is a valid delegation designation, i.e., `0xef0100 || address`, to continue to originate transactions. Accounts with any other code values may not originate transactions. + +Additionally, if a transaction's `destination` has a delegation designation, add the target of the delegation to `accessed_addresses`. ## Rationale +### Cost of Delegation + +The `PER_AUTH_BASE_COST` is the cost to process the authorization tuple and set the delegation destination. We are able to compute a fair cost for this operation by reviewing its impact on the system: + +* ferry 101 bytes of calldata = `101 * non-zero cost (16) = 1616` +* recovering the `authority` address = `3000` +* reading the nonce and code of `authority` = `2600` +* storing values in already warm account = `200` +* cost to deploy code = `200 * 23 = 4600` + +The impact-based assessment leaves us with `12016` gas for the operation. We round up to `12500` to account for miscellaneous costs associated with shuttling data around the state transition. + ### No initcode -Running initcode is not desirable for many reasons. The chief concern is it's unnatural. Initcode is intended to initialize and deploy contracts. With this EIP, it will take on a new role of determine whether it is appropriate to deploy code to the EOA. Suppose a user only wants code deployed to their account if they also have an operation bundled with the general transaction calldata. This gives EOA a unique power to control when and what code executes in their account. Although [EIP-7702](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7702.md) as written still allows this to a degree, the lack of programmability in the decision will force wallets to not sign many authorization tuples and instead focus signing only a tuple pointing to a configurable proxy. This affords EOAs a similar experience to smart contract wallets +Running initcode is not desirable for many reasons. The chief concern is it's unnatural. Initcode is intended to initialize and deploy contracts. With this EIP, it will take on a new role of determining whether it is appropriate to deploy code to the EOA. Suppose a user only wants code deployed to their account if they also have an operation bundled with the general transaction calldata. This gives EOAs a unique power to control when and what code executes in their account. Although [EIP-7702](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7702.md) as written still allows this to a degree, the lack of programmability in the decision will force wallets to not sign many authorization tuples and instead focus on signing only a tuple pointing to a configurable proxy. This affords EOAs a similar experience to smart contract wallets. -Additionally, initcode in transaction tends to be propagated inside the transaction. That means it would need to be included in the authorization tuple and signed over. The minimum initcode would be around 15 bytes and that would simply copy the contract code from an external address. The total cost would be `16 * 15 = 240` calldata cost, plus the [EIP-3860](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3860.md) cost of `2 * 15 = 30`, plus the runtime costs of around `150`. So nearly `500` additional gas would be spent simply preparing the account; and even more likely, 1200+ gas if not copying from an external account. +Additionally, initcode in a transaction tends to be propagated inside the transaction. That means it would need to be included in the authorization tuple and signed over. The minimum initcode would be around 15 bytes, and that would simply copy the contract code from an external address. The total cost would be `16 * 15 = 240` calldata cost, plus the [EIP-3860](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3860.md) cost of `2 * 15 = 30`, plus the runtime costs of around `150`. So nearly `500` additional gas would be spent simply preparing the account; and even more likely, 1200+ gas if not copying from an external account. ### Creation by template -Initcode or not, there is a question of how users should specify the code they intend to run in their account. The two main options are to specify the bytecode directly in the transaction or to specify a pointer to the code. The simplest pointer would just the address of some code deployed on-chain. +Initcode or not, there is a question of how users should specify the code they intend to run in their account. The two main options are to specify the bytecode directly in the transaction or to specify a pointer to the code. The simplest pointer would just be the address of some code deployed on-chain. -The cost analysis makes the answer clear. The smallest proxy would be around 50 bytes and an address is 20 bytes. The 30 byte difference provides no useful additional functionality and will be inefficiently replicated billions of times on the chain. +The cost analysis makes the answer clear. The smallest proxy would be around 50 bytes, and an address is 20 bytes. The 30 byte difference provides no useful additional functionality and will be inefficiently replicated billions of times on the chain. Furthermore, specifying code directly would again make it possible for EOAs to have a new, unique ability to execute arbitrary code specified in the transaction calldata. @@ -149,7 +175,7 @@ Consistency is a valuable property in the EVM, both from an implementation persp The main families of instructions where a ban was considered were storage related and contract creation related. The decision to not ban storage instructions hinged mostly on their importance to smart contract wallets. Although it's possible to have an external storage contract that the smart contract wallet calls into, it is unnecessarily inefficient. In the future, new state schemes may even allow substantially cheaper access to certain storage slots. This is something smart contract wallets will very much want to take advantage of that a storage contract wouldn't support. -Creation instructions were considered for a ban on other similar EIPs, however because this EIP allows EOAs to spend value intra-transaction, the concern with bumping the nonce intra-transaction and invalidating pending transactions is not significant. A neat byproduct of this is that by combining EIP-7702 and CREATE2 it will be possible to commit to deploy specific bytecode to an address without committing to any fee market parameters. This solves the long standing issue of universal cross-chain contract deployment. +Creation instructions were considered for a ban on other similar EIPs, however because this EIP allows EOAs to spend value intra-transaction, the concern with bumping the nonce intra-transaction and invalidating pending transactions is not significant. ### Signature structure @@ -157,35 +183,35 @@ The signature scheme in this EIP supports flexible design patterns, allowing for #### Code pointer -One consideration when signing a code pointer is what code might that address point to on another chain. For some use cases, it may not be desirable to expend the effort verifying the deployment was deterministic. In such situations, the chain ID can be set to reduce the scope of the authorization. For other situations where universal deployment is preferred, e.g. delegating to a wallet proxy. In these cases, it's possible to set chain ID to 0 for validity on all EIP-7702 chains. Wallet maintainers will be able to hard code a single EIP-7702 authorization message into their wallet so that cross-chain code malleability never becomes a concern. +One consideration when signing a code pointer is what code might that address point to on another chain. For some use cases, it may not be desirable to expend the effort verifying the deployment was deterministic. In such situations, the chain ID can be set to reduce the scope of the authorization. For other situations where universal deployment is preferred, e.g., delegating to a wallet proxy, it's possible to set chain ID to 0 for validity on all EIP-7702 chains. Wallet maintainers will be able to hard code a single EIP-7702 authorization message into their wallet so that cross-chain code malleability never becomes a concern. -An alternative to adding chain ID could be to sign over the code the address points to. This seems to have the benefit of both minimizing the on-chain size of auth tuples while retaining specificity of the actual code running in the account. One unfortunate issue of this format though is that it imposes a database lookup to determine the signer of each auth tuple. This imposition itself seems to create enough complexity in transaction propagation that it is decided to avoid and simply sign over address directly. +An alternative to adding chain ID could be to sign over the code the address points to. This seems to have the benefit of both minimizing the on-chain size of auth tuples while retaining specificity of the actual code running in the account. One unfortunate issue of this format, though, is that it imposes a database lookup to determine the signer of each auth tuple. This imposition itself seems to create enough complexity in transaction propagation that it is decided to avoid and simply sign over the address directly. #### In-protocol revocation -Unlike previous versions of this EIP and EIPs similar, the delegation designation can be revoked at anytime signing and sending a EIP-7702 authorization to a new target with the account's current nonce. Without such action, a delegation will remain valid in perpetuity. +Unlike previous versions of this EIP and similar EIPs, the delegation designation can be revoked at any time by signing and sending an EIP-7702 authorization to a new target with the account's current nonce. Without such action, a delegation will remain valid in perpetuity. ### Self-sponsoring: allowing `tx.origin` to set code Allowing `tx.origin` to set code enables simple transaction batching, where the sender of the outer transaction would be the signing account. The ERC-20 approve-then-transfer pattern, which currently requires two separate transactions, could be completed in a single transaction with this proposal. -Once code exists in the EOA, it's possible for self-sponsored EIP-7702 transactions to have `msg.sender == tx.origin` anytime the code in the EOA dispatches a call. Without EIP-7702, this situation can only ever arise in the topmost execution layer of a transaction. Therefore this EIP breaks that invariant and so it affects smart contracts containing `require(msg.sender == tx.origin)` checks. This check is used for at least three purposes: +Once code exists in the EOA, it's possible for self-sponsored EIP-7702 transactions to have `msg.sender == tx.origin` anytime the code in the EOA dispatches a call. Without EIP-7702, this situation can only ever arise in the topmost execution layer of a transaction. Therefore, this EIP breaks that invariant and so it affects smart contracts containing `require(msg.sender == tx.origin)` checks. This check is used for at least three purposes: 1. Ensuring that `msg.sender` is an EOA (given that `tx.origin` always has to be an EOA). This invariant does not depend on the execution layer depth and, therefore, is not affected. - 2. Protecting against atomic sandwich attacks like flash loans, that rely on the ability to modify state before and after the execution of the target contract as part of the same atomic transaction. This protection would be broken by this EIP. However, relying on `tx.origin` in this way is considered bad practice, and can already be circumvented by miners conditionally including transactions in a block. + 2. Protecting against atomic sandwich attacks like flash loans, which rely on the ability to modify state before and after the execution of the target contract as part of the same atomic transaction. This protection would be broken by this EIP. However, relying on `tx.origin` in this way is considered bad practice, and can already be circumvented by miners conditionally including transactions in a block. 3. Preventing reentrancy. -Examples of (1) and (2) can be found in contracts deployed on Ethereum mainnet, with (1) being more common (and unaffected by this proposal.) On the other hand, use case (3) is more severely affected by this proposal, but the authors of this EIP did not find any examples of this form of reentrancy protection, though the search was non-exhaustive. +Examples of (1) and (2) can be found in contracts deployed on Ethereum mainnet, with (1) being more common (and unaffected by this proposal). On the other hand, use case (3) is more severely affected by this proposal, but the authors of this EIP did not find any examples of this form of reentrancy protection, though the search was non-exhaustive. -This distribution of occurrences—many (1), some (2), and no (3)—is exactly what the authors of this EIP expect, because: +This distribution of occurrences—many (1), some (2), and no (3)—is exactly what the authors of this EIP expect because: - * Determining if `msg.sender` is an EOA without `tx.origin` is difficult (if not impossible.) + * Determining if `msg.sender` is an EOA without `tx.origin` is difficult (if not impossible). * The only execution context which is safe from atomic sandwich attacks is the topmost context, and `tx.origin == msg.sender` is the only way to detect that context. - * In contrast, there are many direct and flexible ways of preventing reentrancy (ex. using a transient storage variable.) Since `msg.sender == tx.origin` is only true in the topmost context, it would make an obscure tool for preventing reentrancy, rather than other more common approaches. + * In contrast, there are many direct and flexible ways of preventing reentrancy (e.g., using a transient storage variable). Since `msg.sender == tx.origin` is only true in the topmost context, it would make an obscure tool for preventing reentrancy, rather than other more common approaches. There are other approaches to mitigate this restriction which do not break the invariant: - * Set `tx.origin` to a constant `ENTRY_POINT` address when using `CALL*` instruction in the context of an EOA. + * Set `tx.origin` to a constant `ENTRY_POINT` address when using the `CALL*` instruction in the context of an EOA. * Set `tx.origin` to a special address derived from the sender or signer addresses. * Disallow `tx.origin` from setting code. This would make the simple batching use cases impossible, but could be relaxed in the future. @@ -197,13 +223,25 @@ Specifically: * The `address` that users sign could literally point to existing ERC-4337 wallet code. * The "code pathways" that are used are code pathways that would, in many cases (though perhaps not all), continue to "make sense" in a pure-smart-contract-wallet world. -* Hence, it avoids the problem of "creating two separate code ecosystems", because to a large extent they would be the same ecosystem. There would be some workflows that require kludges under this solution that would be better done in some different "more native" under "endgame AA", but this is relatively a small subset. +* Hence, it avoids the problem of "creating two separate code ecosystems" because, to a large extent, they would be the same ecosystem. There would be some workflows that require kludges under this solution that would be better done in some different "more native" under "endgame AA", but this is relatively a small subset. * It does not require adding any opcodes, that would become dangling and useless in a post-EOA world. * It allows EOAs to masquerade as contracts to be included in ERC-4337 bundles, in a way that's compatible with the existing `EntryPoint`. +### Clearing Delegation Designations + +A general design goal of state transition changes is to minimize the number of special cases an EIP has. In early iterations, this EIP resisted a special case for clearing an account's delegation designation. + +For most intents and purposes, an account delegated to `0x0` is indistinguishable from a true EOA. However, one particular unfortunate case is unavoidable. Even if a user has a zeroed out delegation designation, most operations that interact with that account will encounter an additional `COLD_ACCOUNT_READ_COST` upon the first touch. + +This is not ideal and may be a significant enough concern to impact the overall adoption of the EIP. For these reasons, we have opted to include a mechanism which allow users to restore their EOA to its original pureness. + +### Delegation of code execution only + +Other code retrieving operations like `EXTCODEHASH` do not automatically follow delegations, they operate on the delegation designator itself. If instead delegations were followed, an account would be able to temporarily masquerade as having a particular codehash, which would break contracts that rely on codehashes as an indicator of possible account behavior. A change of behavior in a contract is currently only possible if its code explicitly allows it (in particular via `DELEGATECALL`), and a change of codehash is only possible in the presence of `SELFDESTRUCT` (and as of Cancun only in the same transaction as contract creation), so choosing to follow delegations in `EXTCODE*` opcodes would have created a new type of account that broke prior assumptions. + ## Backwards Compatibility -This EIP breaks the invariant that an account balance can only decrease as a result of transactions originating from that account. It also breaks the invariant that an EOA nonce may not increase after transaction execution has begun. These breakages have consequences for mempool design, and for other EIPs such as inclusion lists. However, because the accounts are listed statically in the outer transaction it is possible to modify transaction propagation rules so that conflicting transactions are not forwarded. +This EIP breaks the invariant that an account balance can only decrease as a result of transactions originating from that account. It also breaks the invariant that an EOA nonce may not increase after transaction execution has begun. These breakages have consequences for mempool design, and for other EIPs such as inclusion lists. However, because the accounts are listed statically in the outer transaction, it is possible to modify transaction propagation rules so that conflicting transactions are not forwarded. ## Security Considerations @@ -211,7 +249,7 @@ This EIP breaks the invariant that an account balance can only decrease as a res The following is a non-exhaustive list of checks/pitfalls/conditions that delegate contracts *should* be wary of and require a signature over from the account's authority: - * Replay protection -- (ex. a nonce) should be implemented by the delegate and signed over. Without it, a malicious actor can reuse a signature, repeating its effects. + * Replay protection (e.g., a nonce) should be implemented by the delegate and signed over. Without it, a malicious actor can reuse a signature, repeating its effects. * `value` -- without it, a malicious sponsor could cause unexpected effects in the callee. * `gas` -- without it, a malicious sponsor could cause the callee to run out of gas and fail, griefing the sponsee. * `target` / `calldata` -- without them, a malicious actor may call arbitrary functions in arbitrary contracts. @@ -229,7 +267,7 @@ The authors of this EIP believe the risks of allowing this are acceptable for th ### Sponsored transaction relayers -It is possible for the `authorized` account to cause sponsored transaction relayers to spend gas without being reimbursed by either invalidating the authorization (i.e. increasing the account's nonce) or by sweeping the relevant assets out of the account. Relayers should be designed with these cases in mind, possibly by requiring a bond to be deposited or by implementing a reputation system. +It is possible for the `authorized` account to cause sponsored transaction relayers to spend gas without being reimbursed by either invalidating the authorization (i.e., increasing the account's nonce) or by sweeping the relevant assets out of the account. Relayers should be designed with these cases in mind, possibly by requiring a bond to be deposited or by implementing a reputation system. ### Front running initialization @@ -247,6 +285,14 @@ While there are a few mitigations for this, the authors recommend that clients d A related issue is that an EOA's nonce maybe incremented more than once per transaction. Because clients already need to be robust in a worse scenario (described above), it isn't a major security concern. However, clients should be aware this behavior is possible and design their transaction propagation accordingly. +### Storage management + +Changing an account's delegation is a security-critical operation that should not be done lightly, especially if the newly delegated code is not purposely designed and tested as an upgrade to the old one. + +In particular, in order to ensure a safe migration of an account from one delegate contract to another, it's important for these contracts to use storage in a way that avoids accidental collisions among them. For example, using [ERC-7201](https://github.com/ethereum/ercs/blob/master/ERCS/erc-7201.md) a contract may root its storage layout at a slot dependent on a unique identifier. To simplify this, smart contract languages may provide a way of re-rooting the entire storage layout of existing contract source code. + +If all contracts previously delegated to by the account used the approach described above, a migration should not cause any issues. However, if there is any doubt, it is recommended to first clear all account storage, an operation that is not natively offered by the protocol but that a special-purpose delegate contract can be designed to implement. + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-466.md b/BEPs/BEP-466.md new file mode 100644 index 00000000..9d5b1757 --- /dev/null +++ b/BEPs/BEP-466.md @@ -0,0 +1,39 @@ +
+  BEP: 466
+  Title: Make the block header format compatible with EIP-7685
+  Status: Enabled
+  Type: Standards
+  Created: 2024-11-25
+
+ +# BEP-466: Make the block header format compatible with EIP-7685 + +- [BEP-466: Make the block header format compatible with EIP-7685](#bep-466-make-the-block-header-format-compatible-with-eip-7685) + - [Abstract](#abstract) + - [Motivation](#motivation) + - [Specification](#specification) + - [Block Header](#block-header) + - [Copyright](#copyright) + + +## Abstract + +[EIP-7685](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7685.md) adds `requests_hash` to the block header. To achieve compatibility, this element must be defined in BNB Smart Chain (BSC). + +## Motivation + +The goal is to make the block header format compatible with EIP-7685. This allows for shared codebases and APIs between implementations, promoting consistency and interoperability. + +## Specification + +### Block Header + +In line with EIP-7685, the header is extended with a new 32-byte commitment value, `requests_hash`. On BSC: + +1. Collecting `requests` or validating their correspondence with `requests_hash` is not required. +2. After the Prague hard fork, `requests_hash` must not be nil to ensure compatibility with EIP-7685. +3. Include `requests_hash` in the computation when calculating the header signature. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-496.md b/BEPs/BEP-496.md new file mode 100644 index 00000000..cd114757 --- /dev/null +++ b/BEPs/BEP-496.md @@ -0,0 +1,112 @@ +
+  BEP: 496
+  Title: Implement EIP-7623: Increase calldata cost
+  Status: Enabled
+  Type: Standards
+  Created: 2024-12-18
+  Description: Increase calldata cost to reduce maximum block size.
+
+ + +# BEP-496: Implement EIP-7623: Increase calldata cost + +- [BEP-496: Implement EIP-7623: Increase calldata cost](#bep-496-implement-eip-7623-increase-calldata-cost) + - [Abstract](#abstract) + - [Motivation](#motivation) + - [Specification](#specification) + - [Rationale](#rationale) + - [Backwards Compatibility](#backwards-compatibility) + - [Security Considerations](#security-considerations) + - [Copyright](#copyright) + +## Abstract + +The current calldata pricing permits EL payloads of up to 7.15 MB, while the average size is much smaller at around 100 KB. +This EIP proposes adjusting the calldata cost to reduce the maximum possible block size and its variance without negatively impacting regular users. +This is achieved by increasing calldata costs for transactions that predominantly post data. + +## Motivation + +The block gas limit has not been increased since [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), while the average size of blocks has continuously increased due to the growing number of rollups posting data to Ethereum. Moreover, calldata costs have remained unchanged since [EIP-2028](https://eips.ethereum.org/EIPS/eip-2028). +[EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) introduces blobs as a preferred method for data availability (DA). +This transition demands a reevaluation of calldata pricing, especially in order to address the disparity between average and maximum block sizes. +By introducing a floor cost dependent on the ratio of gas spent on EVM operations to calldata, this proposal aims to reduce the maximum block size to make room for additional blobs or potential block gas limit increases. + +## Specification + +| Parameter | Value | +|------------------------------|-------| +| `STANDARD_TOKEN_COST` | `4` | +| `TOTAL_COST_FLOOR_PER_TOKEN` | `10` | + + +Let `tokens_in_calldata = zero_bytes_in_calldata + nonzero_bytes_in_calldata * 4`. + +Let `isContractCreation` be a boolean indicating the respective event. + +Let `execution_gas_used` be the gas used for EVM execution with the gas refund subtracted. + +The current formula for determining the total gas used per transaction (`tx.gasUsed`) is equivalent to: + +```python +tx.gasUsed = ( + 21000 + + STANDARD_TOKEN_COST * tokens_in_calldata + + execution_gas_used + + isContractCreation * (32000 + INITCODE_WORD_COST * words(calldata)) +) +``` + +The formula for determining the gas used per transaction changes to: + +```python +tx.gasUsed = ( + 21000 + + + max( + STANDARD_TOKEN_COST * tokens_in_calldata + + execution_gas_used + + isContractCreation * (32000 + INITCODE_WORD_COST * words(calldata)), + TOTAL_COST_FLOOR_PER_TOKEN * tokens_in_calldata + ) +) +``` + +Any transaction with a gas limit below `21000 + TOTAL_COST_FLOOR_PER_TOKEN * tokens_in_calldata` or below its intrinsic gas cost (take the maximum of these two calculations) is considered invalid. This limitation exists because transactions must cover the floor price of their calldata without relying on the execution of the transaction. There are valid cases where `gasUsed` will be below this floor price, but the floor price needs to be reserved in the transaction gas limit. + +## Rationale + +The current maximum EL payload size is approximately 1.79 MB (`30_000_000/16`). It is possible to create payloads filled with zero bytes that expand to 7.15 MB. However, since blocks are typically compressed with Snappy at the P2P layer, zero-byte-heavy EL payloads generally compress to under 1.79 MB. The implementation of [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) increased the maximum possible compressed block size to approximately 2.54 MB. + +This proposal aims to increase the cost of calldata to 10/40 gas for transactions that do not exceed a certain threshold of gas spent on EVM operations relative to gas spent on calldata. This change will significantly reduce the maximum block size by limiting the size of data-heavy transactions that can fit into a single block. By increasing calldata costs from 4/16 to 10/40 gas per byte for data-heavy transactions, this EIP aims to reduce the maximum possible EL payload size to approximately 0.72 MB (`30_000_000/40`) without affecting the majority of users. + +Notably, regular users (e.g. sending ETH/Tokens/NFTs, engaging in DeFi, social media, restaking, bridging, etc.), who do not use calldata predominantly for DA, may remain unaffected. +The calldata cost for transactions involving significant EVM computation remains at 4/16 gas per byte, so those transactions are unaffected. + +## Backwards Compatibility + +This is a backwards incompatible gas repricing that requires a scheduled network upgrade. + +Wallet developers and node operators MUST update gas estimation handling to accommodate the new calldata cost rules. Specifically: + +1. **Wallets**: Wallets using `eth_estimateGas` MUST be updated to ensure that they correctly account for the `TOTAL_COST_FLOOR_PER_TOKEN` parameter. Failure to do so could result in underestimating gas, leading to failed transactions. + +2. **Node Software**: RPC methods such as `eth_estimateGas` MUST incorporate the updated formula for gas calculation. Node developers MUST ensure compatibility with the updated calldata pricing logic. + +Users can maintain their usual workflows without modification, as wallet and RPC updates will handle these changes. + +## Security Considerations + +As the maximum possible block size is reduced, no security concerns have been raised. + +In some cases, it might seem advantageous to combine two transactions into one to reduce costs. For example, bundling a transaction that relies heavily on calldata but minimally on EVM resources with another that does the opposite. However, this is not a significant concern for several reasons: + +1. This type of bundling is already possible today. Merging multiple transactions can save the 21,000 gas cost for each additional transaction beyond the first, a feature explicitly supported in [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337). +2. Such bundling does not compromise the block size reduction objectives of this EIP. +3. In practice, transaction bundling is often impractical due to challenges such as trust and coordination requirements. + +These factors ensure that transaction bundling does not pose a significant issue. + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP-497.md b/BEPs/BEP-497.md new file mode 100644 index 00000000..82af5559 --- /dev/null +++ b/BEPs/BEP-497.md @@ -0,0 +1,98 @@ +
+  BEP: 497
+  Title: Implement EIP-7691: Blob throughput increase
+  Status: Review
+  Type: Standards
+  Created: 2024-12-18
+  Description: Increase the number of blobs to reach a new target and max of 6 and 9 blobs per block respectively.
+
+ + +# BEP-497: Implement EIP-7691: Blob throughput increase + +- [BEP-497: Implement EIP-7691: Blob throughput increase](#bep-497-implement-eip-7691-blob-throughput-increase) + * [Abstract](#abstract) + * [Motivation](#motivation) + * [Specification](#specification) + + [Parameters](#parameters) + * [Rationale](#rationale) + + [Simplicity](#simplicity) + + [Testable changes](#testable-changes) + + [Update Fraction](#update-fraction) + * [Backwards Compatibility](#backwards-compatibility) + * [Security Considerations](#security-considerations) + * [Copyright](#copyright) + +## Abstract + +This EIP proposes to increase to the number of blobs in a block to provide more scale to Ethereum via L2 solution that rely on L1 data capacity. + +## Motivation + +Ethereum, with its rollup centric roadmap, scales by relying on L2. Since the Dencun fork, the blob gas target and maximum was set to 3/6 respectively. The blob gas limit was arrived at based on a series of big block tests performed on the Ethereum mainnet network as well as a series of testnets. The values were chosen cautiously, as it's extremely hard to predict the exact p2p behaviour of Ethereum mainnet. + +As we now have the Dencun upgrade live, we are able to use monitoring tools to check the network health. Initial monitoring indicates that we have a stable network with the current gas target and the re-org rate is trending downwards. Additionally, analysis on messages in gossipsub indicate that the inclusion of `IDONTWANT` messages could bring us a significant bandwidth savings. This allows us to consider starting a series of big block and blob tests to determine the theoretical headroom we currently have. The EIP specifies a proposed new blob gas target and limit based on the series of tests. + +Additional EIPs such as [EIP-7623](./eip-7623.md) proposes a calldata cost increase which would significantly lower the worst case base block size, thus creating more headroom for a potential blob throughput increase. + +The current long term plan of Ethereum is to implement peerDAS as specified by [EIP-7594](./eip-7594.md), but given the uncertain timelines, this EIP aims to increase the throughput short term to provide some scaling until future solutions are deployed. In order to alleviate valid concerns about solo-stakers, approaches such as the inclusion of a flag indicating the max blobs per block for locally built blocks could be considered. + + +## Specification + +### Parameters + +| Constant | Value | +|------------------------------------------|---------------------| +| `PECTRA_FORK_EPOCH` | `tbd` | +| `MAX_BLOBS_PER_BLOCK_ELECTRA` | `9` | +| `TARGET_BLOBS_PER_BLOCK_ELECTRA` | `6` | +| `MAX_BLOB_GAS_PER_BLOCK` | `1179648` | +| `TARGET_BLOB_GAS_PER_BLOCK` | `786432` | +| `BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA` | `5007716` | + +`MAX_BLOBS_PER_BLOCK_ELECTRA` and `TARGET_BLOBS_PER_BLOCK_ELECTRA` are consumed by the consensus layer clients, and starting at `PECTRA_FORK_EPOCH` replace the respective old max and target values. + +`MAX_BLOB_GAS_PER_BLOCK`, `TARGET_BLOB_GAS_PER_BLOCK` and `BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA` are consumed by the execution layer clients, and starting at `PECTRA_FORK_EPOCH` timestamp replace the old max, target and update fraction values. + +## Rationale + +### Simplicity + +A blob limit increase at the fork transition is relatively straightforward from an implementation perspective. We would need to deploy an increased amount of monitoring around the fork epoch, but after a period of stability we can assume that the blob limit increase was successful, reducing any unexpected co-ordination efforts. + +The EIP aims to minimize the amount of testing and implementation effort from the perspective of the client teams, to allow for more resources to be allocated to peerDAS and other scaling research. + +While this EIP may not achieve the new optimal blob limit, it offers a compromise for a short term increase. + +### Testable changes + +Through the use of big block/blob tests on Ethereum mainnet as well as testnets, we can earn a high degree of certainity that the blob limit increase would not negatively impact the network. These tests as well as the associated analysis can be performed mostly by non-client team entities, with minimal input required. Since the changes are quite contained, the EIP should be able to reduce the risk of the blob limit increase. + +### Update Fraction + +The original target and max values from [EIP-4844](./eip-4844.md) were at a 1:2 ratio. As a consequence, responsiveness to full and empty blob sections was symmetrical: + +* full blobs: basefee increases by ~12.5% +* no blobs: basefee decreases by ~11.1% + +The new target and max values from this EIP are at a 2:3 ratio, which breaks that symmetry.As a consequence, the basefee becomes significantly more responsive to empty blob sections (that are 6 blobs under target) than to full ones (that are 3 blobs over target). This is by design, as it takes two blocks with full blobs in a row to make up for a single block with no blobs. However, it creates the challenge of finding a good compromise base fee sensitivity level. + +The `BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA` value in this EIP is chosen as the mid-point between keeping the responsiveness to full blobs and no blobs constant: + +* full blobs: basefee increases by ~8.2% +* no blobs: basefee decreases by ~14.5% + +## Backwards Compatibility + +The consensus clients would continue to use `MAX_BLOBS_PER_BLOCK` and `TARGET_BLOBS_PER_BLOCK` for the deneb fork and once the `ELECTRA` fork is active, they would use `MAX_BLOBS_PER_BLOCK_ELECTRA` and `TARGET_BLOBS_PER_BLOCK_ELECTRA` respectively. + +The execution clients would continue to use `MAX_BLOB_GAS_PER_BLOCK`, `TARGET_BLOB_GAS_PER_BLOCK` and `BLOB_BASE_FEE_UPDATE_FRACTION` for the cancun fork and once the prague fork is active, they would use `MAX_BLOB_GAS_PER_BLOCK`, `TARGET_BLOB_GAS_PER_BLOCK` and `BLOB_BASE_FEE_UPDATE_FRACTION_ELECTRA` respectively. + +## Security Considerations + +todo + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP-520.md b/BEPs/BEP-520.md new file mode 100644 index 00000000..e605132d --- /dev/null +++ b/BEPs/BEP-520.md @@ -0,0 +1,152 @@ +
+  BEP: 520
+  Title: Short Block Interval Phase One: 1.5 seconds
+  Status: Enabled
+  Type: Standards
+  Created: 2025-02-10
+  Description: To shorten the block interval from 3 seconds to 1.5 seconds.
+
+ +# BEP-520: Short Block Interval Phase One: 1.5 seconds +- [BEP-520: Short Block Interval Phase One: 1.5 seconds](#bep-520-short-block-interval-phase-one-15-seconds) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [4.1 Parlia Changes](#41-parlia-changes) + - [4.1.1 Millisecond Representation in Block Header](#411-millisecond-representation-in-block-header) + - [4.1.2 Increase `initialBackOffTime`](#412-increase-initialbackofftime) + - [4.2 Parameter Changes](#42-parameter-changes) + - [4.2.1 Change Table](#421-change-table) + - [5. Rational](#5-rational) + - [5.1 Epoch and TurnLength](#51-epoch-and-turnlength) + - [5.2 GasLimit and GasLimitBoundDivisor](#52-gaslimit-and-gaslimitbounddivisor) + - [5.3 Blob Related](#53-blob-related) + - [5.4 Contract Parameters](#54-contract-parameters) + - [6. Backward Compatibility](#6-backward-compatibility) + - [6.1 MEV](#61-mev) + - [6.2 Layer 2 Solutions](#62-layer-2-solutions) + - [6.3 Quarterly Auto-Burn](#63-quarterly-auto-burn) + - [6.4.DApp Developers And Users](#64dapp-developers-and-users) + - [6.5 Block Finality](#65-block-finality) + - [7. License](#7-license) + +## 1. Summary +Shorten the block interval from 3 seconds to 1.5 seconds to enable faster transaction confirmation and improve user experience. + +## 2. Abstract +Since its inception, BSC has maintained a 3-second block interval. Shortening this interval can provide quicker transaction confirmations, enhancing user experience. However, this modification presents challenges that require adjustments to the consensus mechanism and network parameters. +There would be two phases to shorten block interval from 3 seconds to 0.75 seconds. +- Phase One: shorten block interval from 3 seconds to 1.5 seconds. +- Phase Two: shorten block interval from 1.5 seconds to 0.75 seconds. + +This BEP is mainly for phase one, but it will also include some description of phase two, as they are highly relevant. + +## 3. Motivation +In a competitive blockchain landscape, users demand faster transaction confirmations. Reducing the block interval will make BSC more competitive and meet user expectations for high-performance blockchains. +And the two phases strategy is to avoid one big step to reduce it to 0.75s directly, which could be too risky, as the overall infrastructure may not be fully ready to this change. Phase two(0.75s) would be carried out after phase one(1.5s) has been verified. + +## 4. Specification +### 4.1 Parlia Changes +#### 4.1.1 Millisecond Representation in Block Header +Before the implementation of this BEP, both block intervals and block times were represented with a minimum unit of `second`. Post - BEP, the minimum unit is changed to `millisecond`. + +Regarding the representation of block time, to maintain maximum compatibility, the unit of `Header.Time` remains `second`. The `millisecond` component is stored in the last two bytes of `Header.MixDigest`. The following Go code snippets illustrate how this is achieved: +```Go +// SetMilliseconds can be called once millisecond representation supported +func (h *Header) SetMilliseconds(milliseconds uint64) { + h.MixDigest = common.Hash(uint256.NewInt(milliseconds % 1000).Bytes32()) +} + +// Ensure Milliseconds is less than 1000 when verifying the block header +func (h *Header) MilliTimestamp() uint64 { + milliseconds := uint64(0) + if h.MixDigest != (common.Hash{}) { + milliseconds = uint256.NewInt(0).SetBytes32(h.MixDigest[:]).Uint64() + } + return h.Time*1000 + milliseconds +} +``` + +#### 4.1.2 Increase `initialBackOffTime` +In the Parlia engine, each block height has a designated in-turn validator responsible for producing the block. If the in-turn validator fails to produce the block in time, a second-priority validator will take over after a delay equal to `initialBackOffTime`. +Current settings: +```Go + initialBackOffTime= time.Duration(1)*time.Second +``` +As the block interval decreases, delayed block propagation will result in more blocks being reorganized each time. To mitigate this issue, the `initialBackOffTime` is set to 2 seconds. +```Go + newInitialBackOffTime= time.Duration(2)*time.Second +``` + +### 4.2 Parameter Changes +As mentioned above, phase one and phase two are highly relevant, their parameter changes will be put in one table for easy comparison. But the parameters of phase two here is only for reference, as it could be changed in the future when phase two is finally delivered. + +#### 4.2.1 Change Table +A multitude of system parameters are configured based on the assumption that the default block interval is 3 seconds. Consequently, when the block interval is altered, these parameters must be adjusted accordingly: +|parameter |type |origin(3s) | phase one(1.5s) | phase two(0.75s)| +|--------|--------|--------|--------|--------| +|Epoch |client parameter |200 |500 |1000| +|GasLimit |client parameter |140M |70M |35M| +|GasLimitBoundDivisor |client parameter |256 |1024 |1024| +|Blob Target |client parameter |3 |3 |3 | +|Blob Maximum |client parameter |6 |6 |6 | +|Blob MinBlocksForBlobRequests |client parameter |524288 |1048576 (524288 × 2) |2097152 (524288 × 4)| +|BSCGovernor.votingPeriod |contract parameter |$votingPeriod |$votingPeriod × 2 |$votingPeriod × 4| +|BSCGovernor.minPeriodAfterQuorum |contract parameter |$minPeriodAfterQuorum |$minPeriodAfterQuorum × 2 |$minPeriodAfterQuorum × 4 | +|SlashIndicator.misdemeanorThreshold |contract parameter |$misdemeanorThreshold |$misdemeanorThreshold × 2 |$misdemeanorThreshold × 4| +|SlashIndicator.felonyThreshold |contract parameter |$felonyThreshold |$felonyThreshold × 2 |$felonyThreshold × 4| +|SlashIndicator.felonySlashScope |contract parameter |$felonySlashScope |$felonySlashScope × 2 |$felonySlashScope × 4| +|BSCValidatorSet.TurnLength |contract parameter |4 |8 |16| +## 5. Rational +### 5.1 Epoch and TurnLength +Within an epoch, some validators may fail to produce blocks as scheduled due to maintenance, system failures, or other issues. This can lead to an increased number of low-difficulty blocks, reducing network stability. When a new epoch begins, the validator set is adjusted, replacing validators that have repeatedly failed to produce blocks as scheduled to maintain network stability. Therefore, the epoch duration must not be too long, or the network’s stability will degrade. + +Since validators now produce blocks consecutively, the epoch length should be set so that each validator has an approximately equal number of block production opportunities within an epoch. + +At validator set transition points, a validator can deliberately delay broadcasting its block. As long as the delay does not exceed the predefined `initialBackOffTime`, the delayed block will still be accepted by the network. Increasing `BSCValidatorSet.TurnLength` effectively mitigates this issue. + +Considering these factors, the epoch length is set to 500, and `TurnLength` to 8. When the block interval is reduced to 1.5 seconds, the epoch duration will increase from 600 to 750 seconds. A 500-block epoch roughly allows 21 validators to produce three full rounds of 8 blocks each. + +### 5.2 GasLimit and GasLimitBoundDivisor +As the block interval shortens, the gas limit per block must decrease accordingly. The gas limit is initially set to decrease to 70M in the phase one hard fork and to 35M in phase two hard fork. + +GasLimitBoundDivisor represents the rate of change in GasLimit. Since the block interval will be reduced by a factor of four after phase two, GasLimitBoundDivisor is increased by the same factor to maintain a consistent rate of GasLimit adjustment to avoid sharp gas limit fluctuation if some validators use a too small or too large gas limit value. + +As GasLimit is not part of consensus, it is calculated based on validators' configuration. So need validators's support to downgrade their gas limit configuration before each hard fork. + +### 5.3 Blob Related +This BEP implementation aims to maintain or enhance the network’s capacity to handle blobs. According to the table, before phase one hard fork, the network handles a target of 1 blob per second (3 blobs/3 seconds). After phase one hard fork, it will be 2 blobs per second(3 blobs/1.5seconds). So there will be 100% improvement in blob processing capacity. + +### 5.4 Contract Parameters +The six parameters—`BSCGovernor.votingPeriod`, `BSCGovernor.minPeriodAfterQuorum`, `BSCValidatorSet.misdemeanorThreshold`, `BSCValidatorSet.felonyThreshold`, `BSCValidatorSet.felonySlashScope`, and `Blob MinBlocksForBlobRequests`—are all measured in block numbers and used to calculate time. Therefore, when the block interval is reduced, the block numbers must be increased proportionally to maintain the same time representation. + +## 6. Backward Compatibility +### 6.1 MEV +After phase one, the block interval will be reduced to 1.5 seconds, a single validator will produce 8 consecutive blocks per turn, keeping the total block production time at 12 seconds (1.5 × 8). However, the shorter block time significantly reduces the collaboration window for searchers, builders, and validators, impacting the current process and requiring adjustments. + +### 6.2 Layer 2 Solutions +In the first phase, `Blob Target` and `Blob Maximum` will not be reduced to avoid impacting existing users. + +### 6.3 Quarterly Auto-Burn +The [Quarterly Auto-Burn](https://www.bnbburn.info/) mechanism also requires adjustment,The block count in the formula is replaced with time, resulting in the new formula: + +$B = (T/3)\*1000/(P+K) \approx (T\*334)/(P+K)$ + +where T represents the number of seconds in the corresponding quarter. + +### 6.4.DApp Developers And Users +**Timing Based on Block Numbers** +The reduction in block intervals affects logic that relies on block numbers for timing, whether in independent services or within smart contracts. A simple solution is to adjust the corresponding block count or avoid using block numbers for timing altogether. + +**Indexing Based on `block.timestamp`** +With the block interval reduced to 0.75 seconds, `block.timestamp`, which has second-level precision, may be the same for consecutive blocks. Therefore, using `block.timestamp` as an index key or for similar purposes requires adjustment. A common solution is to use the block hash instead. + +### 6.5 Block Finality +This BEP will not change the fast finality mechanism, but short block interval could bring some challenges to fast finality, as votes need to be propagated in a shorter time. When fast finality works properly, with this BEP, the average transaction finality time would be reduced from 7.5 seconds to 3.75 seconds. +But if fast finality failed, with TurnLength 8 and ValidatorSize 21, for natural block finality, it will be: +- (with >1/2 validator confirmations): 88(11*8) blocks, that is 132 seconds +- (with >2/3 validator confirmations): 120(15*8) blocks, that is 180 seconds + +## 7. License +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-524.md b/BEPs/BEP-524.md new file mode 100644 index 00000000..f935c4ef --- /dev/null +++ b/BEPs/BEP-524.md @@ -0,0 +1,109 @@ +
+  BEP: 524
+  Title: Short Block Interval Phase Two: 0.75 seconds
+  Status: Enabled
+  Type: Standards
+  Created: 2025-02-18
+  Description: To shorten the block interval from 1.5 seconds to 0.75 seconds.
+
+ +# BEP-524: Short Block Interval Phase Two: 0.75 seconds +- [BEP-524: Short Block Interval Phase Two: 0.75 seconds](#bep-524-short-block-interval-phase-two-075-seconds) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [4.1 Parameter Changes](#41-parameter-changes) + - [4.1.1 Change Table](#411-change-table) + - [4.2 Clear MinerHistory Based on Latest Finalized Blocks](#42-clear-minerhistory-based-on-latest-finalized-blocks) + - [5. Rational](#5-rational) + - [5.1 Parameter Changes](#51-parameter-changes) + - [5.2 Clear MinerHistory Based on Latest Finalized Blocks](#52-clear-minerhistory-based-on-latest-finalized-blocks) + - [6. Backward Compatibility](#6-backward-compatibility) + - [6.1 MEV](#61-mev) + - [6.2 Layer 2 Solutions](#62-layer-2-solutions) + - [6.3 Quarterly Auto-Burn](#63-quarterly-auto-burn) + - [6.4 Block Finality](#64-block-finality) + - [7. License](#7-license) + +## 1. Summary +Shorten the block interval from 1.5 seconds to 0.75 seconds to enable faster transaction confirmation and improve user experience. + +## 2. Abstract +BEP-520 is the phase one to reduce the block interval from 3 seconds to 1.5 seconds. And this BEP is the phase two, which would reduce it further to 0.75 seconds. + +## 3. Motivation +Faster transaction confirmation is a critical and long term goal, with 0.75 seconds block interval, it could meet the requirement of some time sensitive applications. + +## 4. Specification +The overall design specification is similar to BEP-520, so only the parameter changes will be covered in this section. + +### 4.1 Parameter Changes +As mentioned above, phase one and phase two are highly relevant, their parameter changes will be put in one table for easy comparison. + +#### 4.1.1 Change Table +A multitude of system parameters are configured based on the assumption of the default block interval. Consequently, when the block interval is altered, these parameters must be adjusted accordingly: +|parameter |type | origin(3s) | phase one(1.5s) | phase two(0.75s)| +|--------|--------|--------|--------|--------| +|Epoch |client parameter |200 |500 |1000| +|GasLimit |client parameter |140M |70M |35M| +|GasLimitBoundDivisor |client parameter |256 |1024 |1024| +|Blob Target |client parameter |3 |3 |3| +|Blob Maximum |client parameter |6 |6 |6| +|Blob MinBlocksForBlobRequests |client parameter |524288 |1048576 (524288 × 2) |2097152 (524288 × 4)| +|BSCGovernor.votingPeriod |contract parameter |$votingPeriod |$votingPeriod × 2 |$votingPeriod × 4| +|BSCGovernor.minPeriodAfterQuorum |contract parameter |$minPeriodAfterQuorum |$minPeriodAfterQuorum × 2 |$minPeriodAfterQuorum × 4 | +|BSCValidatorSet.misdemeanorThreshold |contract parameter |$misdemeanorThreshold |$misdemeanorThreshold × 2 |$misdemeanorThreshold × 4| +|BSCValidatorSet.felonyThreshold |contract parameter |$felonyThreshold |$felonyThreshold × 2 |$felonyThreshold × 4| +|BSCValidatorSet.felonySlashScope |contract parameter |$felonySlashScope |$felonySlashScope × 2 |$felonySlashScope × 4| +|BSCValidatorSet.TurnLength |contract parameter |4 |8 |16| + +### 4.2 Clear MinerHistory Based on Latest Finalized Blocks +Under the current block producer selection algorithm, if a validator fails to produce a block during its assigned slot, another validator may take over. However, due to the restrictions imposed by `MinerHistory`(as defined in [BEP-404](./BEP-404.md)), the replacement validator may also be ineligible during its own slot, which reduces the overall rate of in-turn block production. + +[BEP-404](./BEP-404.md) introduced logic to clear `MinerHistory` when the validator set changes, preventing this issue from accumulating over time. However, since this BEP will increase the `epochLength` to 1000, such off-schedule production issues can now persist and accumulate within a single epoch. + +To mitigate this, this BEP proposes clearing outdated entries in `MinerHistory` based on the latest finalized block. Any entry with a block number less than or equal to the finalized block number will be removed: + +```Go +MinerHistory map[uint64]Address +latestFinalizedBlockNumber uint64 + +// Clear entries up to the latest finalized block +for blockNumber := range MinerHistory { + if blockNumber <= latestFinalizedBlockNumber { + delete(MinerHistory, blockNumber) + } +} + +``` + +## 5. Rational +### 5.1 Parameter Changes +Refer [BEP-520](./BEP-520.md) +### 5.2 Clear MinerHistory Based on Latest Finalized Blocks +This feature leverages Fast Finality to optimize the selection of block producers, improving the overall rate of in-turn block production. As a result, interactions with the in-turn block producer can be further optimized—for example, in terms of block production, voting, transactions, and the propagation of builder-generated bids to the next in-turn block producer. + +## 6. Backward Compatibility +### 6.1 MEV +After phase two, the block interval will be reduced to 0.75 seconds, a single validator will produce 16 consecutive blocks per turn, keeping the total block production time at 12 seconds (0.75 × 16). However, the shorter block time significantly reduces the collaboration window for searchers, builders, and validators, impacting the current process and requiring adjustments. + +### 6.2 Layer 2 Solutions +`Blob Target` and `Blob Maximum` remain unchanged to preserve compatibility with existing users. At the same time, the increased blob capacity lowers the cost of submitting blob data. + + +### 6.3 Quarterly Auto-Burn +The [Quarterly Auto-Burn](https://www.bnbburn.info/) mechanism also requires adjustment,The block count in the formula is replaced with time, resulting in the new formula: + +$B = (T/3)\*1000/(P+K) \approx (T\*334)/(P+K)$ + +where T represents the number of seconds in the corresponding quarter. + +### 6.4 Block Finality +This BEP will not change the fast finality mechanism, but short block interval could bring some challenges to fast finality, as votes need to be propagated in a shorter time. When fast finality works properly, with this BEP, the average transaction finality time would be reduced from 3.75 seconds to 1.875 seconds. +But if fast finality failed, with TurnLength 16 and ValidatorSize 21, for natural block finality, it will be: +- (with >1/2 validator confirmations): 176(11*16) blocks, that is 132 seconds +- (with >2/3 validator confirmations): 240(15*16) blocks, that is 180 seconds + +## 7. License +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-525.md b/BEPs/BEP-525.md new file mode 100644 index 00000000..735a7f7d --- /dev/null +++ b/BEPs/BEP-525.md @@ -0,0 +1,203 @@ +
+  BEP: 525
+  Title: Validator Dedicated Network
+  Status: Withdrawn
+  Type: Standards
+  Created: 2025-02-19
+  Discussions(optional): https://forum.bnbchain.org/t/call-for-feedbacks-bsc-short-block-interval-validator-dedicated-network-and-direct-mempool/3348
+
+ +# BEP-525: Validator Dedicated Network +- [BEP-525: Validator Dedicated Network](#bep-525-validator-dedicated-network) + - [1. Summary](#1-summary) + - [2. Motivation](#2-motivation) + - [3. Specification](#3-specification) + - [3.1.Validator Dedicated Network(VDN)](#31validator-dedicated-networkvdn) + - [3.2.Messages](#32messages) + - [a.Handshake v1](#ahandshake-v1) + - [b.ContactInfo v1](#bcontactinfo-v1) + - [c.Block v1](#cblock-v1) + - [d.RequestBlockByRange v1](#drequestblockbyrange-v1) + - [e.Vote v1](#evote-v1) + - [f.Transactions v1](#ftransactions-v1) + - [4.Rational](#4rational) + - [5. Backwards Compatibility](#5-backwards-compatibility) + - [5.1 Validator Operator](#51-validator-operator) + - [5.2.RPC Providers And Other Full Nodes Operators](#52rpc-providers-and-other-full-nodes-operators) + - [6. License](#6-license) + +## 1. Summary +This is a new network topology that only accepts validators or nodes authorized by validators. + +## 2. Motivation +- For low network latency between validators: as BSC targets to short its block interval to sub-second, it is quite crucial to reduce the network latency between validators. Current P2P gossip based network is good at broadcasting blocks/transactions to the whole network, but it is not efficient enough, i.e. it would take lots of network bandwidth and also cost non-negligible latency. +- For low transaction latency: transaction latency is one of the key user experiences. Directed TxPool can provide a straight-forward path to deliver transactions to validators, whcih could be much faster comparing to the current gossip based public p2p network. +## 3. Specification +### 3.1.Validator Dedicated Network(VDN) +The general network topology can be described by the following diagram: + +![overview](./assets/BEP-525/3-1-2.png) + +Basically validators would be able to find and connect with each other to reduce the network latency. + +Here is the description of these roles in VDN: +- **VDN-BootNode**: It helps validators discover each other and establish connections, and only validators registered with the staking contract are allowed to connect. +- **Validator**: joins the network through the VDN-BootNode, discover and connect with other validators in the VDN, and exchange messages. +- **Validator-Sentry**(optional): it acts as a bridge between the public network and a validator. Transactions can be sent to this sentry node through RPC calls or through the current P2P protocol, then it will forward transactions to the corresponding validator nodes. It will also broadcast blocks produced by validators to public network. This sentry node is optional, validator can have none, one or even more than one sentry nodes. If validator does not have the sentry node, it will receive RPC call or P2P messages directly from public network, exposing the validator to public network directly could have some security risks. Validator can setup 1 or more sentry nodes, which could make it more robust. The sentry node is quite flexible, validators can even share sentry nodes with other validators to share the network security and also save maintenance effort. +- **Validator-Proxy**(optional): in case validator doesn’t want to expose itself to VDN directly, it could authorise one or more proxy nodes to connect to the VDN. It mainly helps on transmitting messages like blocks/votes/transactions between validators in VDN. + +### 3.2.Messages +There would be a new protocol to define the messages that are broadcasted within VDN. These messages would be transmitted with QUIC protocol and will be based on the pubsub mechanism. All messages are `RLP encoded`. + +#### a.Handshake v1 +Protocol ID: `/bsc/vdn/v1/handshake` + +Request & Response Content: + +``` +( + chainID: uint64 + forkID: [4]byte + genesis_hash: Hash + node_version: string + extend: []byte + pub_key: PublicKey + sign: Signature +) +``` + +`chainID`, `forkID`, `genesis_hash` should be valid value, and `extend` is empty now which is reserved for future usage. Only validators registered with the staking contract are allowed to connect. + +Once the validator connects to any node, it will initiate a handshake. If the verification fails, it will disconnect. + +After the connection is successful, it will periodically send handshakes. Once it finds that the validator is no longer active, it will disconnect. + +#### b.ContactInfo v1 +Protocol ID: `/bsc/vdn/v1/contact_info` + +Request Content: + +``` +( + peer_id: string + pub_key: PublicKey + listen_p2p_addrs: []Address // validator can connect it by the addresses. + cache: []Concact // max 8 cache node's contact + create_time: Time +) +``` + +Response Content: + +``` +( + code: StatusCode +) +``` + +After the validator joins the network, it will periodically send its contact info and also the cached contact info to the network. + +Once it connects to most nodes, it will reduce the sending frequency. + +#### c.Block v1 +Protocol ID: `/bsc/vdn/v1/block` + +Request Content: + +``` +( + block: Block + create_time: Time +) +``` + +Response Content: + +``` +( + code: StatusCode +) +``` + +After the inturn validator packs a block, it will immediately send the block to the next N inturn validators. + +> N refers to the number of validators that produce blocks in the current epoch. + +#### d.RequestBlockByRange v1 +Protocol ID: `/bsc/vdn/v1/req/block_by_range` + +Request Content: + +``` +( + start_height: uint64 + count: uint64 +) +``` + +Response Content: + +``` +( + code: StatusCode + blocks: []Block +) +``` + +When the validator receives the future block, it requests the missing block from the source node. + +#### e.Vote v1 +Protocol ID: `/bsc/vdn/v1/vote` + +Request Content: + +``` +( + vote: Vote + create_time: Time +) +``` + +Response Content: + +``` +( + code: StatusCode +) +``` + +When the validator successfully verifies the block, it sends FF vote to the next N inturn validators. + +#### f.Transactions v1 +Protocol ID: `/bsc/vdn/v1/transactions` + +Request Content: + +``` +( + txs: []Transaction // not exceed 10MB in total msg size +) +``` + +Response Content: + +``` +( + code: StatusCode +) +``` + +When the validator receives the block, it sends the current pending txs to the next inturn validator. + +## 4.Rational +TBD + +## 5. Backwards Compatibility +### 5.1 Validator Operator +Operators would need to change their node's network configuration to integrate VDN. They would need fully understand the new topology and may setup the validator-sentry and validator-proxy node respectively. They may also need to monitor their network quality to provide good network quality. + +### 5.2.RPC Providers And Other Full Nodes Operators +Depends on the strategy of the RPC providers and other full nodes, they may connect to validator-sentry nodes directly, so it would have lower latency and user's transaction would be protected as these transaction would not be leaked to public txpool. But they can also choose to not connect to validator-sentry nodes directly and forward transactions to validators through a different route path. The public network composed by these full nodes will mainly help on block syncing, while transaction will not be gossiped in this public network. + +## 6. License +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-536.md b/BEPs/BEP-536.md new file mode 100644 index 00000000..71ba7178 --- /dev/null +++ b/BEPs/BEP-536.md @@ -0,0 +1,48 @@ +
+  BEP: 536
+  Title: Directed TxPool
+  Status: Withdrawn
+  Type: Standards
+  Created: 2025-02-19
+  Discussions(optional): https://forum.bnbchain.org/t/call-for-feedbacks-bsc-short-block-interval-validator-dedicated-network-and-direct-mempool/3348
+
+ +# BEP-536: Directed TxPool +- [BEP-536: Directed TxPool](#bep-536-directed-txpool) + - [1. Summary](#1-summary) + - [2. Motivation](#2-motivation) + - [3. Specification](#3-specification) + - [3.1.Directed TxPool](#31directed-txpool) + - [4.Rational](#4rational) + - [5. Backwards Compatibility](#5-backwards-compatibility) + - [5.1 MEV and PBS](#51-mev-and-pbs) + - [6. License](#6-license) + +## 1. Summary +Transactions will be forwarded directly to a few validators who are most likely to produce the next block. + +## 2. Motivation +- For MEV protection: validators are the key role in the network, it is reasonable that validators have the highest priority to get the transactions. Directed txpool means transactions would be forwarded to a small subset of validators that are most likely to produce the next block. It could avoid exposing users transactions directly to public txpool, so users would less likely to face malicious MEV attacks. +## 3. Specification + +### 3.1.Directed TxPool +It is another key aspect of VDN, transactions that are broadcasted in VDN would no long be gossip based, on the opposite, they will only be broadcasted to next {N} validators which have the highest priority to propose the next block. The value of {N} is configurable, by default {N} could be three, which means one in-turn validator, one next-in-turn validator and first backup validator which has the highest priority to produce the block in case the in-turn validator failed to generate it in time. + +![overview](./assets/BEP-536/3-2.png) + +## 4.Rational +TBD + +## 5. Backwards Compatibility + +### 5.1 MEV and PBS +This BEP would have great impact to the Proposer-Builder-Separation(PBS) mechanism and MEV(Maximum-Extractable-Value) ecosystem. + +As the public txpool would be gradually replaced by directed txpool, which means transactions would be forwarded to validators directly, consequently: +- MEV searchers would have to get the transactions from validators, which would be more difficult. +- MEV builders can still act as a bridge between searchers and validators, but the impact to searchers would impact builders indirectly. + +The PBS architecture was introduced in [BEP-322: Builder API Specification for BNB Smart Chain](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP322.md), which tries to make MEV more transparent and fully competed. But due to the MEV impact by this BEP, current PBS mechanism would be weaken as well. PBS is useful, as none malicious MEV activities are good for the chain ecosystem, community will try to find a solution to sustain or upgrade the PBS mechanism, so builders will be less impacted. + +## 6. License +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-543.md b/BEPs/BEP-543.md new file mode 100644 index 00000000..fe2ad466 --- /dev/null +++ b/BEPs/BEP-543.md @@ -0,0 +1,154 @@ +
+  BEP: 543
+  Title: opBNB Shorter Block Interval
+  Status: Draft
+  Type: Standards
+  Created: 2025-03-14
+  Description: To shorten opBNB block interval from 1 second to 500 milliseconds.
+
+ +# BEP-543: opBNB Short Block Interval +- [BEP-543: opBNB Short Block Interval](#bep-543-opbnb-short-block-interval) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [4.1 Millisecond Representation in opBNB Block Header](#41-millisecond-representation-in-opbnb-block-header) + - [4.2 Timestamp of RawSpanBatch](#42-timestamp-of-rawspanbatch) + - [4.3 Parameter Changes](#43-parameter-changes) + - [5. Rational](#5-rational) + - [5.1 SeqWindowSize and MaxSequencerDrift](#51-seqwindowsize-and-maxsequencerdrift) + - [5.2 ChannelTimeout and MaxChannelDuration](#52-channeltimeout-and-maxchannelduration) + - [5.3 op-Proposer propose interval](#53-op-proposer-propose-interval) + - [5.4 op-Batcher submit Blob data](#54-op-batcher-submit-blob-data) + - [6. Backward Compatibility](#6-backward-compatibility) + - [6.1 DApp Developers And Users](#61-dapp-developers-and-users) + - [7. License](#7-license) + +## 1. Summary +Shorten the block interval from 1 second to 500 milliseconds to adapt BSC shorter block interval change and also enable faster transaction confirmation, improving user experience. + +## 2. Abstract +BSC has started to shorten block intervals [(BEP-524)](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-524.md) to sub-seconds. As the L2 of BSC, opBNB needs to adapt to the change. As design opBNB’s block interval should be less than BSC’s. +Lower block time intervals can provide quicker transaction confirmation and better user experience. +This BEP is mainly to reduce the opBNB block time from 1 second to 500 milliseconds. + +## 3. Motivation +After BSC network moves to the 750 milliseconds block time interval, opBNB will never be able to sync to the latest cross-chain messages and stop producing blocks. +It is required that opBNB reduces the block time interval to adapt. And besides this, reducing block time intervals will make opBNB more competitive and better meet users’ expectations. + +## 4. Specification + +### 4.1 Millisecond Representation in opBNB Block Header +Referencing [BEP-520](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-520.md), the millisecond time for opBNB is also stored in the `Header.MixDigest`. This field is populated by the value from the `Header.MixDigest` of the BSC. Consequently, +the last two bytes of opBNB's `Header.MixDigest` are utilized to store the BSC millisecond time. To prevent any potential conflicts, opBNB has reserved the first two bytes specifically for its own millisecond time. +After the hard fork, all modules of opBNB will switch from second-level timestamps to millisecond-level timestamps, and a flag will be set in the `Header.MixDigest` field to indicate that it has started storing milliseconds. +This careful structuring ensures compatibility while optimizing both chains' functionality. +The opBNB BlockTime is calculated by op-node and distributed to op-geth through `PayloadAttributes`. Therefore, the millisecond timestamp will be written into `PayloadAttributes` and then copied to the opBNB Block Header. + +```Go +// SetMillisecondTimestamp is used to set millisecond timestamp. +// [32]byte PrevRandao +// [0][1] represent l2 millisecond's mill part. +func (pa *PayloadAttributes) SetMillisecondTimestamp(ts uint64, updateMilliSecond bool) { + pa.Timestamp = hexutil.Uint64(ts / 1000) + if updateMilliSecond { + milliPartBytes := uint256.NewInt(ts % 1000).Bytes32() + pa.PrevRandao[0] = milliPartBytes[30] + pa.PrevRandao[1] = milliPartBytes[31] + + // It is just a marker byte to ensure that the whole is not empty; + // op-geth relies on non-empty to determine that the passed in millisecond timestamp. + pa.PrevRandao[2] = 1 + } +} + +// millisecondes returns milliseconds of header +unc (h *Header) millisecondes() uint64 { + if h.MixDigest == (common.Hash{}) { + return 0 + } + return uint256.NewInt(0).SetBytes2(h.MixDigest[:2]).Uint64() +} + +// MilliTimestamp returns timestamp in milliseconds +func (h *Header) MilliTimestamp() uint64 { + return h.Time*1000 + h.millisecondes() +} + +// SecondsTimestamp returns timestamp in seconds +func (h *Header) SecondsTimestamp() uint64 { + return h.Time +} + +// NextMilliTimestamp returns next block's timestamp in milliseconds +func (h *Header) NextMilliTimestamp() uint64 { + if h.MixDigest == (common.Hash{}) { + return h.Time*1000 + 1000 + } + return h.MilliTimestamp() + 500 +} + +// NextSecondsTimestamp returns next block's timestamp in seconds +func (h *Header) NextSecondsTimestamp() uint64 { + return h.NextMilliTimestamp() / 1000 +} +``` + +To ensure forward compatibility, millisecond timestamps can be identified by checking `h.MixDigest == (common.Hash{})`; if not enabled, the timestamps will continue to be in second-level format. + +* `MilliTimestamp` returns the millisecond-level block timestamp to enable opBNB to support sub-second block production. +* `NextMilliTimestamp` may be called when verifying the time relationship between parent and child blocks. +* `NextSecondsTimestamp` and `SecondsTimestamp` will be called when checking for forks, as forks still use second-level timestamps. + + +### 4.2 Timestamp of RawSpanBatch +`RawSpanBatch` serves as a streamlined storage format for L2Block on opBNB and does not have reserved unused fields for storing millisecond timestamps. The timestamps within `RawSpanBatch` + are converted from second-level timestamps to millisecond timestamps after the hard fork. + +### 4.3 Parameter Changes +A multitude of system parameters are configured based on the assumption that the default block interval is 1 second. Consequently, when the block interval is altered, these parameters must be adjusted accordingly: + + +|parameter |type | origin(1s) | new(500ms)| +|--------|--------|--------|--------| +|L1EpochPollInterval |op-node parameter |3s |1.5s/750ms | +|BlockTime |op-node parameter |1s |500ms | +|MaxSequencerDrift |op-node parameter |1800 |3600/7200 | +|SeqWindowSize |op-node parameter |14400 |28800/57600 | +|ChannelTimeout |op-node parameter |1200 |2400/4800 | +|MaxChannelDuration |op-batcher parameter |32 |64/128 | +|TargetNumFrames |op-batcher parameter |6 |3/2 | + +The items in the list that depend on BSC's block time will have two new values, primarily relying on the timing of the BSC hard forks for [BEP-520](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-520.md) and [BEP-524](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-524.md). + +The BlockTime configuration, which was previously specified in seconds, will transition to a millisecond-based unit. For instance, if it was originally set to 1 to represent 1 second, +it must now be adjusted to 1000 post-upgrade to preserve the same functionality. Additionally, it is advisable to avoid configuring block times shorter than 100 milliseconds. + +## 5. Rational +### 5.1 SeqWindowSize and MaxSequencerDrift +SeqWindowSize and MaxSequencerDrift are measured in block numbers. +SeqWindowSize origin value 14400 means that if opBNB fails and does not recover within 14400 * 3s (BSC BlockTime) = 24 hours, opBNB will be permanently irrecoverable. +MaxSequencerDrift origin value 1800 means that after BSC stops producing blocks, opBNB can still produce blocks, but if it exceeds 1800 * 1s (opBNB BlockTime) = 30 minutes, it will stop producing blocks. +Therefore, although both are measured in block numbers, they indeed reflect a measurement of time. With the forks of BSC and opBNB, the time for handling exceptional situations cannot be shortened, +so these parameters need to be adjusted proportionally. + +### 5.2 ChannelTimeout and MaxChannelDuration +ChannelTimeout and MaxChannelDuration are both measured in BSC block numbers, representing the timeout periods for uploading and downloading L2 blocks in the channel. As the BSC BlockTime shortens, +the configuration for storing the same amount of data in the pipeline needs to be increased proportionally. + +### 5.3 op-Proposer propose interval +The interval for op-proposer to propose the state root remains 3600(30min), instead of 7200(1h), primarily considering the following three points: +* The recovery time after a sequencer restart remains the same or even becomes faster. +* Compatibility for users obtaining withdrawal proofs based on the Block Number (the most recent Block Number divisible by 3600). +* The waiting time for users to prove a withdrawal initiated in opBNB has been reduced from 1 hour to 30 minutes. + +### 5.4 op-Batcher submit Blob data +As [BEP-520](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-520.md) describes, the block handles 1 blob per second, blob maximum is 2. Op-batcher will adjust the configuration item TargetNumFrames accordingly. + +## 6. Backward Compatibility +### 6.1 DApp Developers And Users +The impact on DApp developers and users is similar to that of [BEP-520](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP-524.md), primarily affecting **Timing Based on Block Numbers** and **Indexing Based on block.timestamp**. ​A common solution is to use the block hash instead. + +## 7. License +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-563.md b/BEPs/BEP-563.md new file mode 100644 index 00000000..e30a2a11 --- /dev/null +++ b/BEPs/BEP-563.md @@ -0,0 +1,129 @@ +
+  BEP: 563
+  Title: Enhanced Validator Network
+  Status: Enabled
+  Type: Standards
+  Created: 2025-04-16
+  Description: To make network more efficient between validators.
+
+ +# BEP-563: Enhanced Validator Network +- [BEP-563: Enhanced Validator Network](#bep-563-enhanced-validator-network) + * [1. Summary](#1-summary) + * [2. Status](#2-status) + * [3. Motivation](#3-motivation) + * [4. Specification](#4-specification) + + [4.1 Clarification](#41-clarification) + - [4.1.1 Sentry Node](#411-sentry-node) + - [4.1.2 NodeID](#412-nodeid) + + [4.2 NodeID Registration](#42-nodeid-registration) + - [4.2.1 Update on web page](#421-update-on-web-page) + - [4.2.2 Update on node start](#422-update-on-node-start) + + [4.3 NodeID Verification](#43-nodeid-verification) + + [4.4 Message Propagation](#44-message-propagation) + * [5. Rationale](#5-rationale) + + [5.1 Why add validator’s NodeID](#51-why-add-validators-nodeid) + + [5.2 Why use system contract](#52-why-use-system-contract) + * [6. Backward Compatibility](#6-backward-compatibility) + * [7. License](#7-license) + +## 1. Summary + +This BEP supports adding validator’s NodeID on the system contract, so the validators can identify each other in the p2p network and forward messages more efficiently. + +## 2. Status + +Draft + +## 3. Motivation + +The current BSC P2P network runs well with a 3-second block interval, but after BEP-520 and BEP-524, BSC will achieve a subsecond block interval, which has higher requirements for low message latency. + +The current public P2P network is a permissionless network on a large scale, anyone can join the network. Permissionless is necessary for a decentralized network, but it has several challenges, especially on network latency and efficiency. + +To satisfy the network requirement of subsecond block interval, it is very helpful to have validators recognize each other in the network and be close enough to each other. Meanwhile, core consensus messages, such as Block Message and Vote Message, can be propagated under the new network topology with better network quality. + +## 4. Specification + +### 4.1 Clarification + +Before diving deep into the design doc, try to introduce some common concepts first. + +#### 4.1.1 Sentry Node + +For security purposes, most validators work on the intranet. The Sentry Node is a full node that acts as the validator's public network protection node. It connects to the public network P2P Node and forwards P2P messages. + +Since the sentry node is the proxy node of the validator on the public network, the validator needs to register the sentry's NodeID on the chain. + +#### 4.1.2 NodeID + +NodeID is the public key that's used for encrypting communication. A connection can be established with any P2P peer through IP+Port+NodeID. + +### 4.2 NodeID Registration + +This BEP will upgrade the StakeHub contract; it needs to add new storage slots to save the validator's NodeIDs. + +And there are some rules: + +- NodeIDs update can only be conducted with operatorAddress, agentAddress or consensusAddress. +- Only validators created in stakeHub can add multiple NodeIDs. +- The maximum number of NodeIDs that each validator can register can be changed through governance, 5 by default. + +There are two approaches to update the nodes: + +#### 4.2.1 New Interfaces of StakeHub contract + +The StakeHub system contract will provide two new interfaces to add and remove NodeIDs respectively: + +```solidity + function addNodeIDs(bytes32[] calldata newNodeIDs) external; + function removeNodeIDs(bytes32[] calldata targetNodeIDs) external; +``` + +As mentioned above, only three specific addresses of the validator: `operatorAddress`, `agentAddress`, and `consensusAddress` are permitted to call the two interfaces. Calls from any other address will be reverted. + +#### 4.2.2 Tips for Updating NodeIDs + +To simplify the process of updating NodeIDs, several approaches can be considered: + +- The BNB Chain Staking page can offer a user-friendly interface, allowing users to connect their wallets with operator or agent accounts to easily update NodeIDs. +- The BSC client can provide configuration options for adding or removing NodeIDs. + +It’s important to note that this process is not part of the consensus mechanism, and detailed instructions will be provided later. + +### 4.3 NodeID Verification + +- Retrieve the Latest Validator Node IDs: This can be achieved by subscribing to the NodeIDAdded and NodeIDRemoved events for each block, or by periodically querying the interface getNodeIDs(address[] calldata validatorsToQuery). +- P2P Connection Handling: During the P2P connection process, verify if the connected node matches any of the registered validator Node IDs. If it does, it will be classified as a validator’s sentry node; otherwise, it will be considered a normal node. + +### 4.4 Message Propagation + +Some connection features will be enabled between validators to optimize network congestion and reduce message latency. + +- Transaction: it will not be propagated between validators. +- Block: it will prioritize broadcasting directly to all other connected validators in the network. The specific implementation depends on the client and needs to balance latency and bandwidth. +- Vote: same as block. + +## 5. Rationale + +### 5.1 Why add validator’s NodeID + +Currently, validators often connect to the P2P Network through public full nodes. When producing blocks or sending votes, the connected full nodes may forward the block through multiple hops before reaching other validators. + +By adding validator’s NodeID on the chain, validators can be identified, so the validator/sentry can choose to connect to validators first, and keep a small number of full nodes. + +At the same time, a more efficient message forwarding mechanism can be enabled between validators, better traffic control can be implemented, and the delay of message reception can be further reduced. + +### 5.2 Why use system contract + +The update of the system contract depends on the hardfork, which can maintain consistent registration and query logic for all nodes. + +At the same time, registering the NodeID in the system contract can also maximize decentralization. Any active validator can be updated at any time and can quickly establish an efficient P2P connection with other validators. + +## 6. Backward Compatibility + +This BEP requires a hard fork to upgrade the system contract and keep the logic of all nodes consistent. + +## 7. License + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-564.md b/BEPs/BEP-564.md new file mode 100644 index 00000000..53df0181 --- /dev/null +++ b/BEPs/BEP-564.md @@ -0,0 +1,96 @@ +
+  BEP: 564
+  Title: bsc/2 - New Block Fetching Messages
+  Status: Enabled
+  Type: Standards
+  Created: 2025-04-16
+  Description: To accelerate block fetching for shorter block interval.
+
+ +# BEP-564: bsc/2 - New Block Fetching Messages +- [BEP-564: bsc/2 - New Block Fetching Messages](#bep-564-bsc2---new-block-fetching-messages) + * [1. Summary](#1-summary) + * [2. Status](#2-status) + * [3. Motivation](#3-motivation) + * [4. Specification](#4-specification) + + [4.1 Block Fetching Message](#41-block-fetching-message) + * [5. Rationale](#5-rationale) + + [5.1 Why new block fetching messages](#51-why-new-block-fetching-messages) + * [6. Forward Compatibility](#6-forward-compatibility) + + [6.1 eth/69 protocol](#61-eth69-protocol) + * [7. Backward Compatibility](#7-backward-compatibility) + + [7.1 eth/68 protocol](#71-eth68-protocol) + * [8. License](#8-license) + +## 1. Summary + +This BEP introduces new block fetching messages to speed up the import of newly generated blocks, prevent nodes from lagging at subsecond block intervals, and especially improve validator consensus efficiency. + +## 2. Status + +Draft + +## 3. Motivation + +With the future activation of BEP-520 and BEP-524, BSC will achieve a subsecond block interval, which has higher requirements for faster block fetching. + +However, the eth/68 protocol is very inefficient when processing NewBlockHash messages, and it requires multiple queries before a new block can be imported. + +This BEP introduces a New Block Fetching Message, which greatly reduces the number of queries, supports fast fetching of newly generated blocks, avoids validators and full nodes from lagging behind in the subsecond block interval, and especially improves the validator consensus efficiency, which can produce the next block or send vote faster. + +## 4. Specification + +### 4.1 Block Fetching Message + +Current block querying is inefficient, requiring multiple requests for both block headers and block bodies. This BEP will add the following messages to reduce the delay in obtaining blocks. + +```go +const ( + GetBlocksByRangeMsg = 0x02 // it can request (Head-n, Head] range blocks from remote peer + BlocksByRangeMsg = 0x03 // the replied blocks from remote peer +) + +type GetBlocksByRangePacket struct { + RequestId uint64 + StartBlockHeight uint64 // The start block height expected to be obtained from + StartBlockHash common.Hash // The start block hash expected to be obtained from + Count uint64 // Get the number of blocks from the start +} + +type BlocksByRangePacket struct { + RequestId uint64 + Blocks []*types.Block +} +``` + +The peer can request a range of blocks, specifying the starting block using either StartBlockHeight or StartBlockHash. If StartBlockHash is not equal to the empty hash (0x0000000000000000000000000000000000000000000000000000000000000000), the starting block will be determined by StartBlockHash. Otherwise, it will default to StartBlockHeight. + +When specifying a StartBlockHeight or StartBlockHash and a Count, the blocks will be returned in reverse order, starting from the given block and going backward. + +This method is used to synchronize the latest small range of blocks quickly. Historical block synchronization still uses the eth/68 protocol. + +![](assets/BEP-564/image1.png) + +## 5. Rationale + +### 5.1 Why new block fetching messages + +The eth/68 protocol fetches the block header and body from the remote separately and assembles them locally. These messages are also applicable to full sync and snap sync processes, and it can save bandwidth when fetching the fork or bad blocks. + +However, multiple queries will multiply the latency between nodes. After subsecond block interval, fetching the block quickly is the key. New block fetching messages simplify the process of fetching blocks and support requesting a range of blocks with only one round trip. + +## 6. Forward Compatibility + +### 6.1 eth/69 protocol + +The bsc/2 is completely independent of the ETH series of protocols, so future upgrades to eth/69 are fully compatible. + +## 7. Backward Compatibility + +### 7.1 eth/68 protocol + +There should be no impact on eth/68. When obtaining the block announced by NewBlockHash, bsc/2 can work simultaneously with eth/68. Due to the low efficiency of eth/68 fetch, bsc/2 will fetch the block first. After the client marks the current block as known, eth/68 will no longer continue to request. + +## 8. License + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-590.md b/BEPs/BEP-590.md new file mode 100644 index 00000000..779a97bf --- /dev/null +++ b/BEPs/BEP-590.md @@ -0,0 +1,94 @@ +
+  BEP: 590
+  Title: Extended Voting Rules for Fast Finality Stability
+  Status: Enabled
+  Type: Standards
+  Created: 2025-06-25
+  Description: Enhance the robustness of Fast Finality by extending aggregate vote inclusion rules.
+
+ +# BEP-590: Extended Voting Rules for Fast Finality Stability + +- [BEP-590: Extended Voting Rules for Fast Finality Stability](#bep-590-extended-voting-rules-for-fast-finality-stability) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [4.1 Aggregate Vote Rule Changes](#41-aggregate-vote-rule-changes) + - [5. Security](#5-security) + - [6. Backward Compatibility](#6-backward-compatibility) + - [7. License](#7-license) + +## 1. Summary + +This BEP proposes an extension to the aggregate vote inclusion rules in the Fast Finality (FF) protocol of the BNB Smart Chain. The change aims to improve the stability and liveness of Fast Finality under adverse network conditions and support further reductions in block interval. + +## 2. Abstract + +[BEP-126](./BEP126.md) introduced Fast Finality as a mechanism for deterministic block finalization in BNB Smart Chain. Under the original design: + +* Proposers (miners) may only aggregate votes for their direct parent block. + +Formally, if `KAncestorGenerationDepth` defines the inclusion scope, then in the original design: + +``` +KAncestorGenerationDepth = 1 +``` + +This BEP extends the scope by allowing `KAncestorGenerationDepth > 1`: + +* **Aggregate Vote Inclusion Extension** — Proposers may include votes for up to `KAncestorGenerationDepth` recent ancestor blocks, improving tolerance to vote propagation latency. + +This adjustment enhances the resilience of Fast Finality during periods of network congestion, without modifying the core consensus model or cryptographic assumptions. + +## 3. Motivation + +Validators can experience latency in receiving, verifying, and casting votes for blocks. Such delays may lead to missing justifications, which in turn hinders finalization. + +Additionally, as block intervals shorten, inter-region network latency becomes a more prominent bottleneck in vote propagation. + +This BEP addresses these issues by introducing: + +* **More flexible vote aggregation** — to increase the chances of including valid votes despite network delays. + +## 4. Specification + +This BEP introduces modifications to the **Aggregate Vote Inclusion Rules**. + +### 4.1 Aggregate Vote Rule Changes + +To improve vote inclusion under delayed network conditions, proposers are allowed to aggregate votes for recent ancestor blocks. The process follows this priority sequence: + +1. Attempt to aggregate votes for the **immediate parent block**. +2. If unavailable, try the **grandparent block**. +3. Continue iteratively up to `KAncestorGenerationDepth` recent ancestors. + +The process **terminates immediately** once any valid vote is included. At most **one ancestor block’s votes** may be aggregated in a single proposal. + +This rule gives validators up to `KAncestorGenerationDepth` block intervals to propagate their votes, improving the success rate of vote inclusion and reducing justification gaps during periods of network latency. + +With [the block interval reduced to 0.45s](./BEP-619.md), the parameter `KAncestorGenerationDepth` is set to 3. +``` + KAncestorGenerationDepth = 3 +``` + +## 5. Security + +This BEP does **not** alter the core safety assumptions or mechanisms of Fast Finality defined in [BEP-126](./BEP126.md). Specifically, it **does not change**: + +* **Validator Vote Rules** — which govern when and how validators may issue votes. +* **Finality Rules** — including thresholds for justification and finalization. +* **Longest Chain Rule** — the fork-choice rule determining canonical chain selection. + +This proposal only modifies the **vote aggregation scope** to improve vote inclusion flexibility. +All original safety guarantees, including one-block finality under an honest super majority, remain **intact**. + +## 6. Backward Compatibility + +This BEP is **not backward compatible** with older clients, as it changes vote aggregation behavior. However, it introduces no changes to protocol-level message formats or user-facing APIs. + +A full client upgrade across validators and block producers is required to activate the changes and maintain consensus. + +## 7. License + +The content is licensed under [Creative Commons CC0 1.0 Universal License](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP-592.md b/BEPs/BEP-592.md new file mode 100644 index 00000000..01dd18a0 --- /dev/null +++ b/BEPs/BEP-592.md @@ -0,0 +1,141 @@ +
+  BEP: 592
+  Title: Non-Consensus Based Block-Level Access List
+  Status: Candidate
+  Type: Standards
+  Created: 2025-06-30
+  Description: A non-consensus block-level access list mechanism that preloads storage data to accelerate block execution and improve network throughput.
+
+ +# BEP-592: Non-Consensus Based Block-Level Access List + +## Table of Contents +- [BEP-592: Non-Consensus Based Block-Level Access List](#bep-592-non-consensus-based-block-level-access-list) + - [Table of Contents](#table-of-contents) + - [1. Summary](#1-summary) + - [2. Status](#2-status) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [4.1 Parameters](#41-parameters) + - [4.2 Data Structure](#42-data-structure) + - [4.3 BAL Generation](#43-bal-generation) + - [4.4 BAL Propagation and bsc/3 P2P Protocol](#44-bal-propagation-and-bsc3-p2p-protocol) + - [4.5 BAL Storage](#45-bal-storage) + - [4.6 BAL Execution](#46-bal-execution) + - [5. Rationale](#5-rationale) + - [5.1 Why not include the slot value in BAL?](#51-why-not-include-the-slot-value-in-bal) + - [5.2 Why not define a new block header element for BAL?](#52-why-not-define-a-new-block-header-element-for-bal) + - [5.3 Any incentive/slash for a validator to generate BAL?](#53-any-incentiveslash-for-a-validator-to-generate-bal) + - [6. Forward Compatibility](#6-forward-compatibility) + - [7. Backward Compatibility](#7-backward-compatibility) + - [8. License](#8-license) + +## 1. Summary + +This BEP introduces Block-Level Access Lists (BAL) - metadata attached to blocks that enables concurrent preloading of storage data during block import. By caching frequently accessed accounts and storage slots, BAL reduces block execution latency and improves overall network throughput. + +## 2. Status + +Draft + +## 3. Motivation + +The primary objective is to enhance BSC's performance by providing access lists during the mining phase. With shorter block intervals and increasing throughput demands, faster block importing becomes crucial for several key stakeholders. + +BAL addresses this by enabling concurrent data preloading, benefiting key network participants: + +- **MEV Builders**: Earlier bid simulation with reduced latency +- **Fast Finality**: Accelerated validator voting improves stability +- **Validators**: More time for block mining, espcially the first consecutive block +- **Full Nodes**: Faster chain synchronization and catch-up + +## 4. Specification + +### 4.1 Parameters + +The following constants define the operational parameters for BAL: + +| Constant | Value | Description | +|----------|-------|-------------| +| `MAX_BAL_BYTES` | `1048576` | Maximum BAL size in bytes (1MB) | +| `DEFAULT_HISTORICAL_BAL` | `360000` | Default blocks to persist BAL data (~3.1 days) | + +### 4.2 Data Structure + +BAL preserves existing block structures by attaching as an optional component at the block's end, maintaining full backward/forward compatibility. The layout of the block content with BAL can be described by the fowllowing diagram: + +Block layout with BAL + +The BAL data structure is defined as follows: + +```go +// StorageAccessItem is a single storage key that is accessed in a block. +type StorageAccessItem struct { + TxIndex uint32 // index of the first transaction in the block that accessed the storage + Dirty bool // true if the storage was modified in the block, false if it was read only + Key common.Hash +} + +// AccountAccessListEncode & BlockAccessListEncode are for BAL serialization. +type AccountAccessListEncode struct { + TxIndex uint32 // index of the first transaction in the block that accessed the account + Address common.Address + StorageItems []StorageAccessItem +} + +type BlockAccessListEncode struct { + Version uint32 // Version of the access list format + Number uint64 // number of the block that the BAL is for + Hash common.Hash // hash of the block that the BAL is for + SignData []byte // sign data for BAL + Accounts []AccountAccessListEncode +} + +``` +Key components: +- `SignData`: 65-byte validator signature using consensus key +- `Version`: Protocol upgrade support (starts at zero) +- Encoding: RLP format following BSC standards (SSZ considered for future versions) + +### 4.3 BAL Generation + +Validators are responsible for generating BAL content during block creation. As validators execute transactions sequentially to create a block, they have complete knowledge of the accounts and storage slots that the block will access. Validators maintain these access lists, sign, encode and attach the result to the end of the block. BAL may contain partial access information due to size constraints, the size of RLP encoded BAL content should not exceed `MAX_BAL_BYTES`. + +### 4.4 BAL Propagation and bsc/3 P2P Protocol + +BAL data will be propagated along with the block as an optional part. But the BAL will only be propagated to peers which supports bsc/3 p2p protocol. The bsc/3 protocol extends bsc/2 with BAL processing capabilities, ensuring backward compatibility. + +### 4.5 BAL Storage + +BAL storage is optional due to its size and primary use for block import acceleration. Nodes may choose retention policies, with a default of `DEFAULT_HISTORICAL_BAL` blocks. + +### 4.6 BAL Execution + +BAL v0 operates as a non-consensus optimization - no validation required. Nodes parse incoming BAL data and preload specified accounts/storage into cache concurrently with block processing, accelerating execution without affecting consensus safety. + +## 5. Rationale + +### 5.1 Why not include the slot value in BAL? + +Excluding slot values maintains size efficiency. A typical block with 200 transactions accessing 50 slots each would require 320KB just for keys. Including values would also require MPT proofs for verification, dramatically increasing BAL size and negating performance benefits. + +### 5.2 Why not define a new block header element for BAL? + +The current approach prioritizes simplicity and compatibility. While header integration remains possible for future versions, attaching BAL as optional data maintains backward compatibility while delivering immediate performance benefits. + +### 5.3 Any incentive/slash for a validator to generate BAL? + +No incentive or penalty mechanisms exist initially - BAL generation is voluntary. Malicious BAL construction has limited impact due to its non-consensus nature, size constraints, and use solely for optimization. The design relies on validators' natural incentive to improve network performance. + +## 6. Forward Compatibility + +BAL's version field enables seamless protocol evolution. Future versions can introduce new features, encoding schemes (like SSZ), or structural enhancements while maintaining compatibility with v0 implementations. + +## 7. Backward Compatibility + +BAL maintains complete backward compatibility by operating as optional block metadata. Non-supporting nodes continue normal operation without consensus or validation impact, ensuring smooth network-wide deployment. + +## 8. License + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + diff --git a/BEPs/BEP-593.md b/BEPs/BEP-593.md new file mode 100644 index 00000000..fd17d2ee --- /dev/null +++ b/BEPs/BEP-593.md @@ -0,0 +1,118 @@ +
+  BEP: 593
+  Title: Incremental Snapshot
+  Status: Enabled
+  Type: Standards
+  Created: 2025-07-02
+  Description: To make easier for users to start and run BSC nodes.
+
+ +# BEP-593: Incremental Snapshot + +- [BEP-593: Incremental Snapshot](#bep-593-incremental-snapshot) +- [1. Summary](#1-summary) +- [2. Status](#2-status) +- [3. Motivation](#3-motivation) +- [4. Specification](#4-specification) + - [4.1 Incremental Snapshot Schema](#41-incremental-snapshot-schema) + - [4.2 Incremental Snapshot Generation](#42-incremental-snapshot-generation) + - [4.3 Incremental Snapshot Merge](#43-incremental-snapshot-merge) +- [5. Rational](#5-rational) + - [5.1 Incremental Snapshot Size](#51-incremental-snapshot-size) + - [5.2 Safety](#52-safety) +- [6. Backward Compatibility](#6-backward-compatibility) +- [7. License](#7-license) + +# 1. Summary + +This BEP proposes an incremental snapshot mechanism to make it easier for users to start and run BSC nodes with reduced data requirements. By implementing this feature, users will be able to bootstrap their nodes more efficiently while maintaining the necessary functionality for participating in the BSC network. + +Incremental snapshots store incremental block and state data, allowing users to quickly approach the latest block by merging incremental snapshots on top of a [monthly snapshot](https://github.com/bnb-chain/bsc-snapshots?tab=readme-ov-file#mainnetmonthly-update). Compared to the newest prune-ancient snapshot, whose size is greater than 1.0 TB, the monthly incremental snapshot is about 120GB, so users can download some incremental snapshots and merge them can start BSC nodes quickly. + +# 2. Status + +Draft + +# 3. Motivation + +The snapshot of BSC is released monthly, and it usually takes users about 13 hours to download, decompress the snapshot(3 hours), and catch up to the newest block(10 hours). + +

+ storage_compare +

+ +Comparing the full snapshot from June 2025 (total size of 3.72TB) with the one from December 2023 (total size of 2.49TB) reveals that the snapshot has grown significantly, reaching an increase of 49.35%. This will result in longer download and decompression times for users, as well as higher demands on machine disk space and bandwidth usage. This becomes a barrier for users who want to participate in the BSC network. + +To address these challenges, this BEP proposes the incremental snapshot solution. This approach will allow users to more easily catch up with the latest BSC data by downloading smaller, incremental updates rather than a single large snapshot. This will improve the user experience and make it more accessible for new participants to join the BSC network. + +# 4. Specification + +

+ storage_compare +

+ +Execute blocks based on a base snapshot, with a separate backup of the incremental data for each block. Periodically aggregate these incremental data(e.g., fixed at 1000 blocks). + +## 4.1 Incremental Snapshot Schema + +This section describes which data needs to be recorded during block execution for Incremental Snapshot aggregation. The data can be divided into two categories: Block data and State data. + +- Block data mainly includes: BlockHeader, BlockHash, BlockBody, TxReceipt, Difficulty, and BlobSidecar. +- State data includes: StateHistory, which is used for PBSS rollback, and StateTrieNodes, which are used to generate the latest state data during Merge Incremental Snapshot. + +After the Maxwell hard fork, there will be approximately 3,456,000 blocks in one month, with an average size of about 100KB. The total size is roughly 345.6GB. The state trie nodes updated by each block amount to about 2MB, with a total size of approximately 6.92TB. Due to the large volume of data, the download speed for users will be slow. + +Therefore, the following adjustments have been made: + +- Block data only needs to store the most recent several tens of thousands of blocks, similar to pruning ancient snapshots, less than 10GB. +- State data can be aggregated, keeping the size around 100GB. + +## 4.2 Incremental Snapshot Generation + +During startup, add the `--incr.enable` flag. The system will asynchronously generate incremental snapshots in a separate directory, and when the data volume reaches a certain threshold, it will automatically switch to a new directory. Generally, regular users do not need to run nodes with the `-- incr.enable` flag. The official nodes are configured with the `--incr.enable` flag and periodically upload incremental snapshots to remote storage for download by users. + +Additional incremental snapshot generation flags: + +- `--incr.datadir` is used to set data directory for storing generated incremental snapshot data. +- `--incr.block-interval` can be used to set how many blocks interval are stored into one incremental snapshot. Default value is `100_000`. +- `--incr.state-buffer` is used to set the incr state memory buffer to aggregate MPT trie nodes. The larger the setting, the smaller the incr snapshot size, it also needs large memory. The default value is `6GB`. +- `--incr.kept-blocks` is used to set how many blocks are kept in incr snapshot. At least and default value is `1024` blocks. + +## 4.3 Incremental Snapshot Merge + +Add the `--incr.use-remote` flag, and also set the remote incremental snapshot URL using the `--incr.remote-url` flag with `--incr.datadir` to store the downloaded incremental snapshots. After startup, the system will automatically download the required incremental snapshots and perform merging. The incremental snapshots are downloaded sequentially, and the download and merge processes run in a pipeline manner, which significantly improves efficiency. + +During the merge, both block data and state data are written into PebbleDB, and necessary metadata such as `HeadHeader`, `HeadBlock`, etc., are updated to ensure continuity from the latest merged block. Once all incremental snapshots are merged, the client switches to full mode to continue block synchronization from P2P. + +# 5. Rational + +## 5.1 Incremental Snapshot Size + +Prune ancient snapshots to only keep the most recent 360,000 blocks of block data. Keeping the last 10,000 blocks of incremental snapshots is sufficient, around 1GB. + +State data can be aggregated. According to testing, 10GB of space can accommodate the state data for 300,000 blocks, after the hard fork on Maxwell. The total size of the state data can be reduced to ~120GB per month. + +An incremental snapshot is generated once a week. Each incremental snapshot contains the latest 10,000 blocks of block data, approximately 1 GB, and the corresponding state data, with the state data size being approximately 30GB per month (around 120GB per month). Total size approximately 31GB. + +For example, an incremental snapshot representing the block range from 50,000,000 to 50,806,400(one week) would only retain the latest 10,000 blocks of data, covering from 50,796,400 to 50,806,400, ~1GB. The state data must fully include all the change data within the 50,000,000 to 50,806,400 range, but it will be aggregated into several files, each around 10GB in size. It will generate three 10GB state data files. An incremental snapshot is about 31 GB, and it is expected to have 4 incremental snapshots per month, total size of about 124 GB. + +Currently, the size of pruned ancient snapshots is around 1TB. Users' local data is less than one year behind the latest block, so using the “--syncmode snap.increment” mode is worthwhile. + +## 5.2 Safety + +Incremental snapshots allow the local data to quickly jump to a relatively recent state before starting synchronization, thereby reducing the distance to the latest block and improving synchronization speed. The reason why merging incremental snapshots is faster than P2P is mainly because it bypasses the execution and validation phases, essentially only involving the commit phase. + +Incremental snapshots essentially allow the user's local data to quickly chang to a recent pruned ancient snapshot through a centralized method. Its security is equivalent to downloading pruned ancient snapshots. + +# 6. Backward Compatibility + +This BEP maintains full backward compatibility with existing BSC node implementations. Users have the flexibility to choose between two approaches: + +1. Traditional full snapshot: Users can continue to use the complete snapshot as before, which contains all historical data. +2. Incremental snapshot: Users can opt to use the new incremental snapshot mechanism, which provides smaller, more manageable updates. + +The implementation ensures that both methods are fully supported, allowing users to select the approach that best suits their needs and resources. This dual-support system ensures a smooth transition for existing users while providing new options for those who prefer the incremental approach. + +# 7. License + +All the content are licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-594.md b/BEPs/BEP-594.md new file mode 100644 index 00000000..abeb6c2b --- /dev/null +++ b/BEPs/BEP-594.md @@ -0,0 +1,115 @@ +
+  BEP: 594
+  Title: L2 Fast Withdrawal by TEE
+  Status: Draft
+  Type: Standards
+  Created: 2025-07-10
+  Description: Reduce the L2 withdrawal finalization time from 7 days to seconds-level.
+
+ +# BEP-594: L2 Fast Withdrawal by TEE +- [BEP-594: L2 Fast Withdrawal by TEE](#bep-594-l2-fast-withdrawal-by-tee) + * [1. Summary](#1-summary) + * [2. Status](#2-status) + * [3. Motivation](#3-motivation) + * [4. Specification](#4-specification) + + [4.1 Fast withdrawal workflow](#41-fast-withdrawal-workflow) + + [4.2 Architecture changes](#42-architecture-changes) + + [4.3 Contract Interface changes](#43-contract-interface-changes) + * [5. Rational](#5-rational) + + [5.1 Why choose the TEE solution](#51-why-choose-the-tee-solution) + + [5.2 Security](#52-security) + * [6. Backward Compatibility](#6-backward-compatibility) + * [7. License](#7-license) + +## 1. Summary + +This BEP proposes a solution by TEE to reduce the L2 withdrawal finalization time from 7 days to seconds-level. + +## 2. Status + +Draft + +## 3. Motivation + +Asset withdrawals from opBNB to BSC, implemented via an optimistic rollup approach, typically rely on a challenge period (often 7 days) to verify state transitions, resulting in significant delays that cause a poor user experience. + +Referencing the [Base Fast Withdrawal solution](https://blog.base.dev/scaling-with-base-appchains), opBNB proposes an approach leveraging AWS Nitro TEE technology, which reduces the L2 withdrawal finalization time on L1 from several days to just seconds. In the future, our solution will be able to integrate with other standard TEE solutions, providing users with more choices. + +## 4. Specification + +### 4.1 Fast withdrawal workflow + +The following diagram shows the fast withdrawal workflow from a user’s perspective. + +

+ workflow +

+ +User submits an initial withdrawal tx to L2 in step1, and submits a prove & finalize withdrawal tx to L1 in step9. This workflow takes about 30 seconds in total, of which step 4 takes up most of the time. To reduce the time consumption of the whole workflow, the following was included: +* When the op-batcher detects a withdrawal transaction on the L2 unsafe block, it will immediately upload the L2 batches to L1 in step3, rather than waiting until the L2 block data is full. +* When the op-proposer detects a withdrawal transaction on the L2 safe block, it will immediately aggregate, rather than waiting for a certain number of proposals to aggregate, and then send the transaction to update the L2OutputOracle contract. + +### 4.2 Architecture changes + +The following diagram illustrates the overall architecture, primarily explaining the changes made to the architecture and highlighting the location of the newly added op-enclave module within the opBNB system. + +

+ arch +

+ +* op-enclave: It runs the stateless clients in AWS Nitro TEE, passing all the information required for the OP Stack to execute a given block. + +* op-proposer: It interfaces with the TEE running the op-enclave. It maintains an up-to-date proven state and, upon detecting a withdrawal, ensures the proof includes that block before submitting the proposal to L1. op-proposer only proposes safe blocks (post-batch submission), and if no withdrawals occur, it submits a proof every 30 minutes to keep the state current. + +* op-batcher: It posts transaction batches for deriving the L2 state. The batcher is modified such that if a block contains a withdrawal event, the batcher immediately treats the current channel as full and submits the batch to L2. This prioritizes withdrawal transactions for rapid processing. The batcher will also submit a batch every 15 seconds if no withdrawals are seen. + +### 4.3 Contract Interface changes + +The op-proposer produces a verifiable proposal for each block by TEE stateless execution(op-enclave). It aggregates periodically to merge these verifiable proposals to reduce submission frequency and gas fees, and then submits the result to the L2OutputOracle contract for withdrawal proofs. + +The structure of the Proposal is as follows: +```go +type Proposal struct { + OutputRoot common.Hash + Signature hexutil.Bytes + L1OriginHash common.Hash + L2BlockNumber *hexutil.Big +} +``` + +The Signature is generated by signing the Proposal with an ECDSA private key that belongs to TEE. During initialization, TEE registers the ECDSA public key to the L1 L2OutputOracle contract. Before updating the Proposal to L1, the L2OutputOracle contract verifies that the signature originates from a registered op-enclave’s ECDSA.PrivateKey. + +## 5. Rational + +### 5.1 Why choose the TEE solution + +In the opstack rollup, L2 state crosses the chain to L1. There are two finalized solutions: + +* Optimistic Rollups: These rely on a challenge period (often 7 days) to validate state transitions, delaying withdrawals. +* ZK Rollups: ZK rollups offer the promise of fast finality and withdrawals without a challenge period. However, generating ZK validity proofs for the EVM is computationally intensive and expensive. + +While Zero-Knowledge (ZK) solutions are ideal for their minimal trust assumptions, the significant computational cost and complexity of generating proofs make them economically unviable for many applications. + +This BEP therefore proposes a solution using Trusted Execution Environments (TEEs) as a more cost-effective compromise. This TEE-based approach delivers the necessary performance at a fraction of the cost, in exchange for introducing a hardware-based trust assumption. + +### 5.2 Security + +The following table illustrates the trust assumptions of different solutions. + +| |Optimistic | TEE | ZK| +|--------|--------|--------|--------| +|Trust assumptions |Fraud proving |The TEE provider and proposer |Cryptographic proofs, minimal trust| + +The TEE solution adds a new trust relationship with the TEE provider. However, to successfully attack the system, one needs to control both the proposer and the TEE provider, which is very difficult at present. However, TEE is indeed an important part of the cross-chain, and its stability affects the behavior of our system. It has not yet been practiced on a large scale in the blockchain industry. + +## 6. Backward Compatibility + +This BEP maintains full backward compatibility with existing opBNB Stack L2s implementations. It is optional, and even possible to roll back to previous versions. + +Moreover, the TEE architecture code is completely non-intrusive to the opBNB repo. Leveraging opBNB's modular plugin design, the new architecture's code(op-enclave repo) is entirely independent of the opBNB repo. By implementing new plugins, it enables customized special functionalities without affecting the existing code or features of the previous architecture. + +Existing opBNB Stack L2s do not need to worry about the side effects brought by TEE. + +## 7. License +All the content are licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP-610.md b/BEPs/BEP-610.md new file mode 100644 index 00000000..18b6239a --- /dev/null +++ b/BEPs/BEP-610.md @@ -0,0 +1,120 @@ +
+  BEP: 610
+  Title: Implement EVM Super Instruction
+  Status: Candidate
+  Type: Standards
+  Created: 2025-08-12
+  Description: It defines several customized super instruction opcodes to replace high frequency EVM opcode sequences to improve performance
+
+ +# BEP-610: Implement EVM Super Instruction + +- [BEP-610: Implement EVM Super Instruction](#bep-610-implement-evm-super-instruction) + - [1. Abstract](#1-abstract) + - [2. Motivation](#2-motivation) + - [3. Specification](#3-specification) + - [3.1 Super Instruction opcode definition](#31-super-instruction-opcode-definition) + - [3.2 Optimized Bytecode Generation (Background)](#32-optimized-bytecode-generation-background) + - [3.3 Super-Instruction Execution (Foreground)](#33-super-instruction-execution-foreground) + - [3.4 Super-Instruction Set Generation](#34-super-instruction-set-generation) + - [3.5 Compatibility \& Safety](#35-compatibility--safety) + - [3.6 Security Considerations](#36-security-considerations) + - [4. Backwards Compatibility](#4-backwards-compatibility) + - [5. License](#5-license) + +## 1. Abstract +This BEP introduces several customized super instruction opcodes to replace high frequency EVM opcode sequences to improve performance. Contract byte code is pre-processed to convert some sequence of EVM opcodes to super instruction opcodes and the EVM interpreter executes these super instruction opcode atomically. The approach yields significant execution-layer efficiency without altering consensus rules or requiring a hard-fork. + +## 2. Motivation + +On BSC mainnet, repeated execution of identical compiler-generated instruction patterns dominates gas consumption. By fusing these hot paths into single interpreter dispatches, we: + +- Reduce opcode dispatch overhead +- Minimise stack shuffling +- Achieve measurable throughput gains without protocol change. + +## 3. Specification + +### 3.1 Super Instruction opcode definition + +| Index (Hex) | Super Instruction | +|-------------|-----------------------------------------------------| +| 0xb1 | AndSwap1PopSwap2Swap1 | +| 0xb2 | Swap2Swap1PopJump | +| 0xb3 | Swap1PopSwap2Swap1 | +| 0xb4 | PopSwap2Swap1Pop | +| 0xb5 | Push2Jump | +| 0xb6 | Push2JumpI | +| 0xb7 | Push1Push1 | +| 0xb8 | Push1Add | +| 0xb9 | Push1Shl | +| 0xba | Push1Dup1 | +| 0xbb | Swap1Pop | +| 0xbc | PopJump | +| 0xbd | Pop2 | +| 0xbe | Swap2Swap1 | +| 0xbf | Swap2Pop | +| 0xc0 | Dup2LT | +| 0xc1 | JumpIfZero | +| 0xc2 | IsZeroPush2 | +| 0xc3 | Dup2MStorePush1Add | +| 0xc4 | Dup1Push4EqPush2 | +| 0xc5 | Push1CalldataloadPush1ShrDup1Push4GtPush2 | +| 0xc6 | Push1Push1Push1SHLSub | +| 0xc7 | AndDup2AddSwap1Dup2LT | +| 0xc8 | Swap1Push1Dup1NotSwap2AddAndDup2AddSwap1Dup2LT | +| 0xc9 | Dup3And | +| 0xca | Swap2Swap1Dup3SubSwap2Dup3GtPush2 | +| 0xcb | Swap1Dup2 | +| 0xcc | SHRSHRDup1MulDup1 | +| 0xcd | Swap3PopPopPop | +| 0xce | SubSLTIsZeroPush2 | +| 0xcf | Dup11MulDup3SubMulDup1 | + +### 3.2 Optimized Bytecode Generation (Background) + +| Aspect | Design | +|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Feature Toggle | Node flag `--vm.opcode.optimize` (default false). When disabled, the optimisation pipeline becomes a no-op. | +| Workflow | codeHash lookup -> LRU cache hit -> use optimised code. Cache miss -> (codeHash, rawCode) pushed to lock-free queue. | +| Basic-Block Construction | Split at PC==0 or any JUMPDEST; terminate before {JUMP, JUMPI, STOP, RETURN, REVERT, INVALID}. | +| Pattern Matching & Fusion | Sliding window (1-15 bytes) matches curated patterns; first byte replaced by custom opcode 0xb0–0xcf, trailing bytes overwritten with NOP(0x5b) to preserve length. | +| Cache | (codeHash -> fusedCode) stored in in-memory LRU (64 k entries default). Auxiliary static-analysis bitvectors stored in a side-cache. | + +### 3.3 Super-Instruction Execution (Foreground) + +| Phase | Description | +|-------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Loading | Before execution, interpreter queries cache with codeHash. Hit -> contract flagged optimized = true, fused bytecode loaded. Miss -> original bytecode executed. | +| Dispatch | Main loop processes opcodes as usual. For newly added superinstruction opcodes, jump directly to Super-Instruction handler. | +| Semantics | Handler emulates entire sequence (e.g., AND DUP2 ADD SWAP1 DUP2 LT) in one step, adjusts PC by original length, validates jump targets when applicable. | +| Safety | If custom opcode appears in non-optimised contract, throw ErrIllegalSuperInst and revert. | + +### 3.4 Super-Instruction Set Generation + +| Process | Description | +|---------|-------------| +| Data-Driven Mining | Trace production traffic, extract opcode sequences, compress with Re-Pair to obtain non-repetitive string. | +| Scoring | `score = len(sequence) × frequency` | +| Overlap Resolution | Greedy graph algorithm adjusts scores when super-instructions overlap (A ⊂ B). | +| Selection | Choose Top-K sequences (32 by default) as canonical super-instruction sets. | + +### 3.5 Compatibility & Safety +| Aspect | Guarantee | +|--------|--------------------------------------------------------------------------------| +| Switchable | Runtime flag permits instant enable/disable without restart. | +| Length-Preserving | Fused bytecode matches original size; all offset-based tooling remains intact. | +| Consensus Neutral | Only local execution changes; on-chain code unmodified -> no consensus impact. | +| Graceful Fallback | Failure in generation/execution reverts to original code path. | + +### 3.6 Security Considerations + +- **Validator Nodes**: Opt-in optimisation must not diverge state; test-suite includes differential fuzzing against vanilla EVM. +- **Custom Opcode Collision**: Range 0xb0–0xcf currently unused by London EVM; future EIPs allocating these bytes must be gated by network governance before activation. +- **DoS Risk**: Background optimiser bounded by worker pool and queue length to avoid unbounded memory/CPU spikes. + +## 4. Backwards Compatibility +Because bytecode length and on-chain contents remain unchanged, no tooling or contract migration is necessary. Nodes that disable the flag continue to operate identically, ensuring a smooth opt-in rollout. + +## 5. License +All the content are licensed under CC0. diff --git a/BEPs/BEP-619.md b/BEPs/BEP-619.md new file mode 100644 index 00000000..497f4471 --- /dev/null +++ b/BEPs/BEP-619.md @@ -0,0 +1,105 @@ +
+  BEP: 619
+  Title: Short Block Interval Phase Three: 0.45 Seconds
+  Status: Enabled
+  Type: Standards
+  Created: 2025-09-11
+  Description: To shorten the block interval from 0.75 seconds to 0.45 seconds.
+
+ +# BEP-619: Short Block Interval Phase Three: 0.45 Seconds +- [BEP-619: Short Block Interval Phase Three: 0.45 Seconds](#bep-619-short-block-interval-phase-three-045-seconds) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [4.1 Parameter Changes](#41-parameter-changes) + - [4.1.1 Change Table](#411-change-table) + - [4.2 Extended Voting Rules for Fast Finality Stability](#42-extended-voting-rules-for-fast-finality-stability) + - [5. Rationale](#5-rationale) + - [5.1 Parameter Changes](#51-parameter-changes) + - [6. Backward Compatibility](#6-backward-compatibility) + - [6.1 MEV](#61-mev) + - [6.2 Quarterly Auto-Burn](#62-quarterly-auto-burn) + - [6.3 Block Finality](#63-block-finality) + - [7. License](#7-license) + +## 1. Summary + +This proposal shortens the block interval from 0.75 seconds to 0.45 seconds, further improving transaction confirmation speed and enhancing user experience. + +## 2. Abstract + +* **BEP-520** (Phase One): reduced the block interval from 3 seconds to 1.5 seconds. +* **BEP-524** (Phase Two): reduced it further to 0.75 seconds. +* **BEP-619** (Phase Three, this proposal): reduces it to 0.45 seconds. + +## 3. Motivation + +Reducing the block interval is a long-term goal of BNB Smart Chain. A 0.45-second block interval will support time-sensitive applications by providing significantly faster confirmation times. + +## 4. Specification + +The overall design follows BEP-524, with modifications only to the relevant parameters. + +### 4.1 Parameter Changes + +Phases one, two, and three are closely related. For clarity, their parameter changes are consolidated into the following table. + +#### 4.1.1 Change Table + +Many system parameters are tied to the default block interval. When the interval is adjusted, related parameters must also be updated: + +| Parameter | Type | Origin (3s) | Phase One (1.5s) | Phase Two (0.75s) | Phase Three (0.45s) | +| ------------------------------------ | -------- | ---------------------- | ---------------- | ----------------- | ------------------- | +| Epoch | client | 200 | 500 | 1000 | 1000 | +| GasLimit | client | 140M | 100M | 75M | 55M | +| GasLimitBoundDivisor | client | 256 | 1024 | 1024 | 1024 | +| FullImmutabilityThreshold | client | 90,000 | 180,000 | 360,000 | 600,000 | +| receiveRateLimitPerSecond | client | 10 | 20 | 40 | 68 | +| Blob Target | client | 3 | 3 | 3 | 3 | +| Blob Maximum | client | 6 | 6 | 6 | 6 | +| Blob MinBlocksForBlobRequests | client | 524,288 | 1,048,576 (×2) | 2,097,152 (×4) | 3,495,254 (×3/0.45) | +| BSCGovernor.votingPeriod | contract | \$votingPeriod | ×2 | ×4 | ×(3/0.45) | +| BSCGovernor.minPeriodAfterQuorum | contract | \$minPeriodAfterQuorum | ×2 | ×4 | 172800(maximum) | +| BSCValidatorSet.misdemeanorThreshold | contract | \$misdemeanorThreshold | ×2 | ×4 | ×(3/0.45) | +| BSCValidatorSet.felonyThreshold | contract | \$felonyThreshold | ×2 | ×4 | ×(3/0.45) | +| BSCValidatorSet.felonySlashScope | contract | \$felonySlashScope | ×2 | ×4 | ×(3/0.45) | + +`receiveRateLimitPerSecond` is the max number of received votes per second from one peer, used to avoid of DDOS attack. + +### 4.2 Extended Voting Rules for Fast Finality Stability + +With a shorter block interval, network fluctuations and node performance issues have a larger impact on stability. To improve finality robustness, the adjustments defined in [BEP-590: Extended Voting Rules for Fast Finality Stability](./BEP-590.md) will also be applied. + +## 5. Rationale + +### 5.1 Parameter Changes + +* **GasLimit**: In phases one and two, GasLimit did not decrease proportionally with block interval reductions, due to hardware and software optimizations. In phase three, GasLimit is adjusted proportionally to match the reduced interval. +* **Epoch**: Epoch remains at 1000 blocks, reducing epoch time from 750s to 450s. Validator rotation becomes more frequent but is expected to have no negative impact. This also allows more equitable participation opportunities for candidates within a day. + + +## 6. Backward Compatibility + +### 6.1 MEV + +With a 0.45s block interval, each validator still produces 16 consecutive blocks per turn, reducing total turn time to 7.2s (0.45 × 16). This narrows the collaboration window for searchers, builders, and validators, requiring adjustments to current MEV strategies. + +### 6.2 Quarterly Auto-Burn + +*TBD.* + +### 6.3 Block Finality + +The fast finality mechanism remains unchanged. However, shorter intervals reduce the time available for vote propagation. + +* **With fast finality working correctly**: transaction finality improves from \~1.875s to \~1.125s. +* **If fast finality fails** (natural finality with TurnLength=16, ValidatorSize=21): + + * > 1/2 validator confirmations: 176 blocks (11×16) ≈ 79.2s + * > 2/3 validator confirmations: 240 blocks (15×16) ≈ 108s + +## 7. License + +This document is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-640.md b/BEPs/BEP-640.md new file mode 100644 index 00000000..1af7e101 --- /dev/null +++ b/BEPs/BEP-640.md @@ -0,0 +1,63 @@ +
+    BEP: 640
+    Title: Optional Transaction Gas Limit Cap
+    Status: Candidate
+    Type: Standards
+    Created: 2025-12-10
+    Description: Reduces network reorgs by limiting excessively large transactions.
+
+ +# BEP-640: Optional Transaction Gas Limit Cap + +- [BEP-640: Optional Transaction Gas Limit Cap](#bep-640-optional-transaction-gas-limit-cap) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [Community Autonomy and Soft Cap Enforcement](#community-autonomy-and-soft-cap-enforcement) + - [Smooth Transition Towards EIP-7825](#smooth-transition-towards-eip-7825) + - [5. Backward Compatibility](#5-backward-compatibility) + - [6. License](#6-license) + +## 1. Summary + +This BEP proposes an **optional, community-driven, non-protocol-level mechanism** to cap the maximum Gas Limit for individual transactions. The core objective is to **mitigate network reorganizations (reorgs)** caused by transactions with excessively long execution times, thereby enhancing BSC network **stability**. + +## 2. Abstract + +I/O-intensive transactions (e.g., using **$> 16,777,216$ gas**) exploit the underpricing of EVM I/O operations (like `SSTORE`). Their prolonged execution time often exceeds the block interval, leading to frequent **reorgs**. This BEP introduces **optional tooling and recommendation** to limit the per-transaction gas limit, serving as a **temporary, soft measure** before the potential implementation of a protocol-level solution like [**EIP-7825**](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7825.md). + +## 3. Motivation + +The primary motivation is to **improve the stability and reliability** of the BSC network. + +**Excessive execution time** for single, large transactions is the root cause of network instability. By shortening the block processing time, a soft cap on the maximum gas usage per transaction will significantly **reduce the frequency of destabilizing reorg events**, ensuring better network health. This solution is designed to be **lightweight** and deployable without a hard fork. + +## 4. Specification + +This BEP specifies a **recommended, off-chain** mechanism for limiting per-transaction gas usage, maintaining compatibility with the current **MEV-Boost/Auction mechanism**. + +### Community Autonomy and Soft Cap Enforcement + +Enforcement is at the full discretion of Validators. + + * **Validator Implementation:** Validators **SHOULD** implement an optional **client-side flag** to specify a max gas limit cap when building **blocks**. + +### Smooth Transition Towards EIP-7825 + +The cap aligns with the EIP-7825 limit to prepare the network for a future protocol update. + +* **Default Cap Value:** The default transaction gas limit cap implemented in the client **SHOULD be set to a sufficiently high value** to allow P2P nodes to continue propagating large transactions without restriction. +* **Validator Recommendation:** Validators are **recommended** to similarly cap the maximum gas limit of individual transactions they include in their **internally built blocks** at **$16,777,216$ ($2^{24}$)**. +* **Builder Recommendation:** Builders are **recommended** to similarly cap the maximum gas limit of individual transactions they include in their bids at **$16,777,216$ ($2^{24}$)**. + + +## 5. Backward Compatibility + +The impact is minimal, as transactions exceeding $16,777,216$ gas are a **very small percentage (approx. 0.3%%)** of all on-chain activity. + + * **Mitigation & Flexibility:** Validators **always have the option to opt-out** and maintain an unlimited gas limit cap. The non-protocol nature of this BEP allows for easy adjustment or disabling if community need for larger limits arises. + +## 6. License + +The content is licensed under [Creative Commons CC0 1.0 Universal License](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP-648.md b/BEPs/BEP-648.md new file mode 100644 index 00000000..91d0a7cb --- /dev/null +++ b/BEPs/BEP-648.md @@ -0,0 +1,71 @@ +
+  BEP: 648
+  Title: Enhanced Fast Finality via In-Memory Voting Pool
+  Status: Enabled
+  Type: Standards
+  Created: 2026-01-12
+  Description: Enable faster finality by determining finality through in-memory vote pools, without waiting for votes to be included in block headers.
+
+ +# BEP-648: Enhanced Fast Finality via In-Memory Voting Pool + +- [BEP-648: Enhanced Fast Finality via In-Memory Voting Pool](#bep-648-enhanced-fast-finality-via-in-memory-voting-pool) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [5. Security](#5-security) + - [6. Backward Compatibility](#6-backward-compatibility) + - [7. License](#7-license) + +## 1. Summary + +This BEP proposes an optimization to the Fast Finality mechanism introduced in [BEP-126](./BEP126.md), enabling nodes to collect attestations directly from in-memory vote pools rather than waiting for them to be packaged into block headers, thereby achieving faster finality determination. + +## 2. Abstract + +[BEP-126](./BEP126.md) introduced Fast Finality on BNB Smart Chain. Under the current design, a block is justified when its attestation appears in the next block's header, and finalized when both it and its direct child are justified. This requires at least 2 subsequent blocks. + +This BEP extends the justification rule to allow nodes to determine justification directly from in-memory vote pools when ⅔+ validators' votes are received, without waiting for attestations to be included in block headers. This significantly reduces finality latency while maintaining all BEP-126 security guarantees. + +Attestations continue to be included in block headers as per BEP-126, ensuring validator rewards and enabling on-chain consensus verification. + +## 3. Motivation + +Under BEP-126, finality determination is unnecessarily coupled to block production. Validators complete voting quickly, but finality cannot be determined until attestations are included in block headers. Once ⅔+ validators have voted, their votes already provide sufficient cryptographic proof—waiting for block inclusion introduces artificial delay. + +This BEP decouples finality determination from block production by allowing nodes to determine finality directly from in-memory vote pools. + +## 4. Specification + +This BEP extends the Finality Rules from [BEP-126](./BEP126.md) Section 4.1.3. + +There are two steps to finalize a block, the first step we call justify, the second step we call finalize. + +1. A block is called justified if +* (1) it is the root, or +* (2) there exists attestation for this block ~~in its direct child's header~~, we call this block **justified**. +2. A block is called finalized if +* (1) it is the root, or +* (2) it is justified and its direct child is justified. + +All other aspects of BEP-126 remain unchanged, including validator vote rules, aggregate vote rules, and the longest chain rule. + +## 5. Security + +This BEP does **not** alter the core safety assumptions or mechanisms of Fast Finality. It does not change validator vote rules, aggregate vote rules, finalization thresholds, or the longest chain rule. + +The only modification is allowing nodes to determine justification from in-memory vote pools in addition to on-chain attestations. Both approaches rely on the same cryptographic foundation: ⅔+ valid validator votes. Since the underlying cryptographic proof is unchanged, all [BEP-126](./BEP126.md) safety guarantees—including accountable safety and plausible liveness—remain intact. + +## 6. Backward Compatibility + +This BEP is **fully backward compatible**. It does not change consensus rules, block validation, block headers, or vote aggregation. + +Finality determination is a client-side optimization. Upgraded nodes observe faster finality via in-memory vote pools, while non-upgraded nodes continue using header-based finality. Network stability is unaffected. + +This can be deployed as a client upgrade without requiring network-wide coordination or hard fork activation. + +## 7. License + +The content is licensed under [Creative Commons CC0 1.0 Universal License](https://creativecommons.org/publicdomain/zero/1.0/). + diff --git a/BEPs/BEP-651.md b/BEPs/BEP-651.md new file mode 100644 index 00000000..2b1ddc52 --- /dev/null +++ b/BEPs/BEP-651.md @@ -0,0 +1,135 @@ +
+  BEP: 651
+  Title: Implement EIP-7823 – Set upper bounds for MODEXP
+  Status: Enabled
+  Type: Standards
+  Created: 2026-01-20
+  Description: Each input field is restricted to a maximum of 8192 bits
+
+ +# BEP-651: Implement EIP-7823 – Set upper bounds for MODEXP + +- [BEP-651: Implement EIP-7823 – Set upper bounds for MODEXP](#bep-651-implement-eip-7823--set-upper-bounds-for-modexp) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [5. Rationale](#5-rationale) + - [Limit](#limit) + - [EVMMAX](#evmmax) + - [Analysis](#analysis) + - [Base length occurrences](#base-length-occurrences) + - [Exponent length occurrences](#exponent-length-occurrences) + - [Modulo length occurrences](#modulo-length-occurrences) + - [6. Backwards Compatibility](#6-backwards-compatibility) + - [7. Security Considerations](#7-security-considerations) + - [8. License](#8-license) + +## 1. Summary + +This BEP introduces an upper bound on each input field of the MODEXP precompile on BSC. + +## 2. Abstract + +Introduce an upper bound on the inputs of the MODEXP precompile. This can reduce the number of potential bugs, because the testing surface is not infinite anymore, and makes it easier to be replaced using EVMMAX. + +## 3. Motivation + +The MODEXP precompile has been a source of numerous consensus bugs. Many of them were due to specifically crafted cases using impractical input lengths. + +Its pricing function is also quite complex given its nature of unbounded inputs. While we don't suggest to rework the pricing function, it may be possible in a future upgrade once the limits are in place. + +Furthermore this limitation makes it more feasible to have the precompile replaced with EVM code through features like EVMMAX. + +## 4. Specification + +Recap from [EIP-198](https://eips.ethereum.org/EIPS/eip-198): +> At address `0x00……05`, add a precompile that expects input in the following format: +> +> ` ` + +We introduce an upper bound to the inputs of the precompile, each of the length inputs (`length_of_BASE`, `length_of_EXPONENT` and `length_of_MODULUS`) MUST be less than or equal to 8192 bits (1024 bytes). + +If any of these inputs are larger than the limit, the precompile execution stops, returns an error, and consumes all gas. + +## 5. Rationale + +### Limit + +This upper bound allows the existing use cases of MODEXP: + +1. RSA verification with up to 8192 bit keys. Commonly used ones are 1024/2048/4096 bits. +2. Elliptic curve related use cases are usually less than 384 bits. + +### EVMMAX + +Replacing the precompile with EVM code using an instruction set like EVMMAX would be made simpler with this limit: Common cases (256, 381, 1024, 2048) could be implemented in special fast paths, while a slow fallback could be provided for the rest. Or even special, frequently used, moduli could have their own paths. + +Furthermore one could consider limiting the lengths to certain inputs only. + +### Analysis + +Since MODEXP was introduced in the Byzantium hard fork, an analysis has been conducted between block 5472266 (April 20, 2018) and block 21550926 (January 4th, 2025). All lengths of inputs are expressed in bytes. + +#### Base length occurrences + +| `input_of_BASE` | count | +|-----------------|-------| +| 32 | 2439595 | +| 128 | 4167 | +| 256 | 2969 | +| 160 | 436 | +| 512 | 36 | +| 0 | 13 | +| 64 | 7 | +| 78 | 2 | +| 513 | 2 | +| 129 | 1 | +| 385 | 1 | + +#### Exponent length occurrences + +| `input_of_EXPONENT` | count | +|---------------------|-------| +| 32 | 2442255 | +| 3 | 4771 | +| 1 | 159 | +| 128 | 29 | +| 0 | 13 | +| 5 | 2 | + +#### Modulo length occurrences + +| `input_of_MODULUS` | count | +|--------------------|-------| +| 32 | 2439594 | +| 128 | 4167 | +| 256 | 2968 | +| 160 | 436 | +| 512 | 38 | +| 0 | 13 | +| 64 | 8 | +| 78 | 2 | +| 129 | 1 | +| 384 | 1 | +| 257 | 1 | + +This shows that no past successful use case exceeded an input length of 513 bytes, and the majority uses 32/128/256 byte inputs. + +Besides these, there were a few invocations with invalid inputs: + +- Empty inputs +- Inputs consisting of only `0x9e5faafc` or `0x85474728` +- A large, but invalid input: `0x9e281a98000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021e19e0c9bab2400000` + +## 6. Backwards Compatibility + +This is a backwards incompatible change. However, based on analysis until block 21550926 (see above), no past transaction would have behaved differently after this change. + +## 7. Security Considerations + +Since only the accepted input range is reduced, no new security surface area is expected. + +## 8. License + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-652.md b/BEPs/BEP-652.md new file mode 100644 index 00000000..1a2e3f5a --- /dev/null +++ b/BEPs/BEP-652.md @@ -0,0 +1,108 @@ +
+  BEP: 652
+  Title: Implement EIP-7825 Transaction Gas Limit Cap
+  Status: Enabled
+  Type: Standards
+  Created: 2026-01-20
+  Description: Introduce a protocol-level cap on the maximum gas used by a transaction to 16,777,216 (2^24)
+
+ +# BEP-652: Implement EIP-7825 Transaction Gas Limit Cap + +- [BEP-652: Implement EIP-7825 Transaction Gas Limit Cap](#bep-652-implement-eip-7825-transaction-gas-limit-cap) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [Gas Cap](#gas-cap) + - [Changes to EVM Behavior](#changes-to-evm-behavior) + - [Protocol Adjustment](#protocol-adjustment) + - [Builder and MEV Bid Validation](#builder-and-mev-bid-validation) + - [5. Rationale](#5-rationale) + - [Why 16,777,216 (2^24)?](#why-16777216-224) + - [Compatibility with Current Gas Dynamics](#compatibility-with-current-gas-dynamics) + - [6. Backwards Compatibility](#6-backwards-compatibility) + - [7. Security Considerations](#7-security-considerations) + - [8. License](#8-license) + +## 1. Summary + +This BEP proposes to introduce a protocol-level cap on the maximum gas usage +per transaction to **16,777,216 (2^24)** on BSC. Previously, **BEP-640** introduced +an optional soft cap mechanism where validators could voluntarily limit per-transaction +gas. This BEP upgrades it to a **mandatory protocol-level enforcement**, ensuring all +nodes uniformly reject transactions exceeding the limit, which can better improve +network stability and reliability compared to the previous approach. + +## 2. Abstract + +This proposal introduces a protocol-level cap on the maximum gas usage per transaction to 16,777,216 (2^24) gas. By implementing this limit, BSC can enhance its resilience against certain DoS vectors, improve network stability, and provide more predictability to transaction processing costs, especially in the context of increasing the gas limit. + +## 3. Motivation + +Currently, transactions can theoretically consume up to the entire block gas limit, which poses several risks: + +1. **DoS Attacks**: A single transaction consuming most or all of the block gas can result in uneven load distribution and impact network stability. +2. **State Bloat Risks**: High-gas transactions often result in larger state changes, increasing the burden on nodes and exacerbating the state growth problem. +3. **Validation Overhead**: High-gas transactions can lead to longer block verification times, negatively impacting user experience and network decentralization. + +By limiting individual transactions to a maximum of 16,777,216 gas, we aim to: + +- Reduce the risks of single-transaction DoS attacks. +- Promote fairer gas allocation across transactions within a block. +- Ensure better synchronization among nodes by mitigating extreme block validation times. + +## 4. Specification + +### Gas Cap + +- Enforce a protocol-level maximum of **16,777,216 gas (2^24)** for any single transaction. +- This cap applies regardless of the block gas limit set by miners or validators. +- Transactions specifying gas limits higher than 16,777,216 gas will be rejected with an appropriate error code (e.g., `MAX_GAS_LIMIT_EXCEEDED`). + +### Changes to EVM Behavior + +1. **Txpool Validation**: During transaction validation, if the `gasLimit` specified by the sender exceeds 16,777,216, the transaction is invalidated (not included in the txpool). +2. **Block Validation**: As part of block validation before processing, any block having a transaction with `gasLimit` > 16,777,216 is deemed invalid and rejected. + +### Protocol Adjustment + +- The `GAS_LIMIT` parameter for transactions will be capped in client implementations at 16,777,216. +- This cap is **independent** of the block gas limit, which exceeds this value. + +### Builder and MEV Bid Validation + +- **Bid Transaction Validation**: When validators receive bids from builders, + each transaction in the bid is validated against the 16,777,216 gas cap. + Bids containing any transaction with `gasLimit` > 16,777,216 are rejected. + +- **Builder Compliance**: Builders must ensure that all transactions included + in their bids have `gasLimit` ≤ 16,777,216. Bids violating this constraint + will be rejected by validators. + +## 5. Rationale + +### Why 16,777,216 (2^24)? + +The proposed cap of 16,777,216 gas (2^24) provides a clean power-of-two boundary that simplifies implementation while still being large enough to accommodate most complex transactions, including contract deployments and advanced DeFi interactions. This value represents approximately half of typical block sizes (30-40 million gas), ensuring multiple transactions can fit within each block. + +### Compatibility with Current Gas Dynamics + +- **Backward Compatibility**: Transactions with gas usage below 16,777,216 remain unaffected. Existing tooling and dApps need only minor updates to enforce the new cap. +- **Impact on Validators**: Validators can continue to process blocks with a gas limit exceeding 16,777,216, provided individual transactions adhere to the cap. + +## 6. Backwards Compatibility + +This change is **not backward-compatible** with transactions that specify gas limits exceeding 16,777,216. Transactions with such high limits will need to be split into smaller operations. This adjustment is expected to impact a minimal number of users and dApps, as most transactions today fall well below the proposed cap. + +An [empirical analysis](https://github.com/bnb-chain/BEPs/blob/master/BEPs/assets/BEP-652/analysis.md) has been conducted to assess the potential impact of this change. + +## 7. Security Considerations + +1. **DoS Mitigation**: A fixed cap reduces the risk of DoS attacks caused by excessively high-gas transactions. +2. **Block Verification Stability**: By capping individual transactions, the validation of blocks becomes more predictable and uniform. +3. **Edge Cases**: Certain highly complex transactions, such as large contract deployments, may require re-architecting to fit within the 16,777,216 gas cap. + +## 8. License + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-653.md b/BEPs/BEP-653.md new file mode 100644 index 00000000..b02c29ac --- /dev/null +++ b/BEPs/BEP-653.md @@ -0,0 +1,174 @@ +
+  BEP: 653
+  Title: Implement EIP-7883 ModExp Gas Cost Increase
+  Status: Enabled
+  Type: Standards
+  Created: 2026-01-20
+  Description: Increases cost of ModExp precompile
+
+ +# BEP-653: Implement EIP-7883 ModExp Gas Cost Increase + +- [BEP-653: Implement EIP-7883 ModExp Gas Cost Increase](#bep-653-implement-eip-7883-modexp-gas-cost-increase) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [1. Increased minimal and general price](#1-increased-minimal-and-general-price) + - [2. Increase cost for exponents larger than 32 bytes](#2-increase-cost-for-exponents-larger-than-32-bytes) + - [3. Assume the minimal base / modulus length to be 32 and increase the cost when it is larger than 32 bytes](#3-assume-the-minimal-base--modulus-length-to-be-32-and-increase-the-cost-when-it-is-larger-than-32-bytes) + - [5. Rationale](#5-rationale) + - [6. Backwards Compatibility](#6-backwards-compatibility) + - [7. Test Cases](#7-test-cases) + - [8. Security Considerations](#8-security-considerations) + - [9. License](#9-license) + +## 1. Summary + +This BEP increases the gas cost of the ModExp precompile on BSC. + +## 2. Abstract + +This BEP is modifying the `ModExp` precompile pricing algorithm introduced in [EIP-2565](https://eips.ethereum.org/EIPS/eip-2565). + +## 3. Motivation + +Currently the `ModExp` precompile is underpriced in certain scenarios relative to its resource consumption. By adjusting the pricing formula, this BEP aims to address these discrepancies, making `ModExp` sufficiently efficient to enable potential increases in the block gas limit. + +## 4. Specification + +Upon activation of this BEP, the gas cost of calling the precompile at address `0x0000000000000000000000000000000000000005` will be calculated as follows: + +```python +def calculate_multiplication_complexity(base_length, modulus_length): + max_length = max(base_length, modulus_length) + words = math.ceil(max_length / 8) + multiplication_complexity = 16 + if max_length > 32: multiplication_complexity = 2 * words**2 + return multiplication_complexity + +def calculate_iteration_count(exponent_length, exponent): + iteration_count = 0 + if exponent_length <= 32 and exponent == 0: iteration_count = 0 + elif exponent_length <= 32: iteration_count = exponent.bit_length() - 1 + elif exponent_length > 32: iteration_count = (16 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) + return max(iteration_count, 1) + +def calculate_gas_cost(base_length, modulus_length, exponent_length, exponent): + multiplication_complexity = calculate_multiplication_complexity(base_length, modulus_length) + iteration_count = calculate_iteration_count(exponent_length, exponent) + return max(500, math.floor(multiplication_complexity * iteration_count)) +``` + +The specific changes from the algorithm defined in [EIP-2565](https://eips.ethereum.org/EIPS/eip-2565): + +### 1. Increased minimal and general price + +The gas cost calculation is modified from: + +```python + return max(200, math.floor(multiplication_complexity * iteration_count / 3)) +``` + +to: + +```python + return max(500, math.floor(multiplication_complexity * iteration_count)) +``` + +This change increases the minimum gas cost from 200 to 500 and triples the general cost by removing the division by 3. + +### 2. Increase cost for exponents larger than 32 bytes + +The gas cost calculation is modified from: + +```python + elif exponent_length > 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) +``` + +to: + +```python + elif exponent_length > 32: iteration_count = (16 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) +``` + +The multiplier for exponents larger than 32 bytes is increased from 8 to 16, doubling its impact. + +### 3. Assume the minimal base / modulus length to be 32 and increase the cost when it is larger than 32 bytes + +The gas cost calculation is modified from: + +```python +def calculate_multiplication_complexity(base_length, modulus_length): + max_length = max(base_length, modulus_length) + words = math.ceil(max_length / 8) + return words**2 +``` + +to: + +```python +def calculate_multiplication_complexity(base_length, modulus_length): + max_length = max(base_length, modulus_length) + words = math.ceil(max_length / 8) + multiplication_complexity = 16 + if max_length > 32: multiplication_complexity = 2 * words**2 + return multiplication_complexity +``` + +This change introduces a minimal multiplication complexity of 16 and doubles the complexity if the base or modulus length exceeds 32 bytes. + +## 5. Rationale + +Benchmarking the `ModExp` precompile revealed several scenarios where its gas cost was significantly underestimated. Pricing adjustments are designed to rectify underpriced edge cases by modifying the existing `ModExp` pricing formula parameters. Specifically, the minimum cost for `ModExp` will rise from 200 to 500 (a 150% increase), the general cost will triple (a 200% increase), a minimum base/modulus length of 32 bytes will be assumed and the cost will scale more aggressively when the base, modulus, or exponent exceed 32 bytes. These modifications aim to ensure that the `ModExp` precompile's performance, even in its most resource-intensive edge cases across all execution layer clients, no longer impedes potential increases to the block gas limit. + +## 6. Backwards Compatibility + +This BEP introduces a backwards-incompatible change. However, similar gas repricings have occurred multiple times in the Ethereum ecosystem, and their effects are well understood. + +An empirical analysis of this proposal is available [here](https://github.com/ethereum/EIPs/blob/master/assets/eip-7883/call_analysis.md), with a separate breakdown by affected entities provided [here](https://github.com/ethereum/EIPs/blob/master/assets/eip-7883/entity_analysis.md). + +## 7. Test Cases + +The most common usages (approximately 99.69% of historical `Modexp` calls as of January 4th, 2025) will experience either a 150% increase (from 200 to 500 gas) or a 200% increase (tripling from approximately 1360 gas). +No changes are made to the underlying interface or arithmetic algorithms, allowing existing test vectors to be reused. The table below presents the updated gas costs for these test vectors: + +| Test Case | [EIP-2565](https://eips.ethereum.org/EIPS/eip-2565) Pricing | EIP-7883 Pricing | Increase | +|------------------------------|-----|-----|----| +| modexp_nagydani_1_square | 200 | 500 | 150% | +| modexp_nagydani_1_qube | 200 | 500 | 150% | +| modexp_nagydani_1_pow0x10001 | 341 | 2048 | 501% | +| modexp_nagydani_2_square | 200 | 512 | 156% | +| modexp_nagydani_2_qube | 200 | 512 | 156% | +| modexp_nagydani_2_pow0x10001 | 1365 | 8192 | 501% | +| modexp_nagydani_3_square | 341 | 2048 | 501% | +| modexp_nagydani_3_qube | 341 | 2048 | 501% | +| modexp_nagydani_3_pow0x10001 | 5461 | 32768 | 500% | +| modexp_nagydani_4_square | 1365 | 8192 | 501% | +| modexp_nagydani_4_qube | 1365 | 8192 | 501% | +| modexp_nagydani_4_pow0x10001 | 21845 | 131072 | 500% | +| modexp_nagydani_5_square | 5461 | 32768 | 500% | +| modexp_nagydani_5_qube | 5461 | 32768 | 500% | +| modexp_nagydani_5_pow0x10001 | 87381 | 524288 | 500% | +| modexp_marius_1_even | 2057 | 45296 | 2102% | +| modexp_guido_1_even | 2298 | 51136 | 2125% | +| modexp_guido_2_even | 2300 | 51152 | 2124% | +| modexp_guido_3_even | 5400 | 32400 | 500% | +| modexp_guido_4_even | 1026 | 94448 | 9105% | +| modexp_marcin_1_base_heavy | 200 | 1152 | 476% | +| modexp_marcin_1_exp_heavy | 215 | 16624 | 7632% | +| modexp_marcin_1_balanced | 200 | 1200 | 500% | +| modexp_marcin_2_base_heavy | 867 | 5202 | 500% | +| modexp_marcin_2_exp_heavy | 852 | 16368 | 1821% | +| modexp_marcin_2_balanced | 996 | 5978 | 500% | +| modexp_marcin_3_base_heavy | 677 | 2032 | 200% | +| modexp_marcin_3_exp_heavy | 765 | 4080 | 433% | +| modexp_marcin_3_balanced | 1360 | 4080 | 200% | + +## 8. Security Considerations + +This BEP does not introduce any new functionality or make existing operations cheaper, therefore there are no direct security concerns related to new attack vectors or reduced costs. The primary security consideration for this BEP is the potential for `ModExp` scenarios to be overpriced, though this is deemed a lesser risk compared to the current underpricing issues. + +## 9. License + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-654.md b/BEPs/BEP-654.md new file mode 100644 index 00000000..66b17527 --- /dev/null +++ b/BEPs/BEP-654.md @@ -0,0 +1,203 @@ +
+  BEP: 654
+  Title: Implement EIP-7939: Count Leading Zeros (CLZ) Opcode
+  Status: Enabled
+  Type: Standards
+  Created: 2026-01-21
+  Description: Add CLZ opcode to count the number of leading zero bits in a 256-bit word
+
+ +# BEP-654: Implement EIP-7939: Count Leading Zeros (CLZ) Opcode + +- [BEP-654: Implement EIP-7939: Count Leading Zeros (CLZ) Opcode](#bep-654-implement-eip-7939-count-leading-zeros-clz-opcode) + - [1. Summary](#1-summary) + - [2. Motivation](#2-motivation) + - [3. Specification](#3-specification) + - [4. Rationale](#4-rationale) + - [The Special Zero Case](#the-special-zero-case) + - [Preference over `CTZ` (Count Trailing Zeros)](#preference-over-ctz-count-trailing-zeros) + - [Gas Cost](#gas-cost) + - [5. Backwards Compatibility](#5-backwards-compatibility) + - [6. Test Cases](#6-test-cases) + - [7. Security Considerations](#7-security-considerations) + - [8. License](#8-license) + +## 1. Summary + +Introduce a new opcode, `CLZ(x)`, which pops `x` from the stack and pushes the number of leading zero bits in `x` to the stack. If `x` is zero, pushes 256. + +## 2. Motivation + +Count leading zeros (CLZ) is a native opcode in many processor architectures (even in RISC architectures like ARM). + +It is a basic building block used in math operations, byte operations, compression algorithms, data structures: + +- lnWad +- powWad +- lambertW0Wad +- sqrt +- cbrt +- byte string comparisons +- generalized calldata compression/decompression +- bitmaps (for finding the next/previous set/unset bit) +- post quantum signature schemes + +Adding a `CLZ` opcode will: + +- Lead to cheaper compute. +- Lead to cheaper ZK proving costs. The fastest known Solidity implementation uses several dynamic bitwise right shifts `shr`, which are very expensive to prove. In SP1 rv32im, a 32-bit right shift costs 1.6x more than a 32-bit mul. +- Lead to smaller bytecode size. The fastest known Solidity implementation contains several large constants and is often inlined for performance. + +## 3. Specification + +A new opcode is introduced: `CLZ` (`0x1e`). + +- Pops 1 value from the stack. +- Pushes a value to the stack, according to the following code: + +```solidity +/// @dev Count leading zeros. +/// Returns the number of zeros preceding the most significant one bit. +/// If `x` is zero, returns 256. +/// This is the fastest known `CLZ` implementation in Solidity and uses about 184 gas. +function clz(uint256 x) internal pure returns (uint256 r) { + /// @solidity memory-safe-assembly + assembly { + r := shl(7, lt(0xffffffffffffffffffffffffffffffff, x)) + r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, x)))) + r := or(r, shl(5, lt(0xffffffff, shr(r, x)))) + r := or(r, shl(4, lt(0xffff, shr(r, x)))) + r := or(r, shl(3, lt(0xff, shr(r, x)))) + // forgefmt: disable-next-item + r := add(xor(r, byte(and(0x1f, shr(shr(r, x), 0x8421084210842108cc6318c6db6d54be)), + 0xf8f9f9faf9fdfafbf9fdfcfdfafbfcfef9fafdfafcfcfbfefafafcfbffffffff)), iszero(x)) + } +} +``` + +Or in Python, + +```python +def clz(x): + """Returns the number of zeros preceding the most significant one bit.""" + if x < 0: + raise ValueError("clz is undefined for negative numbers") + if x > 2**256 - 1: + raise ValueError("clz is undefined for numbers larger than 2**256 - 1") + if x == 0: + return 256 + # Convert to binary string and remove any '0b' prefix. + bin_str = bin(x).replace('0b', '') + return 256 - len(bin_str) +``` + +Or in C++, + +```c++ +inline uint32_t clz(uint32_t x) { + uint32_t r = 0; + if (!(x & 0xFFFF0000)) { r += 16; x <<= 16; } + if (!(x & 0xFF000000)) { r += 8; x <<= 8; } + if (!(x & 0xF0000000)) { r += 4; x <<= 4; } + if (!(x & 0xC0000000)) { r += 2; x <<= 2; } + if (!(x & 0x80000000)) { r += 1; } + return r; +} + +// `x` is a uint256 bit number represented with 8 uint32 limbs. +// This implementation is optimized for SP1 proving via rv32im. +// For regular compute, it performs similarly to `ADD`. +inline uint32_t clz(uint32_t x[8]) { + if (x[7] != 0) return clz(x[7]); + if (x[6] != 0) return 32 + clz(x[6]); + if (x[5] != 0) return 64 + clz(x[5]); + if (x[4] != 0) return 96 + clz(x[4]); + if (x[3] != 0) return 128 + clz(x[3]); + if (x[2] != 0) return 160 + clz(x[2]); + if (x[1] != 0) return 192 + clz(x[1]); + if (x[0] != 0) return 224 + clz(x[0]); + return 256; +} +``` + +The cost of the opcode is 5, matching MUL (raised from 3 to avoid under-pricing DoS risk). + +## 4. Rationale + +### The Special Zero Case + +256 is the smallest number after 255. Returning a small number allows the result to be compared with minimal additional bytecode. + +For byte scanning operations, one can get the number of bytes to be skipped for a zero word by simply computing `256 >> 3`, which gives 32. + +### Preference over `CTZ` (Count Trailing Zeros) + +Computing the least significant bit can be easily implemented with `CLZ` by isolating the smallest bit via `x & -x`. + +However, it is not possible to implement `CLZ` with `CTZ`. + +### Gas Cost + +We have benchmarked the `CLZ` implementation against the `ADD` implementation in the intx library. `CLZ` uses approximately the same amount of compute cycles as `ADD`. + +The SP1 rv32im optimized variant uses less compute cycles than `ADD`, in the average and worst cases. + +In SP1 rv32im, a 256-bit `CLZ` is cheaper to prove than `ADD`. + +## 5. Backwards Compatibility + +This is a new opcode not present prior. + +## 6. Test Cases + +``` +PUSH32 0x000000000000000000000000000000000000000000000000000000000000000 +CLZ +--- +0x0000000000000000000000000000000000000000000000000000000000000100 +``` + +``` +PUSH32 0x8000000000000000000000000000000000000000000000000000000000000000 +CLZ +--- +0x0000000000000000000000000000000000000000000000000000000000000000 +``` + +``` +PUSH32 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +CLZ +--- +0x0000000000000000000000000000000000000000000000000000000000000000 +``` + +``` +PUSH32 0x4000000000000000000000000000000000000000000000000000000000000000 +CLZ +--- +0x0000000000000000000000000000000000000000000000000000000000000001 +``` + +``` +PUSH32 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +CLZ +--- +0x0000000000000000000000000000000000000000000000000000000000000001 +``` + +``` +PUSH32 0x0000000000000000000000000000000000000000000000000000000000000001 +CLZ +--- +0x00000000000000000000000000000000000000000000000000000000000000ff +``` + +## 7. Security Considerations + +`CLZ` is a stateless opcode that has a low worst-case constant cost in memory usage, compute and proving costs. It is therefore safe from being exploited for denial of service attacks. + +## 8. License + +All content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + + diff --git a/BEPs/BEP-655.md b/BEPs/BEP-655.md new file mode 100644 index 00000000..5ffb0e4a --- /dev/null +++ b/BEPs/BEP-655.md @@ -0,0 +1,80 @@ +
+  BEP: 655
+  Title: Implement EIP-7934 RLP Execution Block Size Limit
+  Status: Enabled
+  Type: Standards
+  Created: 2026-01-20
+  Description: Introduce a protocol-level cap on the maximum RLP-encoded block size to 8 MiB
+
+ +# BEP-655: Implement EIP-7934 RLP Execution Block Size Limit + +- [BEP-655: Implement EIP-7934 RLP Execution Block Size Limit](#bep-655-implement-eip-7934-rlp-execution-block-size-limit) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [Block Size Cap](#block-size-cap) + - [Changes to Protocol Behavior](#changes-to-protocol-behavior) + - [Protocol Adjustment](#protocol-adjustment) + - [5. Backwards Compatibility](#5-backwards-compatibility) + - [6. Security Considerations](#6-security-considerations) + - [7. License](#7-license) + +## 1. Summary + +This BEP introduces a protocol-level cap on the maximum RLP-encoded execution block size to 8 MiB on BSC, since the blob sidecar is not counted as part of the block size. + +## 2. Abstract + +This proposal introduces a protocol-level cap on the maximum RLP-encoded execution block size. The Ethereum community sets this limit to 10 megabytes (MiB), which includes a margin of 2 MiB to account for beacon block sizes. BSC adopts a limit of 8 MiB for the execution block size. + +## 3. Motivation + +Currently, BSC does not enforce a strict upper limit on the encoded size of blocks. This lack of constraint can result in: + +1. **Network Instability**: Extremely large blocks slow down propagation and increase the risk of temporary forks and reorgs. +2. **DoS Risks**: Malicious actors could generate exceptionally large blocks to disrupt network performance. + +Additionally, blocks exceeding 10 MiB are not propagated by the consensus layer's (CL) gossip protocol, potentially causing network fragmentation or denial-of-service (DoS) conditions. + +By imposing a protocol-level limit on the RLP-encoded block size, BSC can ensure enhanced resilience against targeted attacks on block validation times. Adding an additional margin of 2MiB explicitly accommodates beacon block sizes, ensuring compatibility across network components. + +## 4. Specification + +### Block Size Cap + +- Introduce constants: + - `MAX_RLP_BLOCK_SIZE` set to **8 MiB (8,388,608 bytes)** +- Any RLP-encoded block exceeding `MAX_RLP_BLOCK_SIZE` must be considered invalid. + +Thus add the following check to the protocol: + +```python + +# if true, the block is invalid and should be rejected/not get built +def exceed_max_rlp_block_size(block: Block) -> bool: + return len(rlp.encode(block)) > MAX_RLP_BLOCK_SIZE +``` + +### Changes to Protocol Behavior + +1. **Block Creation**: Validators must ensure the total RLP-encoded size of any produced block does not exceed `MAX_RLP_BLOCK_SIZE`. +2. **Block Validation**: Nodes must reject blocks whose RLP-encoded size exceeds `MAX_RLP_BLOCK_SIZE`. + +### Protocol Adjustment + +- All BSC client implementations must integrate this size check as part of block validation and propagation. +- This limit applies independently of gas-related metrics. + +## 5. Backwards Compatibility + +This change is **not backward-compatible** with any blocks larger than the newly specified size limit. Validators and miners will need to ensure their block construction logic strictly respects this limit. + +## 6. Security Considerations + +Restricting maximum block size provides inherent protection against deliberate oversized-block attacks. + +## 7. License + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-656.md b/BEPs/BEP-656.md new file mode 100644 index 00000000..02149efe --- /dev/null +++ b/BEPs/BEP-656.md @@ -0,0 +1,349 @@ +
+  BEP: 656
+  Title: Implement EIP-7910: eth_config JSON-RPC Method
+  Status: Enabled
+  Type: Standards
+  Created: 2026-01-21
+  Description: A JSON-RPC method that describes the configuration of the current and next fork
+
+ +# BEP-656: Implement EIP-7910: eth_config JSON-RPC Method + +- [BEP-656: Implement EIP-7910: eth\_config JSON-RPC Method](#bep-656-implement-eip-7910-eth_config-json-rpc-method) + - [1. Summary](#1-summary) + - [2. Motivation](#2-motivation) + - [Target Audience and Use Cases](#target-audience-and-use-cases) + - [3. Specification](#3-specification) + - [Configuration RPC](#configuration-rpc) + - [Result Object Structure](#result-object-structure) + - [Members of the Configuration Object](#members-of-the-configuration-object) + - [`activationTime`](#activationtime) + - [`blobSchedule`](#blobschedule) + - [`chainId`](#chainid) + - [`forkId`](#forkid) + - [`precompiles`](#precompiles) + - [`systemContracts`](#systemcontracts) + - [4. Rationale](#4-rationale) + - [Why Three Time Horizons?](#why-three-time-horizons) + - [Why Not Include All Future Forks?](#why-not-include-all-future-forks) + - [Standardization and Consistency](#standardization-and-consistency) + - [5. Backwards Compatibility](#5-backwards-compatibility) + - [6. Test Cases](#6-test-cases) + - [With Future Fork Scheduled](#with-future-fork-scheduled) + - [Without Future Fork Scheduled](#without-future-fork-scheduled) + - [7. Security Considerations](#7-security-considerations) + - [8. License](#8-license) + +## 1. Summary + +This document describes an RPC method that provides node-relevant configuration data for the current, next, and last known forks. + +## 2. Motivation + +By providing an RPC method that allows clients to report key configuration variables before the next hard fork, operations teams can gain greater confidence that clients are correctly configured and prepared for upcoming forks. + +### Target Audience and Use Cases + +This method is intended for node operators, validator teams, and network monitoring tools to verify client readiness for upcoming forks. Use cases include: + +- Automated pre-fork validation scripts comparing `eth_config` outputs across nodes. +- Manual checks by validator operators to ensure alignment with fork specifications. +- Debugging by client developers to identify configuration mismatches. +- Automated checks by Consensus Layer counterparties. + +## 3. Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +Clients MUST expose a new RPC method to report the current functional configuration and the expected next configuration via the standard JSON-RPC port. + +Clients MAY also expose this method through the Engine API. + +Clients MAY use these configuration objects to manage their per-fork configurations, though they SHOULD NOT simply return unprocessed configuration data. + +When reporting the current, next and last configurations, clients MUST include every configuration parameter specified in this BEP. + +Clients MUST return up-to-date configuration values, reflecting the most recent block header they provide. If clients cache the configuration, they MUST ensure such caches are purged when fork boundaries are crossed. + +### Configuration RPC + +A new JSON-RPC API, `eth_config`, is introduced. It takes no parameters and returns the result object specified in the next section. + +### Result Object Structure + +The RPC response contains three members: "current", "next", and "last". These members contain the configuration object currently in effect, the next configuration, and the last known configuration, respectively. "next" and "last" will be `null` if the client is not configured to support a future fork. "next" and "last" members will contain the same configuration in the case where the next configured fork is also the last configured fork. + +### Members of the Configuration Object + +Each configuration object MUST contain the following members, presented in alphabetical order. This RPC assumes the network is post-merge, and no accommodations are specified for proof-of-work-related issues. + +Future forks may add, adjust, remove, or update members. The respective changes MUST be defined in either their BEPs or their respective meta-BEPs. Added members MUST be alphabetically sorted, so simply naming the new members is sufficient definition. + +#### `activationTime` + +The fork activation timestamp, represented as a JSON number in Unix epoch seconds (UTC). For the "current" configuration, this reflects the actual activation time; for "next" and "last", it is the scheduled time. + +Activation time is required. If a fork is activated at genesis, the value `0` is used. If the fork is not scheduled to be activated or its activation time is unknown, it should not be in the RPC results. + +#### `blobSchedule` + +The blob configuration parameters for the specific fork, as defined in the genesis file. This is a JSON object with three members—`baseFeeUpdateFraction`, `max`, and `target`—all represented as JSON numbers. + +#### `chainId` + +The chain ID of the current network, presented as a string with an unsigned `0x`-prefixed hexadecimal number, with all leading zeros removed, in lower case. This specification does not support chains without a chain ID or with a chain ID of zero. + +For purposes of canonicalization, this value must always be a string. + +#### `forkId` + +The `FORK_HASH` value as specified in [EIP-6122](https://eips.ethereum.org/EIPS/eip-6122) of the specific fork, presented as an unsigned `0x`-prefixed hexadecimal number, with zeros left-padded to a four-byte length, in lower case. + +#### `precompiles` + +A representation of the active precompile contracts for the fork. If a precompiled contract is replaced by an on-chain contract—or removed—then it is not included. + +This is a JSON object where the members are the agreed-upon names for each contract, typically specified in the BEP defining that contract, and the values are the 20-byte `0x`-prefixed hexadecimal addresses of the precompiles (with zeros preserved), in lower case. + +#### `systemContracts` + +A JSON object representing system-level contracts relevant to the fork, as introduced in their defining BEPs. Keys are the contract names (e.g., `HISTORY_STORAGE_ADDRESS`) from the first BEP where they appeared, sorted alphabetically. Values are 20-byte addresses in `0x`-prefixed hexadecimal form, with leading zeros preserved, in lower case. Omitted for forks before Cancun. + +For Prague, the system contracts are (in order): `HISTORY_STORAGE_ADDRESS`. + +## 4. Rationale + +### Why Three Time Horizons? + +Providing three configurations—current, next, and last—allows clients to: +- **current**: Immediately validate active fork parameters against operational expectations. +- **next**: Verify readiness for the immediately upcoming fork. +- **last**: Confirm long-term configuration alignment. + +This approach balances operational needs (near-term validation) with strategic planning (long-term roadmap verification). + +### Why Not Include All Future Forks? + +Limiting the response to "next" and "last" reduces payload size and simplifies validation logic. Most operational issues arise from misconfiguration of the immediate next fork. Including all future forks would add complexity without proportional benefit, as far-future forks often lack finalized parameters. + +### Standardization and Consistency + +By mandating that all configuration parameters follow a consistent alphabetical ordering and naming convention, this method ensures: +- **Interoperability**: Different client implementations can be easily compared. +- **Predictability**: Tooling can parse responses without client-specific logic. +- **Extensibility**: New forks can add parameters without breaking existing parsers. + +## 5. Backwards Compatibility + +This BEP introduces a new RPC method without modifying existing ones. Clients that do not implement `eth_config` will simply not expose the endpoint, causing no disruption to existing infrastructure. + +Monitoring tools and scripts should gracefully handle the absence of `eth_config` on older clients. + +## 6. Test Cases + +### With Future Fork Scheduled + +An example request and response when a future fork (Prague) is configured: + +```JSON +{ + "jsonrpc": "2.0", + "id": 1, + "method": "eth_config", + "params": [] +} +``` + +Response: + +```JSON +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "current": { + "activationTime": 0, + "blobSchedule": { + "baseFeeUpdateFraction": 3338477, + "max": 6, + "target": 3 + }, + "chainId": "0x38", + "forkId": "0xbef71d30", + "precompiles": { + "BLAKE2F": "0x0000000000000000000000000000000000000009", + "BLS12_G1ADD": "0x000000000000000000000000000000000000000b", + "BLS12_G1MSM": "0x000000000000000000000000000000000000000c", + "BLS12_G2ADD": "0x000000000000000000000000000000000000000d", + "BLS12_G2MSM": "0x000000000000000000000000000000000000000e", + "BLS12_MAP_FP2_TO_G2": "0x0000000000000000000000000000000000000011", + "BLS12_MAP_FP_TO_G1": "0x0000000000000000000000000000000000000010", + "BLS12_PAIRING_CHECK": "0x000000000000000000000000000000000000000f", + "BLS_SIGNATURE_VERIFY": "0x0000000000000000000000000000000000000066", + "BN254_ADD": "0x0000000000000000000000000000000000000006", + "BN254_MUL": "0x0000000000000000000000000000000000000007", + "BN254_PAIRING": "0x0000000000000000000000000000000000000008", + "COMET_BFT_LIGHT_BLOCK_VALIDATE_HERTZ": "0x0000000000000000000000000000000000000067", + "ECREC": "0x0000000000000000000000000000000000000001", + "HEADER_VALIDATE": "0x0000000000000000000000000000000000000064", + "IAVL_MERKLE_PROOF_VALIDATE_PLATO": "0x0000000000000000000000000000000000000065", + "ID": "0x0000000000000000000000000000000000000004", + "KZG_POINT_EVALUATION": "0x000000000000000000000000000000000000000a", + "MODEXP": "0x0000000000000000000000000000000000000005", + "P256VERIFY": "0x0000000000000000000000000000000000000100", + "RIPEMD160": "0x0000000000000000000000000000000000000003", + "SECP256K1_SIGNATURE_RECOVER": "0x0000000000000000000000000000000000000069", + "SHA256": "0x0000000000000000000000000000000000000002", + "VERIFY_DOUBLE_SIGN_EVIDENCE": "0x0000000000000000000000000000000000000068" + }, + "systemContracts": { + "HISTORY_STORAGE_ADDRESS": "0x0000f90827f1c53a10cb7a02335b175320002935" + } + }, + "next": { + "activationTime": 1742999832, + "blobSchedule": { + "baseFeeUpdateFraction": 5007716, + "max": 9, + "target": 6 + }, + "chainId": "0x38", + "forkId": "0x0929e24e", + "precompiles": { + "BLAKE2F": "0x0000000000000000000000000000000000000009", + "BLS12_G1ADD": "0x000000000000000000000000000000000000000b", + "BLS12_G1MSM": "0x000000000000000000000000000000000000000c", + "BLS12_G2ADD": "0x000000000000000000000000000000000000000d", + "BLS12_G2MSM": "0x000000000000000000000000000000000000000e", + "BLS12_MAP_FP2_TO_G2": "0x0000000000000000000000000000000000000011", + "BLS12_MAP_FP_TO_G1": "0x0000000000000000000000000000000000000010", + "BLS12_PAIRING_CHECK": "0x000000000000000000000000000000000000000f", + "BLS_SIGNATURE_VERIFY": "0x0000000000000000000000000000000000000066", + "BN254_ADD": "0x0000000000000000000000000000000000000006", + "BN254_MUL": "0x0000000000000000000000000000000000000007", + "BN254_PAIRING": "0x0000000000000000000000000000000000000008", + "COMET_BFT_LIGHT_BLOCK_VALIDATE_HERTZ": "0x0000000000000000000000000000000000000067", + "ECREC": "0x0000000000000000000000000000000000000001", + "HEADER_VALIDATE": "0x0000000000000000000000000000000000000064", + "IAVL_MERKLE_PROOF_VALIDATE_PLATO": "0x0000000000000000000000000000000000000065", + "ID": "0x0000000000000000000000000000000000000004", + "KZG_POINT_EVALUATION": "0x000000000000000000000000000000000000000a", + "MODEXP": "0x0000000000000000000000000000000000000005", + "P256VERIFY": "0x0000000000000000000000000000000000000100", + "RIPEMD160": "0x0000000000000000000000000000000000000003", + "SECP256K1_SIGNATURE_RECOVER": "0x0000000000000000000000000000000000000069", + "SHA256": "0x0000000000000000000000000000000000000002", + "VERIFY_DOUBLE_SIGN_EVIDENCE": "0x0000000000000000000000000000000000000068" + }, + "systemContracts": { + "HISTORY_STORAGE_ADDRESS": "0x0000f90827f1c53a10cb7a02335b175320002935" + } + }, + "last": { + "activationTime": 1742999832, + "blobSchedule": { + "baseFeeUpdateFraction": 5007716, + "max": 9, + "target": 6 + }, + "chainId": "0x38", + "forkId": "0x0929e24e", + "precompiles": { + "BLAKE2F": "0x0000000000000000000000000000000000000009", + "BLS12_G1ADD": "0x000000000000000000000000000000000000000b", + "BLS12_G1MSM": "0x000000000000000000000000000000000000000c", + "BLS12_G2ADD": "0x000000000000000000000000000000000000000d", + "BLS12_G2MSM": "0x000000000000000000000000000000000000000e", + "BLS12_MAP_FP2_TO_G2": "0x0000000000000000000000000000000000000011", + "BLS12_MAP_FP_TO_G1": "0x0000000000000000000000000000000000000010", + "BLS12_PAIRING_CHECK": "0x000000000000000000000000000000000000000f", + "BLS_SIGNATURE_VERIFY": "0x0000000000000000000000000000000000000066", + "BN254_ADD": "0x0000000000000000000000000000000000000006", + "BN254_MUL": "0x0000000000000000000000000000000000000007", + "BN254_PAIRING": "0x0000000000000000000000000000000000000008", + "COMET_BFT_LIGHT_BLOCK_VALIDATE_HERTZ": "0x0000000000000000000000000000000000000067", + "ECREC": "0x0000000000000000000000000000000000000001", + "HEADER_VALIDATE": "0x0000000000000000000000000000000000000064", + "IAVL_MERKLE_PROOF_VALIDATE_PLATO": "0x0000000000000000000000000000000000000065", + "ID": "0x0000000000000000000000000000000000000004", + "KZG_POINT_EVALUATION": "0x000000000000000000000000000000000000000a", + "MODEXP": "0x0000000000000000000000000000000000000005", + "P256VERIFY": "0x0000000000000000000000000000000000000100", + "RIPEMD160": "0x0000000000000000000000000000000000000003", + "SECP256K1_SIGNATURE_RECOVER": "0x0000000000000000000000000000000000000069", + "SHA256": "0x0000000000000000000000000000000000000002", + "VERIFY_DOUBLE_SIGN_EVIDENCE": "0x0000000000000000000000000000000000000068" + }, + "systemContracts": { + "HISTORY_STORAGE_ADDRESS": "0x0000f90827f1c53a10cb7a02335b175320002935" + } + } + } +} +``` + +### Without Future Fork Scheduled + +When no future forks are configured, the same RPC command would return: + +```JSON +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "current": { + "activationTime": 0, + "blobSchedule": { + "baseFeeUpdateFraction": 3338477, + "max": 6, + "target": 3 + }, + "chainId": "0x38", + "forkId": "0xbef71d30", + "precompiles": { + "BLAKE2F": "0x0000000000000000000000000000000000000009", + "BLS12_G1ADD": "0x000000000000000000000000000000000000000b", + "BLS12_G1MSM": "0x000000000000000000000000000000000000000c", + "BLS12_G2ADD": "0x000000000000000000000000000000000000000d", + "BLS12_G2MSM": "0x000000000000000000000000000000000000000e", + "BLS12_MAP_FP2_TO_G2": "0x0000000000000000000000000000000000000011", + "BLS12_MAP_FP_TO_G1": "0x0000000000000000000000000000000000000010", + "BLS12_PAIRING_CHECK": "0x000000000000000000000000000000000000000f", + "BLS_SIGNATURE_VERIFY": "0x0000000000000000000000000000000000000066", + "BN254_ADD": "0x0000000000000000000000000000000000000006", + "BN254_MUL": "0x0000000000000000000000000000000000000007", + "BN254_PAIRING": "0x0000000000000000000000000000000000000008", + "COMET_BFT_LIGHT_BLOCK_VALIDATE_HERTZ": "0x0000000000000000000000000000000000000067", + "ECREC": "0x0000000000000000000000000000000000000001", + "HEADER_VALIDATE": "0x0000000000000000000000000000000000000064", + "IAVL_MERKLE_PROOF_VALIDATE_PLATO": "0x0000000000000000000000000000000000000065", + "ID": "0x0000000000000000000000000000000000000004", + "KZG_POINT_EVALUATION": "0x000000000000000000000000000000000000000a", + "MODEXP": "0x0000000000000000000000000000000000000005", + "P256VERIFY": "0x0000000000000000000000000000000000000100", + "RIPEMD160": "0x0000000000000000000000000000000000000003", + "SECP256K1_SIGNATURE_RECOVER": "0x0000000000000000000000000000000000000069", + "SHA256": "0x0000000000000000000000000000000000000002", + "VERIFY_DOUBLE_SIGN_EVIDENCE": "0x0000000000000000000000000000000000000068" + }, + "systemContracts": { + "BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02" + } + }, + "next": null, + "last": null + } +} +``` + +## 7. Security Considerations + +- **Exposure Risks**: Incorrect configurations could leak operational details. Operators SHOULD restrict `eth_config` to trusted interfaces (e.g., local access or authenticated endpoints). +- **Dishonest Nodes**: Clients may report false configurations. Peers or monitoring tools MAY cross-check `eth_config` outputs against known fork specifications or other nodes' responses to detect anomalies. +- **DDoS Mitigation**: Clients MAY cache configuration objects internally and rate-limit `eth_config` requests to prevent resource exhaustion. Implementations MAY impose a minimum response interval (e.g., 1 second). + +## 8. License + +All content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + + diff --git a/BEPs/BEP-657.md b/BEPs/BEP-657.md new file mode 100644 index 00000000..8c1bb387 --- /dev/null +++ b/BEPs/BEP-657.md @@ -0,0 +1,77 @@ +
+  BEP: 657
+  Title: Limit Blob Transaction Inclusion by Block Number
+  Status: Enabled
+  Type: Standards
+  Created: 2026-01-21
+  Description: Restrict blob transactions to blocks where block number modulo N equals zero. Initial N=5.
+
+ +# BEP-657: Limit Blob Transaction Inclusion by Block Number + +- [BEP-657: Limit Blob Transaction Inclusion by Block Number](#bep-657-limit-blob-transaction-inclusion-by-block-number) + - [1. Summary](#1-summary) + - [2. Motivation](#2-motivation) + - [3. Specification](#3-specification) + - [3.1 Blob Transaction Inclusion Rules](#31-blob-transaction-inclusion-rules) + - [3.2 Blob Fee Calculation Modification](#32-blob-fee-calculation-modification) + - [4. Rationale](#4-rationale) + - [5. Backward Compatibility](#5-backward-compatibility) + - [6. License](#6-license) + +## 1. Summary + +This BEP restricts blob transaction inclusion to blocks where the block number modulo N equals zero. **The initial value of N is set to 5**, allowing blob transactions in blocks 0, 5, 10, 15, etc. Non-eligible blocks preserve blob fee state from their parent to maintain market continuity. + +## 2. Motivation + +BSC's block time has been reduced from 3 seconds to 0.45 seconds, yet blob transaction volume has remained relatively constant at approximately one per 7-8 blocks. This mismatch has resulted in severe blob space oversupply. + +**Blob Fee Market Dysfunction**: The ~6.7x increase in blob capacity with unchanged demand has caused the blob base fee to consistently remain at its minimum floor price. This prevents the EIP-4844 fee market mechanism from functioning properly, as it relies on supply-demand dynamics for price discovery. + +By restricting blob transactions to every Nth block (blocks where `blockNumber % N == 0`), this BEP concentrates demand to restore proper fee market dynamics while maintaining adequate capacity for current usage patterns. **The initial value of N is set to 5**, meaning blob transactions can only be included in blocks 0, 5, 10, 15, etc. With 0.45s block times, the maximum inclusion delay of 2.25 seconds has minimal impact on L2 operations. + +## 3. Specification + +### 3.1 Blob Transaction Inclusion Rules + +Define a parameter N that determines the frequency of eligible blocks. **The initial value of N is 5.** + +For any block with block number `blockNumber`: +- If `blockNumber % N == 0`: The block MAY contain blob transactions +- If `blockNumber % N != 0`: The block MUST NOT contain any blob transactions + +Blocks violating this rule MUST be rejected as invalid. + +With N=5, eligible blocks are: 0, 5, 10, 15, 20, 25, 30, etc. + +### 3.2 Blob Fee Calculation Modification + +**For blocks where `blockNumber % N == 1`:** +- Normal EIP-4844 blob fee calculation applies + +**For blocks where `blockNumber % N != 1`:** +- `header.ExcessBlobGas` MUST equal `parent.ExcessBlobGas` + +This ensures the blob fee is calculated once after each eligible block, then preserved across subsequent blocks until the next calculation. + +## 4. Rationale + +The modulo N restriction (1 in every N blocks) aligns with current demand patterns. **This BEP sets N=5 as the initial value.** + +* **Fee Market Alignment**: Current usage (~1 blob tx per 7-8 blocks) naturally fits within the 1-in-5 schedule, enabling proper EIP-4844 fee mechanism operation while providing room for demand growth. +* **Minimal User Impact**: With 0.45s block time, maximum inclusion delay is 2.25 seconds, negligible for L2 sequencers posting data every 30-60 seconds. +* **Fee Continuity**: Non-eligible blocks inherit blob fee state from their parent, preserving market state across the 4-block gap and enabling proper price discovery at the next eligible block. +* **Adjustable Parameter**: N can be adjusted in future upgrades to adapt to changing demand patterns without requiring fundamental changes to the mechanism. + +## 5. Backward Compatibility + +This is a consensus-breaking change requiring a hard fork. All validators and full nodes must upgrade before activation. + +Transaction submitters must ensure blob transactions target eligible blocks (blocks where `blockNumber % N == 0`). **With N=5, eligible blocks are 0, 5, 10, 15, 20, etc.** Blob-related MEV opportunities will concentrate in these eligible blocks. + +## 6. License + +This document is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + + diff --git a/BEPs/BEP-658.md b/BEPs/BEP-658.md new file mode 100644 index 00000000..bbf9d0e6 --- /dev/null +++ b/BEPs/BEP-658.md @@ -0,0 +1,84 @@ +
+  BEP: 658
+  Title: BEP-658: Hardfork Meta-Osaka/Mendel
+  Status: Enabled
+  Type: Information
+  Created: 2026-01-22
+  Description: BEPs included in the Osaka/Mendel BSC network upgrade.
+
+ +# BEP-658: Hardfork Meta-Osaka/Mendel + +- [BEP-658: Hardfork Meta-Osaka/Mendel](#bep-658-hardfork-meta-osakamendel) + - [1. Summary](#1-summary) + - [2. Specification](#2-specification) + - [BEPs Scheduled for Inclusion](#beps-scheduled-for-inclusion) + - [BEPs need hard fork](#beps-need-hard-fork) + - [BEPs without hard fork](#beps-without-hard-fork) + - [Rejected EIPs defined in Fusaka](#rejected-eips-defined-in-fusaka) + - [3. Rationale](#3-rationale) + - [4. Security Considerations](#4-security-considerations) + - [5. Copyright](#5-copyright) + + +## 1. Summary + +This Meta BEPs lists the BEPs formally Scheduled for Inclusion in the Osaka/Mendel network upgrade. + +## 2. Specification + +The Mendel network upgrade comprises a total of 9 BEPs. Out of the 13 EIPs introduced in Ethereum's Fusaka scope, BSC has adopted 7 EIPs (6 requiring a hard fork and 1 as a client-side RPC update) while rejecting the remaining 6 EIPs due to architectural differences. Furthermore, the upgrade introduces two BSC-exclusive enhancements: BEP-657, which limits blob transaction inclusion by block number, and BEP-648, designed to reduce latency for Fast Finality. + +### BEPs Scheduled for Inclusion + +#### BEPs need hard fork + +* [BEP-651](./BEP-651.md): Implement EIP-7823 Set upper bounds for MODEXP + * follow the raw specification in [EIP-7823](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7823.md) +* [BEP-652](./BEP-652.md): Implement EIP-7825 Transaction Gas Limit Cap + * follow the raw specification in [EIP-7825](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7825.md) +* [BEP-653](./BEP-653.md): Implement EIP-7883 ModExp Gas Cost Increase + * follow the raw specification in [EIP-7883](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7883.md) +* [BEP-654](./BEP-654.md): Implement EIP-7939 Count Leading Zeros (CLZ) Opcode + * follow the raw specification in [EIP-7939](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7939.md) +* [BEP-655](./BEP-655.md): Implement EIP-7934 RLP Execution Block Size Limit + * there is no beacon client in BSC, so just limit RLP Execution Block Size to 8M to by following the raw specification in [EIP-7934](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7934.md) +* [BEP-657](./BEP-657.md): Limit Blob Transaction Inclusion by Block Number + * BSC Only +* [BEP-659](./BEP-659.md): Implement EIP-7951 Precompile for secp256r1 Curve Support + * have implement by [BEP-381](./BEP-381.md) in BSC Haber hard fork, now change the gas cost by following the raw specification in [EIP-7951](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7951.md) + + +#### BEPs without hard fork + +* [BEP-648](./BEP-648.md): Enhanced Fast Finality via In-Memory Voting Pool + * BSC Only +* [BEP-656](./BEP-656.md): Implement EIP-7910: eth_config JSON-RPC Method + * Client teams MUST support this JSON-RPC method by the activation of Osaka/Mendel network upgrade. + +#### Rejected EIPs defined in [Fusaka](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7607.md) + +* [EIP-7642](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7642.md): eth/69 - Drop pre-merge fields + * eth/69 is not supported in BSC +* [EIP-7594](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7594.md): PeerDAS - Peer Data Availability Sampling + * not need in BSC +* [EIP-7892](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7892.md): Blob Parameter Only Hardforks + * not need in BSC +* [EIP-7917](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7917.md): Deterministic proposer lookahead + * proposer in BSC is already deterministic +* [EIP-7918](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7918.md): Blob base fee bounded by execution cost + * base fee in BSC is always 0 +* [EIP-7935](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7935.md): Set default gas limit to 60M + * not really need in BSC + +## 3. Rationale + +This Meta EIP provides a global view of all changes included in the Osaka/Mendel network upgrade, as well as links to full specification. + +## 4. Security Considerations + +None. + +## 5. Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP-659.md b/BEPs/BEP-659.md new file mode 100644 index 00000000..86c5d5d7 --- /dev/null +++ b/BEPs/BEP-659.md @@ -0,0 +1,267 @@ +
+  BEP: 659
+  Title: Implement EIP-7951 Precompile for secp256r1 Curve Support
+  Status: Enabled
+  Type: Standards
+  Created: 2026-01-20
+  Description: Add precompiled contract for secp256r1 ECDSA signature verification with proper security checks
+
+ +# BEP-659: Implement EIP-7951 Precompile for secp256r1 Curve Support + +- [BEP-659: Implement EIP-7951 Precompile for secp256r1 Curve Support](#bep-659-implement-eip-7951-precompile-for-secp256r1-curve-support) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [Precompile](#precompile) + - [Curve Parameters](#curve-parameters) + - [Fields and Groups](#fields-and-groups) + - [Points and Encoding](#points-and-encoding) + - [Field Elements Encoding](#field-elements-encoding) + - [Encoding of Points in G](#encoding-of-points-in-g) + - [Point of Infinity Encoding](#point-of-infinity-encoding) + - [Encoding of Scalars](#encoding-of-scalars) + - [Behavior on Invalid Inputs](#behavior-on-invalid-inputs) + - [ABI for P256VERIFY Operation](#abi-for-p256verify-operation) + - [Input](#input) + - [Output](#output) + - [Input Validation](#input-validation) + - [Signature Verification Algorithm](#signature-verification-algorithm) + - [Error Cases](#error-cases) + - [Gas Schedule](#gas-schedule) + - [P256VERIFY operation](#p256verify-operation) + - [Gas Burning on Error](#gas-burning-on-error) + - [5. Rationale](#5-rationale) + - [Security Fixes](#security-fixes) + - [Verification vs Recovery](#verification-vs-recovery) + - [Gas Cost Justification](#gas-cost-justification) + - [6. Backwards Compatibility](#6-backwards-compatibility) + - [Interface Compatibility](#interface-compatibility) + - [7. Test Cases](#7-test-cases) + - [8. Security Considerations](#8-security-considerations) + - [Cryptographic Security](#cryptographic-security) + - [Malleability](#malleability) + - [Side-Channel Resistance](#side-channel-resistance) + - [9. License](#9-license) + +## 1. Summary + +BSC already supports functionality to efficiently perform ECDSA signature verification over the secp256r1.This BEP adopts the EIP-7951 implementation and updates the gas cost accordingly. + +## 2. Abstract + +Add functionality to efficiently perform ECDSA signature verification over the secp256r1 elliptic curve (also known as P-256 or prime256v1). This precompile enables native support for signatures generated by modern secure hardware including Apple Secure Enclave, Android Keystore, and FIDO2/WebAuthn devices. + +This specification addresses critical security issues discovered in RIP-7212 while maintaining full interface compatibility with existing Layer 2 implementations. + +## 3. Motivation + +The secp256r1 elliptic curve is a NIST-standardized curve widely supported in modern secure hardware and authentication systems. Adding native support for secp256r1 signature verification to BSC enables several important use cases that are currently impossible or prohibitively expensive. + +Modern secure hardware devices, including Apple Secure Enclave, Android Keystore, HSMs, TEEs, and FIDO2/WebAuthn authenticators, use secp256r1 for key storage and signing operations. Native secp256r1 support enables sophisticated account abstraction patterns like device-native signing, multi-factor authentication, and simplified key management - ultimately reducing friction for mainstream adoption through familiar authentication flows. + +The secp256r1 curve is already widely supported across blockchain networks and protocols, including Layer 2 networks, enterprise blockchains, and interoperability protocols. This broad compatibility enables seamless integration with existing infrastructure while maintaining security through hardware-backed signing capabilities. + +This BEP supersedes RIP-7212 by implementing the same functionality with the same interface, but without the vulnerability. + +## 4. Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +### Precompile + +We introduce `P256VERIFY` a precompile at the address `0x100` which performs ECDSA signature verification over the secp256r1 curve with a gas cost of `6900` gas + +### Curve Parameters + +The secp256r1 curve is fully defined by the following set of parameters: + +```text +Base field modulus = p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff +Curve equation: y^2 = x^3 + ax + b (mod p) +Curve coefficient a = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc +Curve coefficient b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b +Base point G: + Gx = 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 + Gy = 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 +Subgroup order = n = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 +Cofactor = h = 0x1 +``` + +These parameters are standardized by NIST in SP 800-186. + +### Fields and Groups + +The field Fp is defined as the finite field of size `p` with elements represented as integers between 0 and p-1 (both inclusive). + +The group G is defined as a set of Fp pairs (points) `(x,y)` such that either `(x,y)` is `(0,0)` (representing the point at infinity) or `x,y` satisfy the curve equation `y^2 = x^3 + ax + b (mod p)`. + +### Points and Encoding + +#### Field Elements Encoding + +A base field element (Fp) is encoded as `32` bytes by performing BigEndian encoding of the corresponding (unsigned) integer. The corresponding integer **must** be less than the field modulus `p`. + +#### Encoding of Points in G + +Points in G are encoded as byte concatenation of the respective encodings of the `x` and `y` coordinates. Total encoding length for a G point is thus `64` bytes. + +#### Point of Infinity Encoding + +For secp256r1, the point with coordinates `(0, 0)` (zeroes in Fp) is *not* on the curve, so a sequence of `64` zero bytes is used by convention to encode the point of infinity. + +#### Encoding of Scalars + +A scalar is encoded as `32` bytes by performing BigEndian encoding of the corresponding (unsigned) integer. The corresponding integer is **not** required to be less than or equal to the subgroup order `n`. + +#### Behavior on Invalid Inputs + +On inputs that cannot be valid encodings of field elements or points, the precompile *must* return `` (failure). + +### ABI for P256VERIFY Operation + +#### Input + +`P256VERIFY` call expects `160` bytes as input that is interpreted as byte concatenation of: + +- `32` bytes: message hash `h` +- `32` bytes: signature component `r` +- `32` bytes: signature component `s` +- `32` bytes: public key x-coordinate `qx` +- `32` bytes: public key y-coordinate `qy` + +#### Output + +Output is `32` bytes on successful verification and `0` bytes on failure: + +- `0x0000000000000000000000000000000000000000000000000000000000000001` for valid signatures +- `` for invalid signatures or invalid inputs + +#### Input Validation + +The precompile MUST perform the following validation checks and return `` (failure) if any check fails: + +1. **Input length**: Input MUST be exactly `160` bytes +2. **Signature component bounds**: Both `r` and `s` MUST satisfy `0 < r < n` and `0 < s < n` +3. **Public key bounds**: Both `qx` and `qy` MUST satisfy `0 ≤ qx < p` and `0 ≤ qy < p` +4. **Point validity**: The point `(qx, qy)` MUST satisfy the curve equation `qy^2 ≡ qx^3 + a*qx + b (mod p)` +5. **Point not at infinity**: The point `(qx, qy)` MUST NOT be the point at infinity (represented as `(0, 0)`) + +#### Signature Verification Algorithm + +The verification algorithm follows these steps: + +```text +# Input validation (as specified above) +if input_length != 160: + return +if not (0 < r < n and 0 < s < n): + return +if not (0 ≤ qx < p and 0 ≤ qy < p): + return +if qy^2 ≢ qx^3 + a*qx + b (mod p): + return +if (qx, qy) == (0, 0): + return + +# Signature verification +s1 = s^(-1) (mod n) + +# Recover the random point used during signing +R' = (h * s1) * G + (r * s1) * (qx, qy) + +# Check for point at infinity +if R' is the point at infinity: + return + +# Extract x-coordinate from r +r' = R'.x + +# Compare with modular reduction +if r' ≡ r (mod n): + return 0x0000000000000000000000000000000000000000000000000000000000000001 +else: + return +``` + +#### Error Cases + +- Invalid input length (not exactly 160 bytes) +- Invalid field element encoding (≥ field modulus) +- Invalid signature component bounds (r or s not in range (0, n)) +- Invalid public key (point at infinity or not on curve) +- Signature verification failure + +### Gas Schedule + +#### P256VERIFY operation + +`6900` gas + +This cost is based on benchmarking against the existing `ECRECOVER` precompile (`3000` gas). During benchmarks we found that the actual cost of R1 verification was significantly slower than the `ECRECOVER` precompile and the decision was made to increase the gas cost to `6900` gas. + +#### Gas Burning on Error + +The precompile MUST NOT revert under any circumstances. Invalid inputs or verification failures MUST return `` and consume the same amount of gas had verification succeeded. + +## 5. Rationale + +### Security Fixes + +**Note: BSC’s previous BEP implementation already handled these cases correctly and was not impacted by the two issues described below.** + +1. **Point-at-infinity check**: The original RIP-7212 failed to check if the recovered point R' is the point at infinity. This could lead to non-deterministic behavior where the verification result depends on the underlying implementation's handling of infinity points, potentially causing consensus failures. + +2. **Modular comparison**: The original comparison `r' == r` should be `r' ≡ r (mod n)` to handle cases where the x-coordinate of R' exceeds the curve order n. This ensures mathematically correct verification according to ECDSA standards. + +### Verification vs Recovery + +This specification uses signature verification rather than public key recovery (like `ECRECOVER`) because: + +- Most secp256r1 implementations in hardware and software verify signatures directly +- The NIST FIPS 186-5 standard specifies verification, not recovery +- Verification is more efficient than recovery for this curve +- Existing hardware implementations provide verification interfaces + +### Gas Cost Justification + +The 6900 gas cost does not maintain compatibility with L2s, but it matches closer the benchmarks of actual implementations. + +## 6. Backwards Compatibility + +This BEP maintains full interface compatibility with RIP-7212 implementations deployed on Layer 2 networks. The same contract bytecode that works with RIP-7212 will work with this specification. + +The security fixes are transparent to correctly implemented callers - they only affect edge cases that should have failed verification anyway. No existing valid use cases are broken. + +### Interface Compatibility + +The precompile maintains a similar interface as RIP-7212 to ensure compatibility with existing Layer 2 deployments: + +- Same address: `0x100` +- Same input format: 160 bytes +- Same output format: 32 bytes +- Different gas cost: 3450 gas vs 6900 gas +- Same return values + +## 7. Test Cases + +A set of test vectors for verifying implementations is located in a separate [file](https://github.com/ethereum/EIPs/blob/master/assets/eip-7951/test-vectors.json). + +## 8. Security Considerations + +### Cryptographic Security + +The secp256r1 curve provides approximately 128 bits of security, equivalent to secp256k1 already in use in Ethereum. The curve parameters are standardized by NIST SP 800-186 and have undergone extensive cryptographic analysis by the wider cryptographic community in addition to this curve being deployed to several L2s in the form of RIP-7212. + +### Malleability + +Unlike secp256k1 ECDSA signatures, secp256r1 ECDSA signatures are not required to be non-malleable per NIST FIPS 186-5 standard. Applications requiring non-malleability should implement additional checks at the application layer. + +### Side-Channel Resistance + +We explicitly state that this precompile **IS NOT REQUIRED** to perform all the operations using constant time algorithms. + +## 9. License + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-667.md b/BEPs/BEP-667.md new file mode 100644 index 00000000..cfdc71b4 --- /dev/null +++ b/BEPs/BEP-667.md @@ -0,0 +1,147 @@ +
+  BEP: 667
+  Title: Introduce Vote Interval to Relax Fast Finality Consensus Constraint
+  Status: Draft
+  Type: Standards
+  Created: 2026-03-02
+  Description: Maintain stability of Fast Finality when reducing block interval further by relaxing per-block voting to per-N-block voting.
+
+ +# BEP-667: Introduce Vote Interval to Relax Fast Finality Consensus Constraint + +- [BEP-667: Introduce Vote Interval to Relax Fast Finality Consensus Constraint](#bep-667-introduce-vote-interval-to-relax-fast-finality-consensus-constraint) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [4.1 Vote Interval Parameter](#41-vote-interval-parameter) + - [4.2 Consensus Rule Changes](#42-consensus-rule-changes) + - [5. Relationship with BEP-590](#5-relationship-with-bep-590) + - [6. Performance Analysis](#6-performance-analysis) + - [7. Finality Analysis](#7-finality-analysis) + - [8. Security](#8-security) + - [9. Backward Compatibility](#9-backward-compatibility) + - [10. License](#10-license) + +## 1. Summary + +This BEP introduces a **Vote Interval (N)** parameter to the Fast Finality mechanism ([BEP-126](./BEP126.md)), relaxing the consensus constraint from per-block voting to per-N-block voting. This breaks the fundamental `BlockInterval > 2 × OWD` physical limit, maximizing the time window available for block importing. **The initial value of N is 2.** + +Both [BEP-590](./BEP-590.md) and this BEP tolerate late votes — BEP-590 by extending ancestor depth within per-block voting, this BEP by structurally enlarging the voting interval to N blocks. + +## 2. Abstract + +Under the current Fast Finality mechanism (BEP-126), validators must complete a full vote-propagation cycle within each block interval, imposing a hard physical constraint. This BEP introduces a configurable Vote Interval `N` — validators only vote on every Nth block — relaxing the constraint to: + +``` +N × BlockInterval > 2 × OWD + T_import +``` + +where `OWD` (One-Way Delay) is the one-way network delay between validators and `T_import` is the block import/verification time. The current per-block voting model is `N = 1`. By increasing N, the minimum block interval drops to `(2 × OWD + T_import) / N`, breaking through the physical barrier of per-block voting. + +## 3. Motivation + +The current block interval of 450ms on BSC ([BEP-619](./BEP-619.md)) is approaching the physical limit imposed by Fast Finality's per-block voting requirement. + +BEP-126 assumes that "1 block time is totally enough for validators to receive a block, vote for the block and propagate the vote to other validators." This assumption requires: + +``` +BlockInterval > 2 × OWD + T_import +``` + +Block propagation from the proposer to validators takes one `OWD` (~120ms), validators execute the block (`T_import`), and vote propagation back takes another `OWD`. The proposer's effective overhead is `2 × OWD = 240ms` (validators execute during the round-trip), and vote propagation dominates the time budget: + +``` +|<------------ BlockInterval (450ms) ------------>| +| T_const | T_import (~210ms) | +| (~240ms) | | + +CPU Utilization ≈ T_import / BlockInterval = 210 / 450 ≈ 46.7% +``` + +More than half of each block interval is consumed by consensus overhead rather than transaction processing. As block intervals decrease further, this ratio worsens — the constant `2 × OWD` overhead takes an ever-larger share. + +By voting every N blocks, the `2 × OWD` overhead is amortized across N intervals, dramatically increasing the fraction of time available for packing. + +## 4. Specification + +### 4.1 Vote Interval Parameter + +Introduce a new consensus parameter: + +``` +VoteInterval = N (initial value: 2) +``` + +where `N ≥ 1` is a positive integer. When `N = 1`, the behavior is identical to the current per-block voting model. The value of N is adjusted alongside block interval changes via hard fork. + +A block is defined as a **voting block** if: + +``` +blockNumber % N == 0 +``` + +Only voting blocks participate in the Fast Finality vote-aggregate-justify cycle. Non-voting blocks are produced and validated normally but do not carry vote attestations in their headers and do not trigger voting. + +### 4.2 Consensus Rule Changes + +All existing BEP-126 rules (validator voting, vote aggregation, justification, and finalization) remain unchanged — they simply operate on the **voting block subsequence** instead of every block. When a voting block is finalized, all non-voting blocks between it and the previous finalized voting block are also considered finalized. + +## 5. Relationship with BEP-590 + +Both BEP-590 and BEP-667 tolerate late votes, but at different granularity. BEP-590 extends `KAncestorGenerationDepth` within per-block voting to fall back to older ancestors when the immediate parent's votes are delayed. BEP-667 structurally enlarges the voting interval to N blocks, so the normal propagation window is already `N × BlockInterval`. + +With Vote Interval, `KAncestorGenerationDepth` operates on the voting block subsequence and aligns with N (e.g., `depth = 2` when `N = 2`). + +## 6. Performance Analysis + +From `N × BlockInterval > 2 × OWD + T_import`, the maximum T_import is `N × BlockInterval - 2 × OWD` (capped at BlockInterval). With `OWD ≈ 120ms`: + +| BlockInterval | N | Max T_import | CPU Utilization | +|---------------|---|--------------|-----------------| +| 450ms | 1 | 210ms | 46.7% | +| 450ms | 2 | 450ms | ~100% | +| 250ms | 1 | 10ms | 4% | +| 250ms | 2 | 250ms | ~100% | +| 100ms | 2 | — (infeasible) | — | +| 100ms | 3 | 60ms | 60% | + + +## 7. Finality Analysis + +Vote Interval applies the BEP-126 justify/finalize rules — refined by [BEP-648](./BEP-648.md) — to the voting block subsequence. Let `j = blockNumber mod N`. A voting block V[k] is finalized once both V[k] and V[k+1] are justified; a non-voting block is finalized together with the next voting block: + +``` + ⎧ N × BI + (2 × OWD + T_import) if j = 0 (voting block) +L(j) = ⎨ + ⎩ (2N − j) × BI + (2 × OWD + T_import) if 1 ≤ j < N (non-voting block) +``` + +where `2 × OWD + T_import` is the vote-gathering time, strictly less than `N × BI`. + +With `OWD ≈ 120ms`: + +| BlockInterval | N | T_import | Voting (j=0) | Worst (j=1) | Average | +|---------------|---|-------------------|--------------|-------------|---------| +| 450ms (today) | 1 | 210ms | 900ms | — | 900ms | +| 250ms | 2 | 250ms (saturated) | 990ms | 1240ms | 1115ms | +| 250ms | 2 | 100ms (50M gas) | 840ms | 1090ms | 965ms | +| 100ms | 3 | 60ms (saturated) | 600ms | 800ms | 700ms | + +Even with throughput nearly doubling to ~200M gas/s (`N = 2, BI = 250ms`, 50M gas limit, `T_import ≈ 100ms`), average finality remains **965ms — still sub-second** (vs. today's 900ms at ~122M gas/s). + +## 8. Security + +This BEP does not alter the vote rules, finality thresholds, or cryptographic assumptions of BEP-126. The voting block subsequence satisfies the same invariants — identical vote rules, same ⅔+ threshold — so the proofs of **Accountable Safety** (Theorem 1) and **Plausible Liveness** (Theorem 2) apply directly. + +Block production liveness is unaffected: non-voting blocks do not require Fast Finality participation, and the chain can grow with ½+1 validators online as before. + +## 9. Backward Compatibility + +This BEP is **not backward compatible**. It changes the Fast Finality voting and aggregation rules, requiring a hard fork with coordinated client upgrades across all validators and full nodes. + +Finality latency changes from `2 × BlockInterval` to `N × BI + (2 × OWD + T_import)` for voting blocks and `(2N - j) × BI + (2 × OWD + T_import)` for non-voting blocks at position `j` . + +## 10. License + +The content is licensed under [Creative Commons CC0 1.0 Universal License](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-670.md b/BEPs/BEP-670.md new file mode 100644 index 00000000..16163e8c --- /dev/null +++ b/BEPs/BEP-670.md @@ -0,0 +1,107 @@ +
+  BEP: 670
+  Title: Short Block Interval Phase Four: 250ms
+  Status: Draft
+  Type: Standards
+  Created: 2026-03-02
+  Description: To shorten the block interval from 450ms to 250ms, enabled by Vote Interval (BEP-667).
+
+ +# BEP-670: Short Block Interval Phase Four: 250ms + +- [BEP-670: Short Block Interval Phase Four: 250ms](#bep-670-short-block-interval-phase-four-250ms) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [4.1 Parameter Changes](#41-parameter-changes) + - [4.1.1 Change Table](#411-change-table) + - [4.2 Vote Interval](#42-vote-interval) + - [5. Rationale](#5-rationale) + - [5.1 Parameter Changes](#51-parameter-changes) + - [6. Backward Compatibility](#6-backward-compatibility) + - [6.1 MEV](#61-mev) + - [6.2 Block Finality](#62-block-finality) + - [7. License](#7-license) + +## 1. Summary + +This proposal shortens the block interval from 450ms to 250ms, further improving transaction confirmation speed and enhancing user experience. + +## 2. Abstract + +* **BEP-520** (Phase One): reduced the block interval from 3 seconds to 1.5 seconds. +* **BEP-524** (Phase Two): reduced it further to 0.75 seconds. +* **BEP-619** (Phase Three): reduced it to 0.45 seconds. +* **BEP-670** (Phase Four, this proposal): reduces it to 0.25 seconds. + +This phase depends on [BEP-667](./BEP-667.md) (Vote Interval), which relaxes the Fast Finality constraint from per-block voting to per-N-block voting, enabling practical block intervals where per-block voting would leave insufficient time for block importing. + +## 3. Motivation + +Reducing the block interval is a long-term goal of BNB Smart Chain. A 250ms block interval will support time-sensitive applications by providing significantly faster confirmation times. + +Under the current per-block voting model, the constraint `BlockInterval > 2 × OWD + T_import` limits how much of each block interval is available for block importing. At 250ms with `N = 1`, only `250 - 240 = 10ms` would remain for importing — effectively unusable. BEP-667 introduces Vote Interval (`N = 2`), relaxing the constraint to `2 × BlockInterval > 2 × OWD + T_import`, which at 250ms yields `T_import < 260ms` — nearly full utilization. + +## 4. Specification + +The overall design follows BEP-619, with modifications to the relevant parameters and the introduction of Vote Interval. + +### 4.1 Parameter Changes + +Phases one through four are closely related. For clarity, their parameter changes are consolidated into the following table. + +#### 4.1.1 Change Table + +Many system parameters are tied to the default block interval. When the interval is adjusted, related parameters must also be updated: + +| Parameter | Type | Origin (3s) | Phase One (1.5s) | Phase Two (0.75s) | Phase Three (0.45s) | Phase Four (0.25s) | +| ------------------------------------ | -------- | ---------------------- | ---------------- | ----------------- | ------------------- |---------------------| +| Epoch | client | 200 | 500 | 1000 | 1000 | 2000 | +| VoteInterval | client | 1 | 1 | 1 | 1 | 2 | +| GasLimit | client | 140M | 100M | 75M | 55M | 30M | +| GasLimitBoundDivisor | client | 256 | 1024 | 1024 | 1024 | 1024 | +| FullImmutabilityThreshold | client | 90,000 | 180,000 | 360,000 | 600,000 | 1,080,000 | +| receiveRateLimitPerSecond | client | 10 | 20 | 40 | 68 | 60 | +| BlobInterval (BEP-657) | client | 1 | 1 | 1 | 5 | 10 | +| Blob Target | client | 3 | 3 | 3 | 3 | 3 | +| Blob Maximum | client | 6 | 6 | 6 | 6 | 6 | +| Blob MinBlocksForBlobRequests | client | 524,288 | 1,048,576 (×2) | 2,097,152 (×4) | 3,495,254 (×3/0.45) | 6,291,456 (×3/0.25) | +| BSCGovernor.votingPeriod | contract | \$votingPeriod | ×2 | ×4 | ×(3/0.45) | ×(3/0.25) | +| BSCGovernor.minPeriodAfterQuorum | contract | \$minPeriodAfterQuorum | ×2 | ×4 | 172800(maximum) | ×12(345600) | +| BSCValidatorSet.misdemeanorThreshold | contract | \$misdemeanorThreshold | ×2 | ×4 | ×(3/0.45) | ×(3/0.25) | +| BSCValidatorSet.felonyThreshold | contract | \$felonyThreshold | ×2 | ×4 | ×(3/0.45) | ×(3/0.25) | +| BSCValidatorSet.felonySlashScope | contract | \$felonySlashScope | ×2 | ×4 | ×(3/0.45) | ×(3/0.25) | + +`receiveRateLimitPerSecond` is reduced from 68 to 60 because with `VoteInterval = 2`, validators vote on every other block, reducing vote traffic. + +### 4.2 Vote Interval + +With the block interval reduced to 250ms, per-block voting (`N = 1`) leaves only `250 - 240 = 10ms` for block importing. This phase activates [BEP-667](./BEP-667.md) with `VoteInterval = 2`, so validators vote on every other block. The effective vote cycle becomes `2 × 250ms = 500ms`, giving validators sufficient time to import blocks and propagate votes. + +## 5. Rationale + +### 5.1 Parameter Changes + +* **GasLimit**: Adjusted proportionally from 55M to 30M to match the reduced interval. +* **Epoch**: Increased from 1000 to 2000 blocks to maintain a similar epoch duration (~500s). The value is a multiple of `VoteInterval = 2`, ensuring epoch boundaries align with voting blocks. +* **VoteInterval**: Set to 2, the minimum value that satisfies the Fast Finality constraint at 250ms. This is the first phase to require Vote Interval, as all previous phases operated within the per-block voting limit. + +## 6. Backward Compatibility + +### 6.1 MEV + +With a 250ms block interval, each validator produces 8 consecutive blocks per turn, with total turn time of 2s (0.25 × 8). This further narrows the collaboration window for searchers, builders, and validators, requiring adjustments to current MEV strategies. + +### 6.2 Block Finality + +The fast finality mechanism now operates on voting blocks per BEP-667. With `VoteInterval = 2`: + +* **With fast finality working correctly**: finality latency ranges from 1000ms (voting blocks) to 1250ms (non-voting blocks), averaging 1125ms. +* **If fast finality fails** (natural finality with TurnLength=8, ValidatorSize=21): + * \> 1/2 validator confirmations: 88 blocks (11×8) ≈ 22s + * \> 2/3 validator confirmations: 120 blocks (15×8) ≈ 30s + +## 7. License + +This document is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-673.md b/BEPs/BEP-673.md new file mode 100644 index 00000000..cd7cb922 --- /dev/null +++ b/BEPs/BEP-673.md @@ -0,0 +1,47 @@ +
+  BEP: 673
+  Title: BEP-673: Hardfork Meta-Pasteur
+  Status: Draft
+  Type: Information
+  Created: 2026-03-06
+  Description: BEPs included in the Pasteur BSC network upgrade.
+
+ +# BEP-673: Hardfork Meta-Pasteur + +- [BEP-673: Hardfork Meta-Pasteur](#bep-673-hardfork-meta-pasteur) + - [1. Summary](#1-summary) + - [2. Specification](#2-specification) + - [BEPs Scheduled for Inclusion](#beps-scheduled-for-inclusion) + - [BEPs need hard fork](#beps-need-hard-fork) + - [BEPs without hard fork](#beps-without-hard-fork) + - [3. Security Considerations](#3-security-considerations) + - [4. Copyright](#4-copyright) + + +## 1. Summary + +This Meta BEP lists the BEPs formally Scheduled for Inclusion in the Pasteur network upgrade. + +## 2. Specification + +The Pasteur network upgrade comprises a total of 4 BSC only BEPs. + +### BEPs Scheduled for Inclusion + +#### BEPs need hard fork + +* [BEP-682](./BEP-682.md) : Reject Duplicate Validators in CometBFT Light Block Validation +* [BEP-695](./BEP-695.md) : Staking and Governance Security Hardening +* [BEP-696](./BEP-696.md) : Repurpose Unused Block Header Fields for Metadata + +#### BEPs without hard fork +* [BEP-675](./BEP-675.md) : Builder-Proposed Block with Validator Blind Signing + +## 3. Security Considerations + +None. + +## 4. Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP-675.md b/BEPs/BEP-675.md new file mode 100644 index 00000000..01f85377 --- /dev/null +++ b/BEPs/BEP-675.md @@ -0,0 +1,177 @@ +``` + BEP: 675 + Title: Builder-Proposed Block with Validator Blind Signing + Status: Draft + Type: Standards + Created: 2026-04-10 + Description: Remove validator-side transaction simulation in MEV by introducing BidBlock, enabling higher gas limits. +``` + +# BEP-675: Builder-Proposed Block with Validator Blind Signing + +- [BEP-675: Builder-Proposed Block with Validator Blind Signing](#bep-675-builder-proposed-block-with-validator-blind-signing) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [4.1 Builder](#41-builder) + - [4.2 MEV-Sentry](#42-mev-sentry) + - [4.3 Validator](#43-validator) + - [4.4 Economic Model](#44-economic-model) + - [5. Backward Compatibility](#5-backward-compatibility) + - [6. Security](#6-security) + - [7. Performance Analysis](#7-performance-analysis) + - [8. License](#8-license) + +## 1. Summary + +On BSC, the overwhelming majority of blocks are produced from builder bids (the MEV path) rather than purely local validator assembly. Under the existing flow, the validator **simulates the winning bid** before sealing — duplicating execution the builder already performed. This BEP eliminates that validator-side simulation, shortens the builder pipeline critical path, and raises the achievable gas limit and overall throughput ceiling. + +## 2. Abstract + +Under the existing MEV mechanism, the critical path within a single block interval is: + +**Import parent block → Builder constructs bid → Validator simulates bid → Block produced** + +Validator-side bid simulation repeats execution the builder already performed, compressing the effective block-building window and limiting throughput. This BEP removes that redundancy: builders submit **BidBlocks** containing full execution results (stateRoot, receiptHash, etc.), and the validator assembles and seals the block **without re-executing** user transactions. + +| Dimension | Current (`SendBid`) | Proposed (`SendBidBlock`) | +|-----------|---------------------|---------------------------| +| **Builder output** | Bid as a transaction list (plus declared reward); validator must replay to obtain execution results | **BidBlock**: signed user txs, block header (execution results + timestamp), unsigned system txs | +| **Validator work before seal** | **Bid simulation:** re-execute all transactions | Sign system txs → compute transaction root → assemble header → seal (**no EVM** on this path) | +| **EVM on the assembly critical path** | Import + builder work + **bid simulation** (three execution passes) | Import + builder work only (**no bid simulation**) | + +## 3. Motivation + +The primary goal of this proposal is to raise the practical gas limit on BSC. Under the legacy path, validator bid simulation must re-execute all transactions in the bid, so its cost scales linearly with `gasLimit`. This creates a fundamental conflict: raising the gas limit leaves less time for builder competition, effectively capping achievable throughput. By removing bid simulation from the validator's critical path, the time previously spent on redundant re-execution is reclaimed, making room for a substantially higher gas limit without compressing the bidding window. + +## 4. Specification + +### 4.1 Builder + +This BEP introduces a new RPC **`SendBidBlock`** that accepts fully-executed blocks from builders. Unlike the legacy `SendBid` — where the validator re-executes all bid transactions before sealing — `SendBidBlock` allows the validator to assemble and seal directly from builder-supplied execution results, with the validator verifying correctness by importing the block locally after broadcast. Both paths coexist for backward compatibility. + +The builder constructs and submits a BidBlock through the following steps: + +1. **Execute user transactions** — run the selected user transactions (MEV bundles, mempool transactions, etc.) against the parent state. The builder must reserve sufficient gas for system transactions; user transactions may only consume up to `GasLimit - reserved`. +2. **Execute system transactions without signing** — run system transactions (fee distribution, slashing, reward distribution, validator set updates, etc.) through the EVM normally, but leave them **unsigned**. Signing does not affect EVM state changes, so the execution results are identical whether the system transactions are signed or not. +3. **Build the block header** — populate a standard `types.Header` with execution-result fields (state root, receipts root, logs bloom, gas used, blob gas used) and the expected block timestamp. The timestamp must match the deterministic value derived from the parent block (i.e. `parent.MilliTimestamp() + BlockInterval` for in-turn validators). Other consensus fields in the header (coinbase, nonce, difficulty, base fee, etc.) are deterministically derived from the parent block and filled by the builder. The gas limit must be derived from the parent gas limit, move toward the target `GasCeil` from the validator's `mev_params`, and remain within the protocol's per-block gas-limit adjustment bound. The `Extra` field may be left as a placeholder because the validator overwrites it during assembly. +4. **Assemble and sign `BidBlockArgs`** — pack the complete header, signed user transactions, unsigned system transactions, and optional blob sidecars into `BidBlockArgs`, then sign. +5. **Submit via `SendBidBlock`** — send the signed BidBlock through MEV-Sentry to the validator. Builders may submit multiple BidBlocks for the same block until the deadline, up to the existing per-builder, per-block submission limit shared between the `SendBid` and `SendBidBlock` paths. + +**`BidBlockArgs` data structure:** + +```go +type BidBlockArgs struct { + BidBlock *BidBlock + Signature hexutil.Bytes +} + +type BidBlock struct { + Header *types.Header + Transactions []hexutil.Bytes + Sidecars BlobSidecars +} +``` + +- **`Signature`** — builder's signature over `rlpHash(BidBlock)`, covering all fields in `BidBlock`. +- **`BidBlock`** — contains the block header with execution results, all transactions (signed user txs followed by unsigned system txs), and optional blob sidecars. `GasFee` is not a wire field: the validator derives it from the value of the trailing `deposit` system transaction and uses it to rank competing BidBlocks. + +The `Header` uses the standard `types.Header`. The builder populates all fields including execution results (state root, receipts root, bloom, gas used, etc.) and consensus fields deterministically derived from the parent block. The `TxHash` and `Extra` fields are exceptions — the validator recomputes `TxHash` after signing system transactions, and overwrites `Extra` with the validator's local extra-data payload, including vote attestation and seal signature, during assembly. + +### 4.2 MEV-Sentry + +Previously, MEV-Sentry participated in bid processing (including generating a dedicated payment transaction for the legacy `SendBid` path). On the `SendBidBlock` path, Sentry is reduced to a **pure bid proxy**: it forwards BidBlock traffic from builders to validators without additional processing. Its primary remaining role is to **conceal the validator's real network address** and protect validator infrastructure. Legacy `SendBid` handling remains for backward compatibility. + +### 4.3 Validator + +Upon receiving BidBlocks, the validator tracks the current best by derived `GasFee`. At the assembly deadline (a short reserved interval before the block timestamp), the validator selects the highest-fee BidBlock and processes it in three stages. The legacy **GreedyMerge** step — post-simulation mempool transaction merging — is not performed on the `SendBidBlock` path. + +**1. Pre-seal header verification** + +Validate the builder-supplied header against locally derived consensus rules: block number, parent hash, coinbase, gas limit, base fee, and difficulty must match deterministic values from the parent block; the header millisecond timestamp must be derived in the same way as the validator. The derived `GasFee` must also be non-zero. Any failure causes immediate rejection. + +**2. Finalize and assemble** + +- Sign system transactions — identify unsigned system transactions at the tail of the `Transactions` list, sign each with the validator's private key, and replace them in the list. The validator signs only transactions targeting `ValidatorContract` whose method is one of `deposit`, `distributeFinalityReward`, or `updateValidatorSetV2`. Any other transaction is rejected before signing. +- Recompute `TxHash` — calculate the Merkle root over the complete transaction list (user transactions + now-signed system transactions). +- Overwrite `Extra` — replace the builder-supplied `Extra` with the validator's local extra-data payload. +- Assemble the block — combine the updated header and the full transaction list. + +**3. Seal** + +- Add vote attestation — aggregate Fast Finality vote attestations into the extra data. +- Add seal signature — append the validator's ECDSA signature over the complete header. +- Broadcast the sealed block. + +After broadcasting, the validator **imports the block locally** — re-executing all transactions and verifying the state root, receipts root, and blob commitments (if any). Revocation conditions are described in [Section 6](#6-security). + +### 4.4 Economic Model + +Under the legacy `SendBid` path, a dedicated on-chain payment transaction transfers fees from the builder to the validator during simulation. The `SendBidBlock` path does not use this payment transaction, as there is no simulation step. + +Validator revenue instead comes solely from transaction gas fees within the block, distributed through the existing fee-distribution system transaction. + +With bid simulation removed, builders gain more time to optimize transaction ordering and value extraction without needing a separate payment mechanism. + +## 5. Backward Compatibility + +No hard fork is required: the change is at the **client implementation** layer and does not alter consensus rules. Externally observable on-chain block validity and execution semantics stay the same; only how the validator **assembles** the block before sealing changes. + +The legacy `SendBid` path and the new `SendBidBlock` path **coexist permanently**. Validators accept bids from both paths simultaneously and select the best among them. `SendBid` serves as both the fallback for builders that have not yet adopted `SendBidBlock` and the safety net when a builder's `SendBidBlock` permission is revoked (see [Section 6](#6-security)). + +## 6. Security + +The `SendBidBlock` path is an **enhancement to the existing `SendBid` path**, not a replacement. Without simulation, the validator cannot fully verify block validity before sealing. Instead of rejecting builders outright when issues arise, the validator **downgrades** them back to the legacy `SendBid` path (which has full simulation protection). This limits the validator's exposure: each builder can cause at most **one bad BidBlock per 24-hour revoke window** before being downgraded to the simulation-protected legacy path. + +Each validator independently maintains a **per-builder permission** for `SendBidBlock`, operating as follows: + +1. **Default state** — all registered builders have `SendBidBlock` permission. +2. **Detection** — after sealing and broadcasting a BidBlock, the validator imports the block locally. Revocation is triggered if: + 1) `InsertChain` fails, such as due to a state root or receipts root mismatch. + 2) The import succeeds, but the BidBlock's average gas price, excluding system transactions, is below the validator's configured minimum gas price. +3. **Permission revocation** — an `InsertChain` failure revokes the flagged builder for 24 hours; a low average gas price revokes it for one epoch. Subsequent `SendBidBlock` requests are rejected while the corresponding revoke is active. The builder falls back to `SendBid`, which is protected by validator-side simulation. +4. **Rolling reset** — permission is restored after the builder-specific revoke window expires. There is no UTC daily reset. + +The validator exposes an RPC endpoint for builders to query their current permission status, including the reason for any revocation. Builders poll this endpoint periodically (e.g. every 10 seconds) and switch between `SendBidBlock` and `SendBid` accordingly. + +**Builder polling flow:** + +``` +┌──────────────────────────────────────────────────────────────┐ +│ Every 10s: GET /eth/v1/builder/permission │ +│ ┌────────────────────────────────────────────────────────┐ │ +│ │ Response: │ │ +│ │ { allowed: true/false, error: "...", resetAt: "..." } │ │ +│ └────────────────────────────────────────────────────────┘ │ +│ │ │ │ +│ allowed=true allowed=false │ +│ │ │ │ +│ ▼ ▼ │ +│ ┌─────────────┐ ┌─────────────┐ │ +│ │ SendBidBlock │ │ SendBid │ │ +│ │ (new path) │ │ (legacy path)│ │ +│ └─────────────┘ └─────────────┘ │ +│ │ +│ revokedAt + 24h → allowed restored to true │ +└──────────────────────────────────────────────────────────────┘ +``` + +**Worst-case impact:** with N registered builders all producing bad BidBlocks, the validator suffers at most N missed blocks in a 24-hour revoke window (one per builder), after which all builders are downgraded to the simulation-protected `SendBid` path until their individual revoke windows expire. + +**Cost of misbehavior.** A downgraded builder loses the performance advantages of `SendBidBlock` (wider competition window, higher gas limit) for 24 hours, reducing its competitiveness against builders that retain `SendBidBlock` access. + +## 7. Performance Analysis + +Eliminating the validator-side simulation removes one full EVM execution pass from the block-production critical path. Let `G` denote the gas limit in Mgas and `R` the EVM throughput; one pass over `G` takes `G/R` time. The fixed overhead covers network transport, header verification, and state-root computation: + +- **Legacy path** — 3 EVM passes on the critical path (parent import + builder execution + validator simulation): + `3·(G/R) + overhead_legacy = block_interval` +- **Proposed path** — 2 EVM passes (parent import + builder execution): + `2·(G/R) + overhead_proposed = block_interval` + +Solving for `G` yields approximately 50% higher gas-limit ceiling under typical network conditions. Equivalently, the interval during which builders execute and pack transactions extends from approximately 30% of the block interval to approximately 45% — a 50% relative increase — expanding the time available for transaction ordering and MEV optimization. + +## 8. License + +This document is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-677.md b/BEPs/BEP-677.md new file mode 100644 index 00000000..77238aca --- /dev/null +++ b/BEPs/BEP-677.md @@ -0,0 +1,324 @@ +
+  BEP: 677
+  Title: Implement EIP-8056 Scaled UI Amount
+  Status: Draft
+  Type: Standards
+  Created: 2026-04-14
+  Description: Adds an updatable UI multiplier extension for BEP-20 tokens on BSC
+
+ +# BEP-677: Implement EIP-8056 Scaled UI Amount + +- [BEP-677: Implement EIP-8056 Scaled UI Amount](#bep-677-implement-eip-8056-scaled-ui-amount) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [4.1 Core Interface — IScaledUIAmount](#41-core-interface--iscaleduiamount) + - [4.2 Required Extension — IScaledUIAmountNewUIMultiplier](#42-required-extension--iscaleduiamountnewuimultiplier) + - [4.3 Optional Extension — IScaledUIAmountConversion](#43-optional-extension--iscaleduiamountconversion) + - [4.4 Optional Extension — IScaledUIAmountBalances](#44-optional-extension--iscaleduiamountbalances) + - [4.5 BSC Extension — IERC8056Scheduled](#45-bsc-extension--ierc8056scheduled) + - [4.6 ERC-165 Interface IDs](#46-erc-165-interface-ids) + - [4.7 Reference Implementation](#47-reference-implementation) + - [5. Rationale](#5-rationale) + - [6. Backwards Compatibility](#6-backwards-compatibility) + - [7. Security Considerations](#7-security-considerations) + - [7.1 Multiplier Threshold Bounds](#71-multiplier-threshold-bounds) + - [7.2 Pending Change Overwrites](#72-pending-change-overwrites) + - [7.3 Access Control and Centralization](#73-access-control-and-centralization) + - [7.4 Reentrancy in Hooks](#74-reentrancy-in-hooks) + - [7.5 Arithmetic Overflow and Precision Loss](#75-arithmetic-overflow-and-precision-loss) + - [8. License](#8-license) + +## 1. Summary + +This BEP introduces the [EIP-8056](https://eips.ethereum.org/EIPS/eip-8056) Scaled UI Amount extension for BEP-20 tokens on BNB Smart Chain (BSC), and adds a BSC-specific scheduling extension on top of the EIP standard. + +## 2. Abstract + +EIP-8056 defines a standard interface for ERC-20 tokens to expose an updatable UI multiplier. This BEP adopts the interfaces and semantics of EIP-8056 for BEP-20 tokens on BNB Smart Chain (BSC). Unless explicitly stated otherwise, EIP-8056 remains the upstream source of truth for interface definitions, while BEP-677 defines only local adoption, integration guidance, and BSC-specific extensions. + +Wallets, indexers, and frontends use the UI multiplier to display scaled token balances — without minting or burning tokens on-chain. The raw balances stored in the contract remain unchanged; only the human-readable representation is affected. + +This BEP additionally introduces one BSC-specific extension, `IERC8056Scheduled`, which provides richer query semantics for scheduled multiplier changes that have not yet taken effect. + +**Source of requirements:** + +| Requirement | Source | +|-------------|--------| +| `IScaledUIAmount` (§4.1) | Upstream EIP-8056 | +| `IScaledUIAmountNewUIMultiplier` (§4.2) | Upstream EIP-8056 | +| `IScaledUIAmountConversion` (§4.3) | Upstream EIP-8056 | +| `IScaledUIAmountBalances` (§4.4) | Upstream EIP-8056 | +| `IERC8056Scheduled` (§4.5) | BSC extension — **not part of EIP-8056** | + +## 3. Motivation + +Several token categories in the BNB Chain ecosystem require display-layer balance adjustments that do not correspond to actual token issuance or destruction: + +- **Real-world assets (RWA)**: Prices and units of tokenized assets (equities, commodities, bonds) may need periodic redenomination. Updating the UI multiplier achieves this without any on-chain token movement. +- **Stock splits and reverse splits**: Token issuers may wish to adjust the displayed price per token — analogous to a stock split — while keeping the underlying on-chain supply constant. +- **Interest-bearing tokens**: Some protocols track accrued interest off-chain and reflect it through a growing multiplier, rather than rebasing the supply. + +Currently there is no standardized mechanism for wallets and explorers to discover and apply such multipliers. Without a shared interface, each project implements its own display logic, leading to fragmented tooling support and poor user experience. EIP-8056 solves this by providing a discoverable, ERC-165-compliant interface. + +The BSC ecosystem additionally benefits from a scheduled-change extension that allows integrators to query pending multiplier changes before they take effect, enabling proactive UI updates and reducing confusion during transitions. + +## 4. Specification + +### 4.1 Core Interface — IScaledUIAmount + +The core interface MUST be implemented by any EIP-8056-compliant token. The ERC-165 interface ID is `0xa60bf13d`. + +```solidity +interface IScaledUIAmount { + /// @dev Emitted when the UI multiplier is updated. + /// @param oldMultiplier The previous multiplier value + /// @param newMultiplier The new multiplier value scheduled to take effect + /// @param effectiveAtTimestamp The timestamp when the new multiplier becomes active + event UIMultiplierUpdated( + uint256 oldMultiplier, + uint256 newMultiplier, + uint256 effectiveAtTimestamp + ); + + /// @dev REQUIRED. Emitted during a token transfer with the UI-adjusted amount. + /// MUST be emitted alongside every BEP-20 `Transfer` event. + /// @param from Sender address (zero address for mints) + /// @param to Recipient address (zero address for burns) + /// @param amount Raw token amount transferred + /// @param uiAmount UI-adjusted amount at the time of transfer + event TransferWithUIAmount( + address indexed from, + address indexed to, + uint256 amount, + uint256 uiAmount + ); + + /// @dev Returns the current UI multiplier. + /// Multiplier is represented with 18 decimals: 1e18 = 1.0x. + function uiMultiplier() external view returns (uint256); +} +``` + +**Multiplier precision**: The multiplier uses 18 decimal places. A value of `1e18` represents a 1.0× multiplier (no scaling). A value of `2e18` represents a 2.0× multiplier (as in a 2-for-1 stock split). The UI amount is computed as: + +``` +uiAmount = rawAmount × uiMultiplier / 1e18 +``` + +**`UIMultiplierUpdated` event**: Emitted whenever the multiplier is scheduled to change. The event MUST include the old multiplier (the currently active value at the time of scheduling), the new multiplier, and the timestamp at which the new multiplier becomes active. + +**`TransferWithUIAmount` event**: REQUIRED. This event MUST be emitted alongside every BEP-20 `Transfer` event, providing the UI-adjusted amount computed at the time of the transfer. This allows indexers to record the human-readable transfer value without a separate multiplier lookup. + +### 4.2 Required Extension — IScaledUIAmountNewUIMultiplier + +Compliant tokens MUST implement this extension to expose the pending (scheduled but not yet active) multiplier. The ERC-165 interface ID is `0x4bd27648`. + +```solidity +interface IScaledUIAmountNewUIMultiplier { + /// @dev Returns the pending UI multiplier scheduled to take effect at effectiveAt(). + /// Multiplier is represented with 18 decimals: 1e18 = 1.0x. + /// Note: Always returns the stored next multiplier value, even after it has + /// become active. + /// When no pending change exists, MUST return the same value as uiMultiplier(). + function newUIMultiplier() external view returns (uint256); + + /// @dev Returns the timestamp at which the pending multiplier becomes effective. + /// When no pending change exists, MUST return 0. + function effectiveAt() external view returns (uint256); +} +``` + +**Return values when no pending change exists**: When no multiplier change has been scheduled, or when the last scheduled change has already taken effect with no new change pending, `newUIMultiplier()` MUST return the same value as `uiMultiplier()`, and `effectiveAt()` MUST return `0`. Integrators can determine whether a genuine pending change exists by checking `effectiveAt() > block.timestamp`. + +Integrators SHOULD use `uiMultiplier()` (§4.1) to obtain the currently active value, and `newUIMultiplier()` + `effectiveAt()` together to discover what the next scheduled value will be and when it takes effect. + +### 4.3 Optional Extension — IScaledUIAmountConversion + +Tokens MAY implement this extension to provide on-chain helpers for converting between raw amounts and their UI representations. The ERC-165 interface ID is `0x57854fc3`. + +```solidity +interface IScaledUIAmountConversion { + /// @dev Converts a raw token amount to its UI representation. + function toUIAmount(uint256 rawAmount) external view returns (uint256); + + /// @dev Converts a UI amount back to its raw token amount. + function fromUIAmount(uint256 uiAmount) external view returns (uint256); +} +``` + +### 4.4 Optional Extension — IScaledUIAmountBalances + +Tokens MAY implement this extension to expose UI-adjusted balance and total supply queries directly on-chain. The ERC-165 interface ID is `0xd890fd71`. + +```solidity +interface IScaledUIAmountBalances { + /// @dev Returns the UI-adjusted balance of an account. + function balanceOfUI(address account) external view returns (uint256); + + /// @dev Returns the UI-adjusted total supply. + function totalSupplyUI() external view returns (uint256); +} +``` + +### 4.5 BSC Extension — IERC8056Scheduled + +> **Note:** This extension is a BSC-specific addition and is **not part of the EIP-8056 specification**. Implementations on other chains may not support it. + +This extension provides richer semantics for querying pending multiplier changes. Specifically, it returns pending change information as a tuple (multiplier + effectiveAt together) and exposes a boolean guard to distinguish "has a pending change" from "reading stale stored state". The ERC-165 interface ID is `0xeb0093dd`. + +```solidity +interface IERC8056Scheduled { + /// @dev Emitted when a pending multiplier change is overwritten before taking effect. + /// @param overwrittenMultiplier The multiplier value that was scheduled but overwritten + /// @param overwrittenEffectiveAt The timestamp when the overwritten multiplier was supposed to take effect + /// @param newMultiplier The new multiplier value that replaced it + /// @param newEffectiveAt The timestamp when the new multiplier will take effect + event UIMultiplierChangeOverwritten( + uint256 overwrittenMultiplier, + uint256 overwrittenEffectiveAt, + uint256 newMultiplier, + uint256 newEffectiveAt + ); + + /// @dev Returns the pending multiplier and its effective timestamp as a tuple. + /// Use hasPendingMultiplier() to check if a change is actually pending. + /// When hasPendingMultiplier() == false, MUST return (0, 0). + /// @return multiplier The scheduled next multiplier value + /// @return effectiveAt The timestamp when the multiplier becomes active + function pendingMultiplier() external view returns (uint256 multiplier, uint256 effectiveAt); + + /// @dev Returns true if there is a pending multiplier change that has not yet taken effect. + function hasPendingMultiplier() external view returns (bool); +} +``` + +**Return values when no pending change exists**: When `hasPendingMultiplier()` returns `false`, `pendingMultiplier()` MUST return `(0, 0)`. Because a scheduled change requires `effectiveAtTimestamp > block.timestamp` (see §4.2), no genuine pending state has `effectiveAt == 0`, so the `(0, 0)` tuple unambiguously signals "no pending change". Clients MAY check `pendingMultiplier()` directly against `(0, 0)`, or call `hasPendingMultiplier()` for an explicit boolean check. + +**Motivation for this extension**: The EIP-8056 standard's `newUIMultiplier()` always returns the stored "next" value, even after that value has already become active. This makes it ambiguous whether a change is genuinely pending. `hasPendingMultiplier()` resolves this ambiguity directly. Additionally, `UIMultiplierChangeOverwritten` provides an on-chain audit trail when a scheduled change is replaced before it takes effect — important for governance scenarios and multi-sig controlled tokens. + +### 4.6 ERC-165 Interface IDs + +| Interface | ID | Status | +|-----------|-----|--------| +| `IScaledUIAmount` | `0xa60bf13d` | EIP-8056 core — MUST implement | +| `IScaledUIAmountNewUIMultiplier` | `0x4bd27648` | EIP-8056 required extension — MUST implement | +| `IScaledUIAmountConversion` | `0x57854fc3` | EIP-8056 optional extension | +| `IScaledUIAmountBalances` | `0xd890fd71` | EIP-8056 optional extension | +| `IERC8056Scheduled` | `0xeb0093dd` | BSC extension — not part of EIP-8056 | + +Wallets and integrators MUST use `ERC165.supportsInterface()` to check which extensions a token implements before calling extension-specific functions. + +### 4.7 Reference Implementation + +A reference implementation is available at [bnb-chain/bep-677-contracts](https://github.com/bnb-chain/bep-677-contracts). It includes: + +- `ERC8056BaseUpgradeable` — abstract Beacon-upgradeable base implementing all five interfaces above (recommended for new deployments; inherit and implement `_authorizeMultiplierUpdate`) +- `ERC8056TokenUpgradeable` — concrete Beacon-deployable BEP-20 token using `OwnableUpgradeable` for access control (deploy directly via the OpenZeppelin Upgrades plugin) + +The reference implementation uses OpenZeppelin Contracts v5 (including upgradeable counterparts) and Solidity `^0.8.24`. During initialization, the implementation emits `UIMultiplierUpdated(0, 1e18, block.timestamp)` to provide a deterministic single-event-stream anchor for off-chain indexers. The value `oldMultiplier == 0` serves as an initialization sentinel; the runtime invariant `uiMultiplier > 0` guarantees this value cannot appear in any post-init emission. The `toUIAmount` and `fromUIAmount` calculations use `Math.mulDiv` for overflow-safe 512-bit arithmetic. The implementation rounds toward zero (integer division truncation); as a result, `fromUIAmount(toUIAmount(x)) <= x` — round-trip conversion is not lossless. Integrators MUST NOT assume round-trip symmetry or use these functions for internal accounting; raw on-chain amounts are the canonical source of truth. + +When an extreme multiplier causes `rawAmount × uiMultiplier` to overflow `uint256`, the internal `_update` path uses `Math.tryMul` to detect the overflow and emits `TransferWithUIAmount(..., uiAmount = 0)` as a sentinel rather than reverting, preserving ERC-20 backwards compatibility. View helpers `balanceOfUI` and `totalSupplyUI` deliberately revert in that regime to avoid misleading frontends with a false zero balance. + +## 5. Rationale + +**Layered interface design**: EIP-8056 separates the core getter (`uiMultiplier`), the pending-state extension, and the optional on-chain helpers into distinct interfaces, each with its own ERC-165 ID. This allows wallets to detect only what a token actually supports, rather than requiring all tokens to implement every helper. Tokens targeting minimal compliance only need to implement §4.1 and §4.2. + +**Multiplier precision at 18 decimals**: Using `1e18` as the 1.0× baseline aligns with the conventions of ETH and most BEP-20 token decimals. It allows sub-1× multipliers (e.g., a 0.5× reverse split is `5e17`) to be expressed with reasonable precision without overflowing a `uint256`. + +**Future-only scheduling**: The `effectiveAtTimestamp` parameter is required to be strictly in the future (`> block.timestamp`). This gives wallets and indexers a window to fetch the pending change and update their display logic before it activates, avoiding an abrupt display change that surprises users. However, this notice window is advisory: a subsequent `setUIMultiplier` call MAY overwrite the pending change with an earlier `effectiveAtTimestamp`, potentially shortening the lead time to as little as the next block. Integrators that depend on a guaranteed lead time MUST treat the originally announced `effectiveAtTimestamp` as a hint, not a contract, and react to `UIMultiplierChangeOverwritten` events (§4.5). + +**BSC `IERC8056Scheduled` extension**: The two-return-value `pendingMultiplier()` function is more convenient for frontends than calling `newUIMultiplier()` and `effectiveAt()` separately with two RPC calls. The `UIMultiplierChangeOverwritten` event is essential for governance contexts where a pending change may be superseded — integrators listening to `UIMultiplierUpdated` alone would not detect that an earlier scheduled change was discarded. + +**How the multiplier is updated is left to the implementer**: EIP-8056 intentionally does not specify an interface for _setting_ the multiplier. This preserves flexibility: some tokens may use a simple `Ownable` owner, others a multisig, a DAO vote, or an oracle. The reference implementation exposes `setUIMultiplier(uint256 newMultiplier, uint256 effectiveAtTimestamp)` as a public function with `_authorizeMultiplierUpdate()` for access control, but this is not a standardized interface. + +## 6. Backwards Compatibility + +This BEP introduces a new optional BEP-20 extension. Existing BEP-20 tokens that do not implement `IScaledUIAmount` are unaffected. Wallets and indexers that are not aware of EIP-8056 will continue to display raw balances, which is the existing behavior. + +No changes are made to the EVM, BSC consensus, or the BEP-20 token standard. This BEP does not require a hard fork. + +**Raw ERC-20 operations must remain functional**: An EIP-8056 implementation MUST guarantee that standard BEP-20 functions (`transfer`, `transferFrom`, `mint`, `burn`) continue to operate on raw amounts regardless of the current multiplier value. In particular, emitting `TransferWithUIAmount` MUST NOT cause the underlying transfer to revert. If an extreme multiplier makes the UI-adjusted amount unrepresentable (i.e., `rawAmount × uiMultiplier` overflows `uint256`), the implementation SHOULD emit a sentinel value (such as `uiAmount = 0` while `amount != 0`) rather than reverting. See §4.7 for how the reference implementation handles this case. + +## 7. Security Considerations + +### 7.1 Multiplier Threshold Bounds + +The `uiMultiplier()` value is used in multiplication: `uiAmount = rawAmount × uiMultiplier / 1e18`. While `Math.mulDiv` handles intermediate overflow safely via 512-bit arithmetic, extreme multiplier values still pose result-range and business-logic risks: + +- **Extremely high multipliers** (e.g., `> 1e30`): The computed `uiAmount` may exceed meaningful numeric ranges, producing values that are misleading or unusable for display purposes. For very large raw balances combined with very large multipliers, the final result may also exceed `uint256` capacity. +- **Extremely low multipliers** (e.g., `< 1e12`): For small raw balances, integer division truncation will round `uiAmount` down to zero, making balances appear empty to users. + +Token issuers SHOULD override the multiplier validation hook to enforce reasonable bounds for their use case. Example ranges: + +| Use case | Suggested min | Suggested max | +|----------|--------------|--------------| +| Stock splits | `1e17` (0.1×) | `1e20` (100×) | +| RWA redenomination | `1e15` (0.001×) | `1e21` (1000×) | + +### 7.2 Pending Change Overwrites + +By default, a scheduled multiplier change can be overwritten by a new `setUIMultiplier` call before it takes effect. This can cause: + +- **User confusion**: Users who observed the `UIMultiplierUpdated` event and made financial plans based on the announced change may be surprised by a different multiplier becoming active. +- **Governance issues**: In DAO or multi-sig controlled tokens, separate proposals may inadvertently overwrite each other. The final on-chain state may not correspond to any approved proposal. + +The `UIMultiplierChangeOverwritten` event (§4.5) provides an audit trail when overwrites occur. For strict governance requirements, implementers SHOULD override the `_beforeMultiplierUpdate` hook to revert when a pending change already exists: + +```solidity +function _beforeMultiplierUpdate(uint256, uint256) internal view override { + require(!hasPendingMultiplier(), "ERC8056: pending change exists"); +} +``` + +**Pending change acceleration**: The new `effectiveAtTimestamp` is only constrained to be in the future (`> block.timestamp`). An overwrite MAY shorten the previously announced effective time to as little as the next block. Integrators MUST NOT rely on the originally announced `effectiveAt` for risk-management timing windows; they MUST monitor `UIMultiplierChangeOverwritten` events and react accordingly. For implementations that need to guarantee a minimum notice window, override `_beforeMultiplierUpdate` to reject acceleration: + +```solidity +function _beforeMultiplierUpdate(uint256, uint256 effectiveAtTimestamp) internal view override { + if (hasPendingMultiplier()) { + require(effectiveAtTimestamp >= effectiveAt(), "ERC8056: cannot accelerate pending change"); + } +} +``` + +Choose this override only if your governance model excludes legitimate emergency corrections; the default behavior preserves operational flexibility while the `UIMultiplierChangeOverwritten` audit trail ensures transparency. + +### 7.3 Access Control and Centralization + +The ability to change `uiMultiplier` is a privileged operation. If a single EOA (externally owned account) controls this function: + +- It can arbitrarily scale up displayed balances, which may mislead users into believing their holdings are worth more. +- It can scale down displayed balances, potentially causing wallets to show zero balances for small holders. + +For production deployments, token issuers SHOULD: + +- Use a multisig wallet or governance contract as the authorized updater. +- Implement a timelock between scheduling and activation (the `effectiveAtTimestamp` mechanism already provides this if set sufficiently far in the future). +- Clearly document centralization assumptions for users and auditors. + +### 7.4 Reentrancy in Hooks + +The `_beforeMultiplierUpdate` hook is called before state variables are updated. If a token overrides this hook with logic that performs external calls, a reentrancy attack could call `setUIMultiplier` again before the state is committed. Implementers MUST apply reentrancy protection (e.g., OpenZeppelin `ReentrancyGuard`) if their hook makes external calls. + +### 7.5 Arithmetic Overflow and Precision Loss + +`toUIAmount` computes `rawAmount × uiMultiplier / 1e18`. The reference implementation uses `Math.mulDiv` from OpenZeppelin, which performs a 512-bit intermediate multiplication to prevent overflow in the intermediate product. Implementers that reimplement this function MUST use equivalent overflow-safe arithmetic. Plain `rawAmount * uiMultiplier / 1e18` in Solidity 0.8.x will revert on overflow for large intermediate products. Note that `mulDiv` improves overflow safety and arithmetic correctness of the multiply-then-divide operation, but does not eliminate integer-division truncation — rounding loss is inherent to integer arithmetic. For use cases where precision is critical, implementers SHOULD consider the rounding mode (`mulDiv` rounds down by default; OpenZeppelin also provides a `Rounding.Ceil` variant). + +Integrators that reuse `toUIAmount` / `fromUIAmount` for internal accounting will accumulate truncation error across multiple round-trips — `fromUIAmount(toUIAmount(x))` is not guaranteed to equal `x`. Raw on-chain amounts MUST remain the canonical source of truth; these conversion helpers should be called only at the display boundary. + +### 7.6 Storage Layout and Upgrade-Collision Risk + +The reference `ERC8056BaseUpgradeable` reserves a storage gap (`uint256[47] __gap`) immediately after its three multiplier slots, allowing the abstract base to be extended in future releases without colliding with state declared in inheriting contracts. Contracts that inherit `ERC8056BaseUpgradeable` adopt this layout transitively, and therefore inherit the responsibility to preserve layout compatibility across upgrades. Inheritors: + +- MUST NOT reorder, remove, or change the type of inherited state variables across upgrades. State declared in the abstract base is part of the storage contract. +- MUST validate every candidate implementation against the currently deployed one before submitting an upgrade transaction. The reference implementation ships an automated check using `@openzeppelin/hardhat-upgrades`'s `validateUpgrade` (see §4.7); equivalent tooling exists for other frameworks (Foundry, Truffle). +- SHOULD re-run layout validation whenever the upstream `ERC8056BaseUpgradeable` releases a new version that consumes slots from the reserved gap, because the post-gap layout of the inheriting contract shifts accordingly. +- When adding their own state, MUST place new fields after the inherited base layout. Solidity inheritance ordering does this automatically for declarations in the inheriting contract; the requirement is to never edit the abstract base directly to insert fields. + +Implementations that adopt an alternative storage strategy (e.g., ERC-7201 namespaced storage) should follow the corresponding tooling and conventions for that pattern; the underlying safety requirement — preserve layout compatibility across upgrades — is identical. + +## 8. License + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-682.md b/BEPs/BEP-682.md new file mode 100644 index 00000000..218d6fbd --- /dev/null +++ b/BEPs/BEP-682.md @@ -0,0 +1,76 @@ +
+  BEP: 682
+  Title: Reject Duplicate Validators in CometBFT Light Block Validation
+  Status: Draft
+  Type: Standards
+  Created: 2026-04-22
+
+ +# BEP-682: Reject Duplicate Validators in CometBFT Light Block Validation + +- [BEP-682: Reject Duplicate Validators in CometBFT Light Block Validation](#bep-682-reject-duplicate-validators-in-cometbft-light-block-validation) + - [1. Summary](#1-summary) + - [2. Abstract](#2-abstract) + - [3. Motivation](#3-motivation) + - [4. Specification](#4-specification) + - [5. Backward Compatibility](#5-backward-compatibility) + - [6. Security Considerations](#6-security-considerations) + - [7. License](#7-license) + +## 1. Summary + +This BEP extends the CometBFT light block validation precompile ([BEP-221](./BEP221.md), address `0x67`) to reject duplicate validators, preventing malformed validator sets from bypassing bridge verification assumptions. + +## 2. Abstract + +[BEP-221](./BEP221.md) introduced the `0x67` precompile for cross-chain light block verification between BSC and CometBFT-compatible blockchains. The precompile decodes validator sets but does not enforce uniqueness. This BEP adds a new variant that checks validator address, consensus public key, BLS public key, and relayer address for duplicates within each validator set, and rejects the input if any are found. + +## 3. Motivation + +The bridge verification logic assumes each validator in a set is unique, but the `0x67` precompile does not enforce this. A crafted input with duplicate validators could: + +- Inflate voting power and bypass signing thresholds — a duplicated validator counts multiple times, and one signature satisfies multiple index slots, allowing a minority to forge a supermajority. +- Cause ambiguous bridge identity attribution via duplicate relayer addresses or BLS keys. + +## 4. Specification + +### 4.1 Uniqueness Rules + +After this BEP is enabled, the precompile checks the following fields for uniqueness across every validator within each validator set: + +| Field | Requirement | +|-------|-------------| +| Validator address (20 bytes) | Must be unique | +| Consensus public key (32 bytes) | Must be unique | +| BLS public key (48 bytes) | Must be unique among non-zero values | +| Relayer address (20 bytes) | Must be unique among non-zero values | + +In the consensus state encoding (BEP-221), validator address is derived from pubkey via `tmhash(pubkey)[:20]` rather than stored explicitly. In the light block's protobuf encoding, it is an explicit field. + +BLS keys and relayer addresses may be unset (all-zero or empty) for validators that have not registered bridge identity on-chain — we can just pad zero bytes as described in BEP-221. Unset values are excluded from the uniqueness check, so multiple validators may have zero-filled optional fields without error. + +### 4.2 Validation Scope + +The uniqueness check is applied to both validator sets in the precompile input: + +1. The validator set in the **trusted consensus state** (fixed-width binary encoding, BEP-221 §3.1) +2. The validator set in the **incoming light block** (CometBFT protobuf encoding, BEP-221 §3.2) + +Both checks run before any light client verification logic. Cross-set duplicates are not flagged, as validators may appear in both sets during normal rotation. + +When a duplicate is detected, the precompile returns an error. Only the precompile's fixed gas cost is consumed; remaining gas is returned to the caller: +``` +duplicate validator # and #: +``` + +## 5. Backward Compatibility + +This is a breaking change. After activation, `0x67` rejects inputs with duplicate validators that were previously accepted. In practice, legitimate validator sets never contain duplicates — only maliciously crafted inputs are affected. + +## 6. Security Considerations + +No new security surface area is introduced. This BEP strictly narrows the accepted input range of an existing precompile. + +## 7. License + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP-695.md b/BEPs/BEP-695.md new file mode 100644 index 00000000..dc4da045 --- /dev/null +++ b/BEPs/BEP-695.md @@ -0,0 +1,53 @@ +
+  BEP: 695
+  Title: Staking and Governance Security Hardening
+  Status: Draft
+  Type: Standards
+  Created: 2026-06-09
+
+ +# BEP-695: Staking and Governance Security Hardening + +- [BEP-695: Staking and Governance Security Hardening](#bep-695-staking-and-governance-security-hardening) + - [1. Summary](#1-summary) + - [2. Motivation](#2-motivation) + - [3. Specification](#3-specification) + - [3.1 Revoke Validator-Admin Authority from Rotated Consensus Keys](#31-revoke-validator-admin-authority-from-rotated-consensus-keys) + - [3.2 Propagate Slash Eviction After Consensus Key Rotation](#32-propagate-slash-eviction-after-consensus-key-rotation) + - [3.3 Reject Blacklisted Voters on Signature-Based Governance Votes](#33-reject-blacklisted-voters-on-signature-based-governance-votes) + - [4. Backward Compatibility](#4-backward-compatibility) + - [5. License](#5-license) + +## 1. Summary + +This BEP bundles three security-hardening measures for the BSC system contracts: two tighten authorization and slash-eviction handling around validator consensus key rotation (`StakeHub` and `BSCValidatorSet`), and one strengthens blacklist enforcement on signature-based governance voting (`BSCGovernor`). + +## 2. Motivation + +Each measure closes a gap where stale state or an incomplete check led to an unsafe outcome: + +1. A rotated (old) consensus address could still authorize validator-admin actions. +2. Slashing a validator that had rotated its consensus key did not promptly remove it from the active mining set. +3. Blacklist enforcement on governance voting did not cover the signature-based voting paths. + +## 3. Specification + +### 3.1 Revoke Validator-Admin Authority from Rotated Consensus Keys + +`StakeHub` resolves a validator operator from the calling consensus address when authorizing validator-admin actions. This resolution now additionally requires the calling address to be the validator's current (non-expired) consensus key. The post-rotation (old) consensus address is intentionally retained in the mapping for slash and reward resolution, but it no longer resolves to the operator for admin actions. + +### 3.2 Propagate Slash Eviction After Consensus Key Rotation + +`StakeHub.doubleSignSlash` and `StakeHub.maliciousVoteSlash` now call `BSCValidatorSet.felony` with the validator's current consensus key, immediately after jailing. `BSCValidatorSet.felony` is specified as idempotent: invoking it with an address that is not in the active validator set (`currentValidatorSetMap`) returns without any state change. The existing `SlashIndicator`-driven eviction, which uses the pre-rotation consensus key, is retained. The two evictions are complementary and together remove the validator from the active set whether or not `BSCValidatorSet` has synced the rotated key. + +### 3.3 Reject Blacklisted Voters on Signature-Based Governance Votes + +`BSCGovernor`'s blacklist check previously applied only to the transaction sender. `BSCGovernor._castVote` now additionally reverts with `InBlackList` when the recovered voter `account` is blacklisted. This extends blacklist enforcement to the signature-based voting paths (`castVoteBySig` and `castVoteWithReasonAndParamsBySig`), where the sender is a relayer distinct from the voter. Direct voting, where the sender and voter are the same account, is unchanged. + +## 4. Backward Compatibility + +All three changes will be activated in the upcoming Pasteur hardfork. They only tighten enforcement and do not change any ABI, storage layout, or cross-chain message format, so compliant flows are expected to continue working unchanged. + +## 5. License + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP-696.md b/BEPs/BEP-696.md new file mode 100644 index 00000000..7a304153 --- /dev/null +++ b/BEPs/BEP-696.md @@ -0,0 +1,78 @@ +
+  BEP: 696
+  Title: Repurpose Unused Block Header Fields for Metadata
+  Status: Draft
+  Type: Standards
+  Created: 2026-06-11
+  Description: Allow BSC block producers to use currently unused header fields for producer metadata.
+
+ +# BEP-696: Repurpose Unused Block Header Fields for Metadata + +- [BEP-696: Repurpose Unused Block Header Fields for Metadata](#bep-696-repurpose-unused-block-header-fields-for-metadata) + - [1. Summary](#1-summary) + - [2. Motivation](#2-motivation) + - [3. Specification](#3-specification) + - [3.1 Current Behavior](#31-current-behavior) + - [3.2 Header Field Usage and Metadata Encoding](#32-header-field-usage-and-metadata-encoding) + - [3.3 Block Validity](#33-block-validity) + - [4. Backward Compatibility](#4-backward-compatibility) + - [5. License](#5-license) + +## 1. Summary + +This BEP repurposes two BSC block header fields that carry no information today, `UncleHash` and `ParentBeaconRoot`, as general-purpose metadata fields. Once this BEP is activated, block producers may write metadata, such as software or block-production pipeline version information, into these fields instead of keeping them pinned to constant values. + +## 2. Motivation + +Two 32-byte header fields are inherited from the Ethereum header format but carry no information on BSC: + +1. Parlia does not allow uncle blocks, so `UncleHash` is pinned to the empty-list hash in every block. +2. BSC has no consensus-layer beacon chain, so `ParentBeaconRoot` is pinned to the zero hash and the EIP-4788 system call is never executed. + +Repurposing these two fields gives each block a home for producer metadata, such as the software or pipeline version that produced it, which is useful for rollout monitoring, debugging, and indexing. The metadata adds zero overhead — no new header field, no size increase, and no change to block encoding — and sits inside the sealed block header, covered by the producer's signature and directly readable by nodes, indexers, and monitoring systems. + +## 3. Specification + +### 3.1 Current Behavior + +Neither field carries information on BSC today; header verification pins both to constants: + +1. `UncleHash` is always the empty-list hash because Parlia does not allow uncle blocks. +2. `ParentBeaconRoot` is nil before Bohr and the zero hash after Bohr. Since it is always zero when present, the EIP-4788 beacon-root system call is skipped on BSC. + +These constants do not affect EVM execution. This BEP relaxes the corresponding validation checks so the fields can carry producer metadata once activated. + +### 3.2 Header Field Usage and Metadata Encoding + +Starting from the activation of this BEP: + +1. Block producers may write producer metadata into `UncleHash`. +2. Block producers may write producer metadata into `ParentBeaconRoot`. +3. If a block producer does not write metadata, it SHOULD keep using the current default values: `EmptyUncleHash` for `UncleHash` and the zero hash for `ParentBeaconRoot`. + +The block header RLP layout and existing JSON-RPC field names remain unchanged: `sha3Uncles` and `parentBeaconBlockRoot` continue to expose the raw 32-byte values. + +This BEP reserves the two fields for producer metadata, such as version information, and does not mandate a specific encoding. A follow-up BEP or client release will define the concrete layout of the 32-byte values. Encodings MUST be deterministic and MUST NOT collide with the default values defined above. + +The metadata is claimed by the block producer and covered by the block seal, but its content is not verified by consensus. Consumers should treat it as informational metadata. + +### 3.3 Block Validity + +After this BEP is activated: + +1. Clients MUST accept any 32-byte value in `UncleHash` and `ParentBeaconRoot` when validating Parlia blocks. `ParentBeaconRoot` MUST remain present (non-nil). +2. The uncle list in the block body MUST remain empty. Clients MUST verify this directly on the body, and MUST NOT derive the expected uncle list from `UncleHash`. +3. `ParentBeaconRoot` MUST NOT trigger the EIP-4788 beacon root system call, regardless of its value. Neither field affects EVM execution. + +Before this BEP is activated, existing validation rules remain unchanged. + +## 4. Backward Compatibility + +This change requires a hard fork: nodes that do not upgrade will continue to enforce the constant values described in 3.1 and reject blocks that carry metadata in these fields. + +Since the header layout and field names are unchanged, existing tools continue to decode blocks, but tools that assume `sha3Uncles` is always the empty uncle hash or that `parentBeaconBlockRoot` is always zero should be updated. Until a concrete metadata encoding is deployed, the default values remain in use and observable chain data does not change at activation. + +## 5. License + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/BEPs/BEP1.md b/BEPs/BEP1.md index 6c57a97b..e4da061b 100644 --- a/BEPs/BEP1.md +++ b/BEPs/BEP1.md @@ -33,7 +33,8 @@ For BNB Chain contributors, it is a convenient way to track the progress of thei There are three types of BEP: -- **Standards**: A Standards BEP describes functional changes on BNB Chain, such as a change to the network protocol, proposer selection mechanism in consensus algorithm, change in block size or fee mechanism in application level. It will effect the implementation of BNB Chain. +- **Standards**: A Standards BEP outlines functional changes on the BNB Chain, such as modifications to the network protocol, consensus algorithm, changes in block size, or adjustments to the fee mechanis. These changes will impact the implementation of the BNB Chain. +- **Application**: It defines standards for application layer interactions on BNB Chain, distinguishing it from Standards BEPs which govern core protocol changes. Application proposals are designated as BAPs (BNB Chain Application Proposals) and are stored in the "/BAPs/" folder. For more information, please see the [BAP README](../BAPs/README.md). - **Information**: An Information BEP will clarify some concepts of the BNB Chain, it may not effect the BNB Chain client implementation. - **Process**: This kind of proposal will change the workflow of BNB Chain working process, like this BEP itself. diff --git a/BEPs/BEP12.md b/BEPs/BEP12.md index 82437c2a..5b93f636 100644 --- a/BEPs/BEP12.md +++ b/BEPs/BEP12.md @@ -1,6 +1,6 @@ # BEP12: Introduce Customized Scripts and Transfer Memo Validation ## Summary -This BEP describes a new feature that enables addresses to customize scripts, and introduces the a validation script for transfer transaction memo. +This BEP describes a new feature that enables addresses to customize scripts, and introduces a validation script for transfer transaction memo. ## Abstract In some circumstances, users may want to specify some additional functions or/and validations on some transactions. diff --git a/BEPs/BEP153.md b/BEPs/BEP153.md index ad13fcfc..6e2ce61f 100644 --- a/BEPs/BEP153.md +++ b/BEPs/BEP153.md @@ -22,6 +22,7 @@ - [5.5.2 Crash in Application Layer](#552-crash-in-application-layer) - [5.5.3 Error in Communication Layer](#553-error-in-communication-layer) - [5.5.4 How Funds are Handled When Errors Occur](#554-how-funds-are-handled-when-errors-occur) + - [6. License](#6-license) ## 1. Summary @@ -223,4 +224,8 @@ It is very important to protect the safety of actors’ funds. As funds need to When a delegation request fails, an extra cross-chain package will be sent back to BSC. The funds will be unlocked from the tokenhub system contract, transferred to the staking system contract and be recorded as a part of the delegator’s pending undelegated. The delegator can get his/her funds back by claimUndelegated later. However, if the msg sender is a contract without a receive/fallback method, the transfer will fail and the funds may be lost forever. So **make sure your dApp implements the receive/fallback method**. -![5.3 Error handle](./assets/bep-153/5.3_errorhandle.jpg) \ No newline at end of file +![5.3 Error handle](./assets/bep-153/5.3_errorhandle.jpg) + +## 6. License + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP172.md b/BEPs/BEP172.md index de1996da..3a1ffb46 100644 --- a/BEPs/BEP172.md +++ b/BEPs/BEP172.md @@ -16,6 +16,7 @@ Discussions: https://forum.bnbchain.org/t/bep-172-draft-improvement-on-bsc-valid - [4.1 Overall workflow](#41-overall-workflow) - [4.2 Remove recentlySigned validators from the candidate set](#42-remove-recentlysigned-validators-from-the-candidate-set) - [4.3 Reduce minimum delay duration to be zero added to 3 seconds](#43-reduce-minimum-delay-duration-to-be-zero-added-to-3-seconds) + - [5. License](#5-license) ## 1. Summary @@ -39,4 +40,8 @@ With this BEP we rewrite the calculation algorithm for the `offturn` validation ### 4.2 Remove recentlySigned validators from the candidate set - All validators would be involved to calculate the `delay` time when committing the block mined by themselves currently, and when the `inturn` validator missed its turn, the fastest-with the smallest `delay` duration equals to 4 seconds-`offturn` validator might be the one that had signed recently which led to some other `offturn` validator be the valid selected one to commit block. This is how we observed a block be committed in more than 4 seconds when the `slash` happened. In this BEP, we remove the `recently signed` validators off from the candidate set for calculating `delay` duration from 1 seconds(then the duration would be 3+1=4 seconds) up. ### 4.3 Reduce minimum delay duration to be zero added to 3 seconds - - When a `slash` happened, things would go wrong for quite a long time later on. For example, when `inturn` validator_A was `slashed` on block_100 and `offturn` validator_B took its place to commit the block of number 100. However validator_B should be `inturn` for committing block_101, then it would fail to commit block_101 since it had committed block_100 `recently`. So although there was actually no `slash` happend(all validator worked appropriately), we still need to `delay` some time (1 second or more) to wait for the `offturn` validator committing the block since the `inturn` validator had `recently` committed some block earlier.In this BEP, we reduce the shortest duration to zero second for this specific scenario which means blocks should be able to committed in expected duration (3 seconds) when all validators workd propriately. + - When a `slash` happened, things would go wrong for quite a long time later on. For example, when `inturn` validator_A was `slashed` on block_100 and `offturn` validator_B took its place to commit the block of number 100. However validator_B should be `inturn` for committing block_101, then it would fail to commit block_101 since it had committed block_100 `recently`. So although there was actually no `slash` happened(all validator worked appropriately), we still need to `delay` some time (1 second or more) to wait for the `offturn` validator committing the block since the `inturn` validator had `recently` committed some block earlier.In this BEP, we reduce the shortest duration to zero second for this specific scenario which means blocks should be able to committed in expected duration (3 seconds) when all validators worked propriately. + +## 5. License + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP173.md b/BEPs/BEP173.md index 8d9006ab..0a69738a 100644 --- a/BEPs/BEP173.md +++ b/BEPs/BEP173.md @@ -13,7 +13,7 @@ - [4.3.2 Voting stage](#432-voting-stage) - [4.3.3 Tallying stage](#433-tallying-stage) - [4.3.4 Execution stage](#434-execution-stage) - + - [5. License](#5-license) ## 1. Summary @@ -98,3 +98,7 @@ If any of these conditions are not met, the deposit associated with the denied p #### 4.3.4 Execution Stage Once a text proposal is passed, it has no direct effect on the BNB Chain. Generic proposals such as a TextProposal must be reviewed by the BNB-Chain developers and the community for decisions on how to manually implement them. + +## 5. License + +The content is licensed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file diff --git a/BEPs/BEP20.md b/BEPs/BEP20.md index 5d6020a0..4819b62a 100644 --- a/BEPs/BEP20.md +++ b/BEPs/BEP20.md @@ -13,11 +13,10 @@ - [5.1.1.3 decimals](#5113-decimals) - [5.1.1.4 totalSupply](#5114-totalsupply) - [5.1.1.5 balanceOf](#5115-balanceof) - - [5.1.1.6 getOwner](#5116-getowner) - - [5.1.1.7 transfer](#5117-transfer) - - [5.1.1.8 transferFrom](#5118-transferfrom) - - [5.1.1.9 approve](#5119-approve) - - [5.1.1.10 allowance](#51110-allowance) + - [5.1.1.6 transfer](#5117-transfer) + - [5.1.1.7 transferFrom](#5118-transferfrom) + - [5.1.1.8 approve](#5119-approve) + - [5.1.1.9 allowance](#51110-allowance) - [5.1.2 Events](#512-events) - [5.1.2.1 Transfer](#5121-transfer) - [5.1.2.2 Approval](#5122-approval) @@ -81,21 +80,14 @@ function balanceOf(address _owner) public view returns (uint256 balance) ``` - Returns the account balance of another account with address `_owner`. -##### 5.1.1.6 getOwner -``` -function getOwner() external view returns (address); -``` -- Returns the bep20 token owner which is necessary for binding with bep2 token. -- **NOTE** - This is an extended method of EIP20. Tokens which don’t implement this method will never flow across the BNB Beacon Chain and BNB Smart Chain. - -##### 5.1.1.7 transfer +##### 5.1.1.6 transfer ``` function transfer(address _to, uint256 _value) public returns (bool success) ``` - Transfers `_value` amount of tokens to address `_to`, and MUST fire the Transfer event. The function SHOULD throw if the message caller’s account balance does not have enough tokens to spend. - **NOTE** - Transfers of 0 values MUST be treated as normal transfers and fire the Transfer event. -##### 5.1.1.8 transferFrom +##### 5.1.1.7 transferFrom ``` function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) ``` @@ -103,14 +95,14 @@ function transferFrom(address _from, address _to, uint256 _value) public returns - The transferFrom method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD throw unless the `_from` account has deliberately authorized the sender of the message via some mechanism. - **NOTE** - Transfers of 0 values MUST be treated as normal transfers and fire the Transfer event. -##### 5.1.1.9 approve +##### 5.1.1.8 approve ``` function approve(address _spender, uint256 _value) public returns (bool success) ``` - Allows `_spender` to withdraw from your account multiple times, up to the `_value` amount. If this function is called again it overwrites the current allowance with `_value`. - **NOTE** - To prevent attack vectors like the one described here and discussed here, clients SHOULD make sure to create user interfaces in such a way that they set the allowance first to 0 before setting it to another value for the same spender. THOUGH The contract itself shouldn’t enforce it, to allow backwards compatibility with contracts deployed before -##### 5.1.1.10 allowance +##### 5.1.1.9 allowance ``` function allowance(address _owner, address _spender) public view returns (uint256 remaining) ``` diff --git a/BEPs/BEP206.md b/BEPs/BEP206.md index 542254e8..b3e377e5 100644 --- a/BEPs/BEP206.md +++ b/BEPs/BEP206.md @@ -214,7 +214,7 @@ It is somehow reasonable, as the first transaction will be executed first, so it Snapshot will still be corresponding to the MPT structure. -Once the MPT is shrinked due to more sub-paths being expired, which will make the MPT end up with some boundary nodes. Boundary nodes are trie nodes that are either leaf nodes or intermediate nodes with at least one of its children expired. +Once the MPT is shrunk due to more sub-paths being expired, which will make the MPT end up with some boundary nodes. Boundary nodes are trie nodes that are either leaf nodes or intermediate nodes with at least one of its children expired. The snapshot shrink can be conducted by off-line prune according to the MPT. ![7_snapshot.png](./assets/bep-206/7_snapshot.png) @@ -292,7 +292,7 @@ if curEpoch in EpochRecords { // first time to access var NewEpochRecords := {curEpoch, 0} // reset -EpochRecordsSorted := sort(EpochRecords) // decending order +EpochRecordsSorted := sort(EpochRecords) // descending order for epoch, numKeys := range EpochRecordsSorted { fee := GetEpochFee(epoch, numKeys) if RentBalance >= fee { diff --git a/BEPs/BEP217.md b/BEPs/BEP217.md index 53c11b14..3a2c96a2 100644 --- a/BEPs/BEP217.md +++ b/BEPs/BEP217.md @@ -52,7 +52,7 @@ It is motivated by three reasons: 2. To have a cost system which is extendable in the future (i.e. for proposals like[ EIP-3670](https://eips.ethereum.org/EIPS/eip-3670)). 3. To simplify EVM engines by the explicit limits (code size, code offsets (PC), and jump offsets fit 16-bits). -## 4. Specificaton +## 4. Specification ### Parameters diff --git a/BEPs/BEP322.md b/BEPs/BEP322.md index 0f60d0d4..49057d61 100644 --- a/BEPs/BEP322.md +++ b/BEPs/BEP322.md @@ -43,9 +43,9 @@ proposing blocks. ## 2. Motivation The Ethereum MEV market is thriving, with -the [Ethereum Builder API Specification](https://github.com/ethereum/builder-specs)) widely supported by +the [Ethereum Builder API Specification](https://github.com/ethereum/builder-specs) widely supported by mainstream consensus clients. As of October 2023, the inclusion rate of blocks from builders is -approximately [90%](https://dune.com/ChainsightAnalytics/mev-after-ethereum-merge)). +approximately [90%](https://dune.com/ChainsightAnalytics/mev-after-ethereum-merge). The BNB Smart Chain MEV market still remains at a Wild West stage. The absence of PBS adoption results in a chaotic landscape with different architectures and API standards. Nowadays, it is very challenging for validators to @@ -288,6 +288,60 @@ Response: } ``` +##### 4.4.1.3 Query Bundle Data + +This API enables MEV data analysts to query bundle information from builders. +It is particularly useful for MEV data providers who need to analyze market trends and create analytics dashboards. +For instance, to accurately measure MEV market activity, providers can use this API to display metrics such as +daily bundle counts and bundles per block in their analytics panels. + +Request: + +```json +{ + "jsonrpc": "2.0", + "method": "eth_bundles", + "params": [ + "0x1", + "0x3" + ], + "id": 1 +} +``` + +Params: + +1. String - `FromBlock`, It is the hex value of a block number. +2. String - `ToBlock`, It is either the hex value of a block number OR block tags: "latest", "pending". It should be +no less than `FromBlock` and less than `FromBlock+100`. + +Response: + +* Return bundles whose first-received-height(`receivedBlock`) is within the block range [`FromBlock`, `ToBlock`]. + +```json +{ + "jsonrpc": "2.0", + "result": [ + { + "receivedBlock": "0x1", + "bundles": [ + ["0x88...44b", "0x89..45b"], // tx hase list in the bundle + ["0x90...46b"] + ] + }, + { + "receivedBlock": "0x2", + "bundles": [ + ["0x23...24b", "0x39..45b"], + ["0x43...55a", "0x45..33a", "0x39..45b"] // it is possible that a same tx hash exists in different block + ] + } + ], + "id": 1 +} +``` + #### 4.4.2 Validator APIs The following APIs should be implemented on the validator side or BSC clients. diff --git a/BEPs/BEP333.md b/BEPs/BEP333.md index 60e67561..c7d3be55 100644 --- a/BEPs/BEP333.md +++ b/BEPs/BEP333.md @@ -1,7 +1,7 @@
   BEP: 333
   Title: BNB Chain Fusion
-  Status: Candidate
+  Status: Enabled
   Type: Standards
   Created: 2023-11-29
 
diff --git a/BEPs/BEP9.md b/BEPs/BEP9.md index 6ecfcf85..96727d6f 100644 --- a/BEPs/BEP9.md +++ b/BEPs/BEP9.md @@ -22,7 +22,7 @@ This BEP describes a proposal for a time-locking feature of tokens on the BNB Be BEP-9 Proposal describes functionality to time-lock tokens on the BNB Beacon Chain. Such as: -+ TimeLock: TimeLock will transfer locked tokens to a purely-code-controlled escrow account. A purely-code-controlled escrow account is a kind of account which is derived from a hard-coded string in BNB Beacon Chain protocol. This kind of account has no private key and it's only controled by code in protocol. Before the lock time expires, the specific user will not be able to claim them back, including restrictions where they cannot use, transfer or spend these tokens. ++ TimeLock: TimeLock will transfer locked tokens to a purely-code-controlled escrow account. A purely-code-controlled escrow account is a kind of account which is derived from a hard-coded string in BNB Beacon Chain protocol. This kind of account has no private key and it's only controlled by code in protocol. Before the lock time expires, the specific user will not be able to claim them back, including restrictions where they cannot use, transfer or spend these tokens. + TimeUnlock: TimeUnlock will claim the locked tokens back when the specified lock time has passed. + TimeRelock: TimeRelock can extend lock times, increase the amount of locked tokens or modify the description of an existing lock record. + QueryTimeLocks: QueryTimeLocks will query all lock records of a given address. diff --git a/BEPs/assets/BEP-525/3-1-2.png b/BEPs/assets/BEP-525/3-1-2.png new file mode 100644 index 00000000..1cb1fbcb Binary files /dev/null and b/BEPs/assets/BEP-525/3-1-2.png differ diff --git a/BEPs/assets/BEP-525/3-1.png b/BEPs/assets/BEP-525/3-1.png new file mode 100644 index 00000000..569943ac Binary files /dev/null and b/BEPs/assets/BEP-525/3-1.png differ diff --git a/BEPs/assets/BEP-536/3-2.png b/BEPs/assets/BEP-536/3-2.png new file mode 100644 index 00000000..4e157556 Binary files /dev/null and b/BEPs/assets/BEP-536/3-2.png differ diff --git a/BEPs/assets/BEP-564/image1.png b/BEPs/assets/BEP-564/image1.png new file mode 100644 index 00000000..3ef292c7 Binary files /dev/null and b/BEPs/assets/BEP-564/image1.png differ diff --git a/BEPs/assets/BEP-592/bal-asset-1.png b/BEPs/assets/BEP-592/bal-asset-1.png new file mode 100644 index 00000000..b49d7b19 Binary files /dev/null and b/BEPs/assets/BEP-592/bal-asset-1.png differ diff --git a/BEPs/assets/BEP-593/bep_593_arch.png b/BEPs/assets/BEP-593/bep_593_arch.png new file mode 100644 index 00000000..855fd070 Binary files /dev/null and b/BEPs/assets/BEP-593/bep_593_arch.png differ diff --git a/BEPs/assets/BEP-593/storage_compare.png b/BEPs/assets/BEP-593/storage_compare.png new file mode 100644 index 00000000..5781db78 Binary files /dev/null and b/BEPs/assets/BEP-593/storage_compare.png differ diff --git a/BEPs/assets/BEP-594/bep_594_arch.png b/BEPs/assets/BEP-594/bep_594_arch.png new file mode 100644 index 00000000..5aefbfbb Binary files /dev/null and b/BEPs/assets/BEP-594/bep_594_arch.png differ diff --git a/BEPs/assets/BEP-594/bep_594_workflow.png b/BEPs/assets/BEP-594/bep_594_workflow.png new file mode 100644 index 00000000..d7340695 Binary files /dev/null and b/BEPs/assets/BEP-594/bep_594_workflow.png differ diff --git a/BEPs/assets/BEP-652/analysis.md b/BEPs/assets/BEP-652/analysis.md new file mode 100644 index 00000000..fe28ea44 --- /dev/null +++ b/BEPs/assets/BEP-652/analysis.md @@ -0,0 +1,111 @@ +# BEP-652 Empirical Report + +*The following represents a summary with empirical findings from analyzing a `2**24` (16,777,216) transaction gas limit cap.* +*Date: January 28, 2026* + +## Dataset + +- **Period**: 2025-12-27 to 2026-01-28 +- **Blocks analyzed**: 4,802,727 +- **Total transactions**: 517,359,109 + +## Impact Metrics + +### Transaction Impact + +| Metric | Value | +|--------|-------| +| Affected transactions | 41,604 | +| Impact rate | 0.0080% | +| Unique affected addresses | 5,905 | +| Avg transactions per affected address | 7.0 | + +## Gas Analysis (of Affected) + +| Metric | Value | +|--------|-------| +| Average gas limit (affected txs) | 30,112,436 | +| Average gas used | 21,864,045 | +| Gas efficiency | 72.6% | +| Min gas used | 10,003,266 | +| Max gas used | 95,975,271 | +| Transactions with unnecessary high limits | 16,254 (39.07%) | + +> Note: "Unnecessary high limits" = gasLimit > gasUsed * 1.5 (50% buffer) + +## Gas Limit Distribution (gasLimit >= 16,777,216) + +| Gas Limit Range | Percentage | Transaction Count | +|-----------------|------------|-------------------| +| 16,777,216 - 30,000,000 | 58.08% | 24,154 | +| 30,000,000 - 40,000,000 | 23.62% | 9,829 | +| >40,000,000 | 18.32% | 7,620 | + + +## Gas Limit Distribution of Slow Transactions (>500ms) + +| Gas Limit Range | Percentage | Transaction Count | +|-----------------|------------|-------------------| +| <= 16,777,216 | 4.21% | 4 | +| 16,777,216 - 30,000,000 | 11.58% | 11 | +| 30,000,000 - 40,000,000 | 16.84% | 16 | +| > 40,000,000 | 67.37% | 64 | + +Total slow transactions (>500ms): 95 + +## Address Analysis + +### Top 10 From Addresses + +| Rank | Address | Transactions | Avg Gas Limit | Max Gas Limit | +|------|---------|--------------|---------------|---------------| +| 1 | 0x4688e0...ab20 | 4,749 | 24,894,947 | 24,956,279 | +| 2 | 0x5e6d93...9ac5 | 3,394 | 30,945,200 | 30,945,200 | +| 3 | 0xd81904...7220 | 2,808 | 40,945,200 | 40,945,200 | +| 4 | 0x6ad7b5...f848 | 1,634 | 25,191,664 | 61,421,290 | +| 5 | 0xeda91b...9118 | 1,158 | 17,230,949 | 17,314,203 | +| 6 | 0x8c38ce...95ea | 918 | 40,000,000 | 40,000,000 | +| 7 | 0x6205d0...f047 | 767 | 31,493,975 | 53,098,753 | +| 8 | 0x99187c...5889 | 644 | 20,000,000 | 20,000,000 | +| 9 | 0xb433b8...4ea6 | 540 | 23,572,658 | 29,066,877 | +| 10 | 0xc64bf1...7c8e | 481 | 17,351,652 | 17,351,993 | + +### Top 10 To Addresses + +| Rank | Address | Transactions | % of Total | Note | +|------|---------|--------------|------------|------| +| 1 | 0xba49fa...49dc | 4,749 | 11.4% | Airdrop Contract | +| 2 | 0xffb667...9649 | 3,394 | 8.2% | Batch Transfer Contract | +| 3 | 0xe39a5e...3d26 | 2,525 | 6.1% | Complex Transaction Contract (MEV/Arbitrage) | +| 4 | 0x7d6b49...8d95 | 2,148 | 5.2% | NFT2 Token Contract + Transfer | +| 5 | 0x4d1cdb...dbde | 1,781 | 4.3% | | +| 6 | 0x8ac784...146a | 1,717 | 4.1% | | +| 7 | 0x291c36...bd8c | 1,183 | 2.8% | | +| 8 | 0xe4f072...0e5f | 1,158 | 2.8% | | +| 9 | 0x24293c...4595 | 1,022 | 2.5% | | +| 10 | 0x07964f...0000 | 772 | 1.9% | | + +## Migration Analysis + +### Transaction Splitting Requirements + +If gasLimit capped at 16,777,216, how many splits needed per address: + +| Splits Required | Address Count | Percentage | +|-----------------|---------------|------------| +| 2 | 4,295 | 72.7% | +| 3 | 1,218 | 20.6% | +| 4+ | 392 | 6.6% | + +Total addresses needing splits: 5,905 + +## Summary + +| Metric | Value | +|--------|-------| +| Affected transactions | 41,604 (0.0080%) | +| Affected addresses | 5,905 | +| Total extra BNB | 0.0084 BNB (at 0.05 gwei) | +| Average splits required | 2.36 | + +____ diff --git a/BEPs/assets/bep-520/5-3.png b/BEPs/assets/bep-520/5-3.png new file mode 100644 index 00000000..e6c059ba Binary files /dev/null and b/BEPs/assets/bep-520/5-3.png differ diff --git a/README.md b/README.md index 161caf4f..0e2e068f 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,6 @@ Here is the list of subjects of BEPs: | [BEP-87](./BEPs/BEP87.md) | Token Symbol Minimum Length Change | Standards | Enabled | | [BEP-89](./BEPs/BEP89.md) | Visual Fork of BNB Smart Chain | Standards | Enabled | | [BEP-91](./BEPs/BEP91.md) | Increase Block Gas Ceiling for BNB Smart Chain | Standards | Enabled | -| [BEP-93](./BEPs/BEP93.md) | Diff Sync Protocol on BSC | Standards | Withdrawn | | [BEP-95](./BEPs/BEP95.md) | Introduce Real-Time Burning Mechanism | Standards | Enabled | | [BEP-126](./BEPs/BEP126.md) | Introduce Fast Finality Mechanism | Standards | Enabled | | [BEP-127](./BEPs/BEP127.md) | Temporary Maintenance Mode for Validators | Standards | Enabled | @@ -56,9 +55,9 @@ Here is the list of subjects of BEPs: | [BEP-293](./BEPs/BEP-293.md) | Greenfield Link to opBNB | Standards | Draft | | [BEP-294](./BEPs/BEP294.md) | BSC Native Staking after BC Fusion | Standards | Enabled | | [BEP-297](./BEPs/BEP297.md) | BSC Native Governance Module | Standards | Enabled | -| [BEP-299](./BEPs/BEP-299.md) | Token Migration after BC Fusion | Standards | Candidate | +| [BEP-299](./BEPs/BEP-299.md) | Token Migration after BC Fusion | Standards | Enabled | | [BEP-311](./BEPs/BEP-311.md) | Implement EIP-3651 Warm COINBASE | Standards | Enabled | -| [BEP-312](./BEPs/BEP-312.md) | Announce EIP-6049 Deprecate SELFDESTRUCT | Standards | Review | +| [BEP-312](./BEPs/BEP-312.md) | Announce EIP-6049 Deprecate SELFDESTRUCT | Standards | Enabled | | [BEP-319](./BEPs/BEP-319.md) | Optimize the incentive mechanism of the Fast Finality feature | Standards | Enabled | | [BEP-322](./BEPs/BEP322.md) | Builder API Specification for BNB Smart Chain | Standards | Enabled | | [BEP-323](./BEPs/BEP323.md) | Bundle Format for Greenfield | Standards | Enabled | @@ -78,12 +77,50 @@ Here is the list of subjects of BEPs: | [BEP-402](./BEPs/BEP-402.md) | Complete Missing Fields in Block Header to Generate Signature | Standards | Enabled | | [BEP-404](./BEPs/BEP-404.md) | Clear Miner History when Switching Validator Set | Standards | Enabled | | [BEP-410](./BEPs/BEP-410.md) | Add Agent for Validators | Standards | Enabled | -| [BEP-414](./BEPs/BEP-414.md) | EOA based Paymaster API Spec | Standards | Draft | -| [BEP-439](./BEPs/BEP-439.md) | Implement EIP-2537: Precompile for BLS12-381 curve operations | Standards | Review | -| [BEP-440](./BEPs/BEP-440.md) | Implement EIP-2935: Serve historical block hashes from state | Standards | Review | -| [BEP-441](./BEPs/BEP-441.md) | Implement EIP-7702: Set EOA account code | Standards | Review | +| [BEP-414](./BEPs/BEP-414.md) | EOA based Paymaster API Spec | Standards | Enabled | +| [BEP-439](./BEPs/BEP-439.md) | Implement EIP-2537: Precompile for BLS12-381 curve operations | Standards | Enabled | +| [BEP-440](./BEPs/BEP-440.md) | Implement EIP-2935: Serve historical block hashes from state | Standards | Enabled | +| [BEP-441](./BEPs/BEP-441.md) | Implement EIP-7702: Set EOA account code | Standards | Enabled | +| [BEP-466](./BEPs/BEP-466.md) | Make the block header format compatible with EIP-7685 | Standards | Enabled | +| [BEP-496](./BEPs/BEP-496.md) | Implement EIP-7623: Increase calldata cost | Standards | Enabled | +| [BEP-520](./BEPs/BEP-520.md) | Short Block Interval Phase One: 1.5 seconds | Standards | Enabled | +| [BEP-524](./BEPs/BEP-524.md) | Short Block Interval Phase Two: 0.75 seconds | Standards | Enabled | +| [BEP-563](./BEPs/BEP-563.md) | Enhanced Validator Network | Standards | Enabled | +| [BEP-564](./BEPs/BEP-564.md) | bsc/2 - New Block Fetching Messages | Standards | Enabled | +| [BEP-590](./BEPs/BEP-590.md) | Extended Voting Rules for Fast Finality Stability | Standards | Enabled | +| [BEP-592](./BEPs/BEP-592.md) | Non-Consensus Based Block-Level Access List | Standards | Candidate | +| [BEP-593](./BEPs/BEP-593.md) | Incremental Snapshot | Standards | Enabled | +| [BEP-594](./BEPs/BEP-594.md) | L2 Fast Withdrawal by TEE | Standards | Draft | +| [BEP-610](./BEPs/BEP-610.md) | Implement EVM Super Instruction | Standards | Candidate | +| [BEP-619](./BEPs/BEP-619.md) | Short Block Interval Phase Three: 0.45 Seconds | Standards | Enabled | +| [BEP-648](./BEPs/BEP-648.md) | Enhanced Fast Finality via In-Memory Voting Pool | Standards | Enabled | +| [BEP-651](./BEPs/BEP-651.md) | Implement EIP-7823 Set upper bounds for MODEXP | Standards | Enabled | +| [BEP-652](./BEPs/BEP-652.md) | Implement EIP-7825 Transaction Gas Limit Cap | Standards | Enabled | +| [BEP-653](./BEPs/BEP-653.md) | Implement EIP-7883 ModExp Gas Cost Increase | Standards | Enabled | +| [BEP-654](./BEPs/BEP-654.md) | Implement EIP-7939 Count Leading Zeros (CLZ) Opcode | Standards | Enabled | +| [BEP-655](./BEPs/BEP-655.md) | Implement EIP-7934 RLP Execution Block Size Limit | Standards | Enabled | +| [BEP-656](./BEPs/BEP-656.md) | Implement EIP-7910: eth_config JSON-RPC Method | Standards | Enabled | +| [BEP-657](./BEPs/BEP-657.md) | Limit Blob Transaction Inclusion by Block Number | Standards | Enabled | +| [BEP-658](./BEPs/BEP-658.md) | Hardfork Meta-Osaka/Mendel | Information | Enabled | +| [BEP-659](./BEPs/BEP-659.md) | Implement EIP-7951 Precompile for secp256r1 Curve Support | Standards | Enabled | +| [BEP-673](./BEPs/BEP-673.md) | Hardfork Meta-Pasteur | Information | Draft | +| [BEP-675](./BEPs/BEP-675.md) | Builder-Proposed Block with Validator Blind Signing | Standards | Draft | +| [BEP-677](./BEPs/BEP-677.md) | Implement EIP-8056 Scaled UI Amount | Standards | Draft | +| [BEP-682](./BEPs/BEP-682.md) | Reject Duplicate Validators in CometBFT Light Block Validation | Standards | Draft | +| [BEP-695](./BEPs/BEP-695.md) | Staking and Governance Security Hardening | Standards | Draft | +| [BEP-696](./BEPs/BEP-696.md) | Repurpose Unused Block Header Fields for Metadata | Standards | Draft | +# BAPs +BAP (BNB Application Proposal) defines standards for application layer interactions on BNB Chain. Unlike BEPs which govern core protocol changes, BAPs focus on establishing conventions and interfaces for how applications communicate and interact with each other within the BNB Chain ecosystem. +The process for submitting and managing BAPs follows the standardized workflow outlined in [BEP-1: Purpose and Guidelines](https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP1.md). BAP numbers are assigned based on the PR number, ensuring no overlap with BEP numbers. + +Here is the list of subjects of BAPs: + + +| Number | Title | Type | Status | +|------------------------------| --------------------------------------------------------- | --------- |-----------| +| [BAP-578](./BAPs/BAP-578.md) | BAP-578: Non-Fungible Agent (NFA) Token Standard | Application | Draft | # BNB Chain Upgrades [BNB Chain Upgrades(Mainnet): History & Forecast](https://forum.bnbchain.org/t/bnb-chain-upgrades-mainnet/936) @@ -91,5 +128,5 @@ Here is the list of subjects of BEPs: [BNB Chain Upgrades(Testnet): History & Forecast](https://forum.bnbchain.org/t/bnb-chain-upgrades-testnet/934) -# How To Contribute A BEP -If you have an idea and want to make it a BEP, you may refer [BEP-1](./BEPs/BEP1.md) +# How To Contribute +If you have an idea and want to make it a BEP/BAP, you may refer [BEP-1](./BEPs/BEP1.md) \ No newline at end of file