Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(counter-based ccc): add keccak #1015

Merged
merged 5 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -821,6 +821,7 @@ func (m callMsg) Value() *big.Int { return m.CallMsg.Value }
func (m callMsg) Data() []byte { return m.CallMsg.Data }
func (m callMsg) AccessList() types.AccessList { return m.CallMsg.AccessList }
func (m callMsg) IsL1MessageTx() bool { return false }
func (m callMsg) TxSize() common.StorageSize { return 0 }

// filterBackend implements filters.Backend to support filtering for logs without
// taking bloom-bits acceleration structures into account.
Expand Down
1 change: 1 addition & 0 deletions core/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func NewEVMTxContext(msg Message) vm.TxContext {
To: msg.To(),
GasPrice: new(big.Int).Set(msg.GasPrice()),
IsL1MessageTx: msg.IsL1MessageTx(),
TxSize: msg.TxSize(),
}
}

Expand Down
1 change: 1 addition & 0 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ type Message interface {
Data() []byte
AccessList() types.AccessList
IsL1MessageTx() bool
TxSize() common.StorageSize
}

// ExecutionResult includes all output after executing given evm
Expand Down
27 changes: 15 additions & 12 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,7 @@ type Message struct {
accessList AccessList
isFake bool
isL1MessageTx bool
txSize common.StorageSize
}

