Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rachit77 committed Jun 1, 2024
1 parent 116d024 commit ca6db9e
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 31 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ require (
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/garslo/gogen v0.0.0-20170307003452-d6ebae628c7c // indirect
github.com/gateway-fm/cdk-erigon-lib v0.0.0-20240415152010-66aa405ca33f // indirect
github.com/go-llsqlite/adapter v0.0.0-20230912124304-94ed0e573c23 // indirect
github.com/go-llsqlite/crawshaw v0.0.0-20230910110433-7e901377eb6c // indirect
github.com/go-logr/logr v1.2.4 // indirect
Expand Down Expand Up @@ -282,6 +283,7 @@ require (
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/supranational/blst v0.3.11 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/torquem-ch/mdbx-go v0.27.10 // indirect
github.com/valyala/fastrand v1.1.0 // indirect
github.com/valyala/histogram v1.2.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/garslo/gogen v0.0.0-20170307003452-d6ebae628c7c h1:uYNKzPntb8c6DKvP9EfrBjkLkU7pM4lM+uuHSIa8UtU=
github.com/garslo/gogen v0.0.0-20170307003452-d6ebae628c7c/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8=
github.com/gateway-fm/cdk-erigon-lib v0.0.0-20240415152010-66aa405ca33f h1:/o6bj7zF7c72CttEswr8gG0iFC749eVprCVc2pKIB9w=
github.com/gateway-fm/cdk-erigon-lib v0.0.0-20240415152010-66aa405ca33f/go.mod h1:Ky//z32wQOTY/drV858kr8dECBD9OBV9Xzy+aG6TxSk=
github.com/gateway-fm/vectorized-poseidon-gold v1.0.0 h1:Du0ZW+fkZhgRNGx/gAkHnMj3/Rl8uJkAEe+ZDPX3PDw=
github.com/gateway-fm/vectorized-poseidon-gold v1.0.0/go.mod h1:VLGQpyjrOg8+FugH/+d8tfYd/c3z4Xqa+zbUBITygaw=
github.com/gballet/go-verkle v0.0.0-20221121182333-31427a1f2d35 h1:I8QswD9gf3VEpr7bpepKKOm7ChxFITIG+oc1I5/S0no=
Expand Down Expand Up @@ -990,6 +992,8 @@ github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5I
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY=
github.com/torquem-ch/mdbx-go v0.27.10 h1:iwb8Wn9gse4MEYIltAna+pxMPCY7hA1/5LLN/Qrcsx0=
github.com/torquem-ch/mdbx-go v0.27.10/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E=
github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc=
github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4=
github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU=
Expand Down
2 changes: 1 addition & 1 deletion turbo/stages/mock/mock_sentry.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK
londonBlock := mock.ChainConfig.LondonBlock
shanghaiTime := mock.ChainConfig.ShanghaiTime

mock.TxPool, err = txpool.New(newTxs, mock.DB, txpoolcfg.DefaultConfig, &ethconfig.Defaults, kvcache.NewDummy(), *chainID, shanghaiTime, londonBlock)
mock.TxPool, err = txpool.New(newTxs, mock.DB, txpoolcfg.DefaultConfig, &ethconfig.Defaults, kvcache.NewDummy(), *chainID, shanghaiTime, londonBlock, nil)
if err != nil {
tb.Fatal(err)
}
Expand Down
28 changes: 28 additions & 0 deletions zk/txpool/acl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package txpool

import (
"github.com/ledgerwatch/erigon-lib/kv"
)

const (
Whitelist = "Whitelist"
Blacklist = "Blacklist"
)

var ACLTables = []string{
Whitelist,
Blacklist,
}

var ACLTablesCfg = kv.TableCfg{}

const ACLDB kv.Label = 255

func init() {
for _, name := range ACLTables {
_, ok := ACLTablesCfg[name]
if !ok {
ACLTablesCfg[name] = kv.TableCfgItem{}
}
}
}
129 changes: 129 additions & 0 deletions zk/txpool/policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package txpool

import (
"bytes"
"context"

"github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/types"
)

// PolicyName is a named policy
type PolicyName string

const (
// SendTx is the name of the policy that governs that an address may send transactions to pool
SendTx PolicyName = "send_tx"
// Deploy is the name of the policy that governs that an address may deploy a contract
Deploy PolicyName = "deploy"
)

// containsPolicy checks if the given policy is present in the policy list
func containsPolicy(policies []byte, policy PolicyName) bool {
return bytes.Contains(policies, []byte(policy))
}

// create a method checkpolicy to check an address according to passed policy in the method
func (p *TxPool) checkPolicy(addr common.Address, policy PolicyName) (bool, error) {
var whitelistPolicy []byte
err := p.aclDB.View(context.TODO(), func(tx kv.Tx) error {
value, err := tx.GetOne("Whitelist", addr.Bytes())
if err != nil {
return err
}
whitelistPolicy = value
return nil
})
if err != nil {
return false, err
}
if whitelistPolicy != nil && containsPolicy(whitelistPolicy, policy) {
// If address is in the whitelist and has the policy, return true
return true, nil
}

var blacklistPolicy []byte
err = p.aclDB.View(context.TODO(), func(tx kv.Tx) error {
value, err := tx.GetOne("Blacklist", addr.Bytes())
if err != nil {
return err
}
blacklistPolicy = value
return nil
})
if err != nil {
return false, err
}
if blacklistPolicy != nil && containsPolicy(blacklistPolicy, policy) {
// If address is in the blacklist and has the policy, return false
return false, nil
}

// If the address is not in either list, return false
return false, nil
}

// create a method to resolve policy which will decode a tx to either sendTx or deploy policy
func resolvePolicy(txn *types.TxSlot) PolicyName {
if txn.Creation {
return Deploy
}
return SendTx
}

// create a method to setpolicy which will set a policy for an address in the db
func (p *TxPool) setpolicy(addr common.Address, policy PolicyName, bucket string) error {
return p.aclDB.Update(context.TODO(), func(tx kv.RwTx) error {
value, err := tx.GetOne(bucket, addr.Bytes())
if err != nil {
return err
}
var policies []byte
if value != nil {
policies = value
// Check if the policy already exists
if bytes.Contains(policies, []byte(policy)) {
return nil
}
// Append the new policy
policies = append(policies, byte(','))
policies = append(policies, []byte(policy)...)
} else {
// New entry
policies = []byte(policy)
}
return tx.Put(bucket, addr.Bytes(), policies)
})
}

// method to remove a address from policy
func (p *TxPool) removepolicy(addr common.Address, policy PolicyName, bucket string) error {
return p.aclDB.Update(context.TODO(), func(tx kv.RwTx) error {
value, err := tx.GetOne(bucket, addr.Bytes())
if err != nil {
return err
}
if value == nil {
// No policies exist for this address
return nil
}

policies := bytes.Split(value, []byte(","))
var updatedPolicies [][]byte

for _, p := range policies {
if string(p) != string(policy) {
updatedPolicies = append(updatedPolicies, p)
}
}

if len(updatedPolicies) == 0 {
return tx.Delete(bucket, addr.Bytes())
}

// Join the updated policies back into a single byte slice
updatedValue := bytes.Join(updatedPolicies, []byte(","))
return tx.Put(bucket, addr.Bytes(), updatedValue)
})
}
90 changes: 61 additions & 29 deletions zk/txpool/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,31 +116,33 @@ const (
type DiscardReason uint8

const (
NotSet DiscardReason = 0 // analog of "nil-value", means it will be set in future
Success DiscardReason = 1
AlreadyKnown DiscardReason = 2
Mined DiscardReason = 3
ReplacedByHigherTip DiscardReason = 4
UnderPriced DiscardReason = 5
ReplaceUnderpriced DiscardReason = 6 // if a transaction is attempted to be replaced with a different one without the required price bump.
FeeTooLow DiscardReason = 7
OversizedData DiscardReason = 8
InvalidSender DiscardReason = 9
NegativeValue DiscardReason = 10 // ensure no one is able to specify a transaction with a negative value.
Spammer DiscardReason = 11
PendingPoolOverflow DiscardReason = 12
BaseFeePoolOverflow DiscardReason = 13
QueuedPoolOverflow DiscardReason = 14
GasUintOverflow DiscardReason = 15
IntrinsicGas DiscardReason = 16
RLPTooLong DiscardReason = 17
NonceTooLow DiscardReason = 18
InsufficientFunds DiscardReason = 19
NotReplaced DiscardReason = 20 // There was an existing transaction with the same sender and nonce, not enough price bump to replace
DuplicateHash DiscardReason = 21 // There was an existing transaction with the same hash
InitCodeTooLarge DiscardReason = 22 // EIP-3860 - transaction init code is too large
UnsupportedTx DiscardReason = 23 // unsupported transaction type
OverflowZkCounters DiscardReason = 24 // unsupported transaction type
NotSet DiscardReason = 0 // analog of "nil-value", means it will be set in future
Success DiscardReason = 1
AlreadyKnown DiscardReason = 2
Mined DiscardReason = 3
ReplacedByHigherTip DiscardReason = 4
UnderPriced DiscardReason = 5
ReplaceUnderpriced DiscardReason = 6 // if a transaction is attempted to be replaced with a different one without the required price bump.
FeeTooLow DiscardReason = 7
OversizedData DiscardReason = 8
InvalidSender DiscardReason = 9
NegativeValue DiscardReason = 10 // ensure no one is able to specify a transaction with a negative value.
Spammer DiscardReason = 11
PendingPoolOverflow DiscardReason = 12
BaseFeePoolOverflow DiscardReason = 13
QueuedPoolOverflow DiscardReason = 14
GasUintOverflow DiscardReason = 15
IntrinsicGas DiscardReason = 16
RLPTooLong DiscardReason = 17
NonceTooLow DiscardReason = 18
InsufficientFunds DiscardReason = 19
NotReplaced DiscardReason = 20 // There was an existing transaction with the same sender and nonce, not enough price bump to replace
DuplicateHash DiscardReason = 21 // There was an existing transaction with the same hash
InitCodeTooLarge DiscardReason = 22 // EIP-3860 - transaction init code is too large
UnsupportedTx DiscardReason = 23 // unsupported transaction type
OverflowZkCounters DiscardReason = 24 // unsupported transaction type
SenderDisallowedSendTx DiscardReason = 25 // sender is not allowed to send transactions by ACL policy
SenderDisallowedDeploy DiscardReason = 26 // sender is not allowed to deploy contracts by ACL policy
)

func (r DiscardReason) String() string {
Expand Down Expand Up @@ -195,6 +197,10 @@ func (r DiscardReason) String() string {
return "unsupported transaction type"
case OverflowZkCounters:
return "overflow zk-counters"
case SenderDisallowedSendTx:
return "sender disallowed to send tx by ACL policy"
case SenderDisallowedDeploy:
return "sender disallowed to deploy contract by ACL policy"
default:
panic(fmt.Sprintf("discard reason: %d", r))
}
Expand Down Expand Up @@ -303,14 +309,15 @@ type TxPool struct {
shanghaiTime *big.Int
isPostShanghai atomic.Bool
allowFreeTransactions bool
aclDB kv.RwDB

// we cannot be in a flushing state whilst getting transactions from the pool, so we have this mutex which is
// exposed publicly so anything wanting to get "best" transactions can ensure a flush isn't happening and
// vice versa
flushMtx *sync.Mutex
}

func New(newTxs chan types.Announcements, coreDB kv.RoDB, cfg txpoolcfg.Config, ethCfg *ethconfig.Config, cache kvcache.Cache, chainID uint256.Int, shanghaiTime *big.Int, londonBlock *big.Int) (*TxPool, error) {
func New(newTxs chan types.Announcements, coreDB kv.RoDB, cfg txpoolcfg.Config, ethCfg *ethconfig.Config, cache kvcache.Cache, chainID uint256.Int, shanghaiTime *big.Int, londonBlock *big.Int, aclDB kv.RwDB) (*TxPool, error) {
var err error
localsHistory, err := simplelru.NewLRU[string, struct{}](10_000, nil)
if err != nil {
Expand Down Expand Up @@ -352,6 +359,7 @@ func New(newTxs chan types.Announcements, coreDB kv.RoDB, cfg txpoolcfg.Config,
shanghaiTime: shanghaiTime,
allowFreeTransactions: ethCfg.Zk.AllowFreeTransactions,
flushMtx: &sync.Mutex{},
aclDB: aclDB,
}, nil
}

Expand Down Expand Up @@ -643,7 +651,7 @@ func (p *TxPool) AddRemoteTxs(_ context.Context, newTxs types.TxSlots) {
}
}

func (p *TxPool) validateTx(txn *types.TxSlot, isLocal bool, stateCache kvcache.CacheView) DiscardReason {
func (p *TxPool) validateTx(txn *types.TxSlot, isLocal bool, stateCache kvcache.CacheView, from common.Address) DiscardReason {
isShanghai := p.isShanghai()
if isShanghai {
if txn.DataLen > fixedgas.MaxInitCodeSize {
Expand Down Expand Up @@ -704,6 +712,30 @@ func (p *TxPool) validateTx(txn *types.TxSlot, isLocal bool, stateCache kvcache.
}
return InsufficientFunds
}

// check ACL policy
switch resolvePolicy(txn) {
case SendTx:
var allow bool
allow, err := p.checkPolicy(from, SendTx)
if err != nil {
panic(err)
}
if !allow {
return SenderDisallowedSendTx
}
case Deploy:
var allow bool
// check that sender may deploy contracts
allow, err := p.checkPolicy(from, Deploy)
if err != nil {
panic(err)
}
if !allow {
return SenderDisallowedDeploy
}
}

return Success
}

Expand Down Expand Up @@ -775,7 +807,7 @@ func (p *TxPool) validateTxs(txs *types.TxSlots, stateCache kvcache.CacheView) (

goodCount := 0
for i, txn := range txs.Txs {
reason := p.validateTx(txn, txs.IsLocal[i], stateCache)
reason := p.validateTx(txn, txs.IsLocal[i], stateCache, txs.Senders.AddressAt(i))
if reason == Success {
goodCount++
// Success here means no DiscardReason yet, so leave it NotSet
Expand Down Expand Up @@ -1535,7 +1567,7 @@ func (p *TxPool) fromDB(ctx context.Context, tx kv.Tx, coreTx kv.Tx) error {

isLocalTx := p.isLocalLRU.Contains(string(k))

if reason := p.validateTx(txn, isLocalTx, cacheView); reason != NotSet && reason != Success {
if reason := p.validateTx(txn, isLocalTx, cacheView, addr); reason != NotSet && reason != Success {
return nil
}
txs.Resize(uint(i + 1))
Expand Down
12 changes: 11 additions & 1 deletion zk/txpool/txpooluitl/all_components.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@ func AllComponents(ctx context.Context, cfg txpoolcfg.Config, ethCfg *ethconfig.
return nil, nil, nil, nil, nil, err
}

aclDB, err := mdbx.NewMDBX(log.New()).Label(txpool.ACLDB).Path(cfg.DBDir).
WithTableCfg(func(defaultBuckets kv.TableCfg) kv.TableCfg { return txpool.ACLTablesCfg }).
Flags(func(f uint) uint { return f ^ mdbx2.Durable | mdbx2.SafeNoSync }).
GrowthStep(16 * datasize.MB).
SyncPeriod(30 * time.Second).
Open(ctx)
if err != nil {
return nil, nil, nil, nil, nil, err
}

chainConfig, _, err := SaveChainConfigIfNeed(ctx, chainDB, txPoolDB, true)
if err != nil {
return nil, nil, nil, nil, nil, err
Expand All @@ -124,7 +134,7 @@ func AllComponents(ctx context.Context, cfg txpoolcfg.Config, ethCfg *ethconfig.
shanghaiTime = cfg.OverrideShanghaiTime
}

txPool, err := txpool.New(newTxs, chainDB, cfg, ethCfg, cache, *chainID, shanghaiTime, chainConfig.LondonBlock)
txPool, err := txpool.New(newTxs, chainDB, cfg, ethCfg, cache, *chainID, shanghaiTime, chainConfig.LondonBlock, aclDB)
if err != nil {
return nil, nil, nil, nil, nil, err
}
Expand Down

0 comments on commit ca6db9e

Please sign in to comment.