func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice, gasFeeCap, gasTipCap *big.Int, data []byte, accessList AccessList, isFake bool) Message {
Expand Down Expand Up @@ -785,6 +786,7 @@ func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) {
accessList: tx.AccessList(),
isFake: false,
isL1MessageTx: tx.IsL1MessageTx(),
txSize: tx.Size(),
}
// If baseFee provided, set gasPrice to effectiveGasPrice.
if baseFee != nil {
Expand All @@ -795,18 +797,19 @@ func (tx *Transaction) AsMessage(s Signer, baseFee *big.Int) (Message, error) {
return msg, err
}

func (m Message) From() common.Address { return m.from }
func (m Message) To() *common.Address { return m.to }
func (m Message) GasPrice() *big.Int { return m.gasPrice }
func (m Message) GasFeeCap() *big.Int { return m.gasFeeCap }
func (m Message) GasTipCap() *big.Int { return m.gasTipCap }
func (m Message) Value() *big.Int { return m.amount }
func (m Message) Gas() uint64 { return m.gasLimit }
func (m Message) Nonce() uint64 { return m.nonce }
func (m Message) Data() []byte { return m.data }
func (m Message) AccessList() AccessList { return m.accessList }
func (m Message) IsFake() bool { return m.isFake }
func (m Message) IsL1MessageTx() bool { return m.isL1MessageTx }
func (m Message) From() common.Address { return m.from }
func (m Message) To() *common.Address { return m.to }
func (m Message) GasPrice() *big.Int { return m.gasPrice }
func (m Message) GasFeeCap() *big.Int { return m.gasFeeCap }
func (m Message) GasTipCap() *big.Int { return m.gasTipCap }
func (m Message) Value() *big.Int { return m.amount }
func (m Message) Gas() uint64 { return m.gasLimit }
func (m Message) Nonce() uint64 { return m.nonce }
func (m Message) Data() []byte { return m.data }
func (m Message) AccessList() AccessList { return m.accessList }
func (m Message) IsFake() bool { return m.isFake }
func (m Message) IsL1MessageTx() bool { return m.isL1MessageTx }
func (m Message) TxSize() common.StorageSize { return m.txSize }

// copyAddressPtr copies an address.
func copyAddressPtr(a *common.Address) *common.Address {
Expand Down
9 changes: 5 additions & 4 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ type BlockContext struct {
// All fields can change between transactions.
type TxContext struct {
// Message information
Origin common.Address // Provides information for ORIGIN
To *common.Address // Provides information for trace
IsL1MessageTx bool // Provides information for trace
GasPrice *big.Int // Provides information for GASPRICE
Origin common.Address // Provides information for ORIGIN
To *common.Address // Provides information for trace
IsL1MessageTx bool // Provides information for trace
TxSize common.StorageSize // Provides information for trace
GasPrice *big.Int // Provides information for GASPRICE
}

// EVM is the Ethereum Virtual Machine base object and provides
Expand Down
36 changes: 29 additions & 7 deletions rollup/ccc/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ import (
)

const (
sigCountMax = 127
ecAddCountMax = 50
ecMulCountMax = 50
ecPairingCountMax = 2
rowUsageMax = 1_000_000
sigCountMax = 127
ecAddCountMax = 50
ecMulCountMax = 50
ecPairingCountMax = 2
rowUsageMax = 1_000_000
keccakRounds = 24
keccakRowsPerRound = 12
keccakRowsPerChunk = (keccakRounds + 1) * keccakRowsPerRound
)

var _ vm.EVMLogger = (*Logger)(nil)
Expand All @@ -37,7 +40,6 @@ var _ vm.EVMLogger = (*Logger)(nil)
// tx: row usage depends on the length of raw txns and the number of storage
// slots and/or accounts accessed. With the current gas limit of 10M, it is not possible
// to overflow the circuit.
// keccak: coming soon
type Logger struct {
currentEnv *vm.EVM
isCreate bool
Expand All @@ -54,11 +56,16 @@ type Logger struct {
sha256Usage uint64
expUsage uint64
modExpUsage uint64
keccakUsage uint64

l2TxnsRlpSize uint64
}

func NewLogger() *Logger {
const miscKeccakUsage = 50_000 // heuristically selected safe number to account for Rust side implementation details
return &Logger{
codesAccessed: make(map[common.Hash]bool),
keccakUsage: miscKeccakUsage,
}
}

Expand Down Expand Up @@ -89,6 +96,11 @@ func (l *Logger) logRawBytecode(code []byte) {
l.logBytecodeAccess(crypto.Keccak256Hash(code), uint64(len(code)))
}

// computeKeccakRows computes the number of rows used in keccak256 for the given bytes array length
func computeKeccakRows(length uint64) uint64 {
return ((length + 135) / 136) * keccakRowsPerChunk
}

// logPrecompileAccess checks if the invoked address is a precompile and increments
// resource usage of associated subcircuit
func (l *Logger) logPrecompileAccess(to common.Address, inputLen uint64, inputFn func(int64, int64) []byte) {
Expand All @@ -97,6 +109,7 @@ func (l *Logger) logPrecompileAccess(to common.Address, inputLen uint64, inputFn
switch to {
case common.BytesToAddress([]byte{1}): // &ecrecover{},
l.sigCount++
l.keccakUsage += computeKeccakRows(64)
outputLen = 32
case common.BytesToAddress([]byte{2}): // &sha256hash{},
l.logSha256(inputLen)
Expand Down Expand Up @@ -156,7 +169,10 @@ func (l *Logger) CaptureStart(env *vm.EVM, from common.Address, to common.Addres

if !env.TxContext.IsL1MessageTx {
l.sigCount++
l.l2TxnsRlpSize += uint64(env.TxContext.TxSize)
}
l.keccakUsage += computeKeccakRows(uint64(env.TxContext.TxSize))
l.keccakUsage += computeKeccakRows(64) // ecrecover per txn
}

func (l *Logger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) {
Expand All @@ -182,7 +198,10 @@ func (l *Logger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *
l.logCopy(scope.Stack.Back(3).Uint64())
case vm.CALLDATACOPY, vm.RETURNDATACOPY, vm.CODECOPY, vm.MCOPY, vm.CREATE, vm.CREATE2:
l.logCopy(scope.Stack.Back(2).Uint64())
case vm.LOG0, vm.LOG1, vm.LOG2, vm.LOG3, vm.LOG4, vm.SHA3, vm.RETURN, vm.REVERT:
case vm.SHA3:
l.keccakUsage += computeKeccakRows(scope.Stack.Back(1).Uint64())
l.logCopy(scope.Stack.Back(1).Uint64())
case vm.LOG0, vm.LOG1, vm.LOG2, vm.LOG3, vm.LOG4, vm.RETURN, vm.REVERT:
l.logCopy(scope.Stack.Back(1).Uint64())
case vm.DELEGATECALL, vm.STATICCALL:
inputOffset := int64(scope.Stack.Back(2).Uint64())
Expand Down Expand Up @@ -274,6 +293,9 @@ func (l *Logger) RowConsumption() types.RowConsumption {
}, {
Name: "mod_exp",
RowNumber: l.modExpUsage,
}, {
Name: "keccak",
RowNumber: l.keccakUsage + computeKeccakRows(l.l2TxnsRlpSize),
},
}
}
Expand Down
Loading