Skip to content

Commit 1e749f6

Browse files
sync: coreth PR #1166: refactor predication verification logic (#1749)
Signed-off-by: Jonathan Oppenheimer <[email protected]> Co-authored-by: Stephen Buttolph <[email protected]>
1 parent 4e5b628 commit 1e749f6

File tree

4 files changed

+323
-403
lines changed

4 files changed

+323
-403
lines changed

core/predicate_check.go

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,50 +18,90 @@ import (
1818

1919
var ErrMissingPredicateContext = errors.New("missing predicate context")
2020

21-
// CheckPredicates verifies the predicates of [tx] and returns the result. Returning an error invalidates the block.
22-
func CheckPredicates(rules params.Rules, predicateContext *precompileconfig.PredicateContext, tx *types.Transaction) (predicate.PrecompileResults, error) {
23-
// Check that the transaction can cover its IntrinsicGas (including the gas required by the predicate) before
24-
// verifying the predicate.
25-
intrinsicGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, rules)
21+
// CheckBlockPredicates verifies the predicates of a block of transactions and
22+
// returns the results.
23+
//
24+
// Returning an error invalidates the block.
25+
func CheckBlockPredicates(
26+
rules params.Rules,
27+
predicateContext *precompileconfig.PredicateContext,
28+
txs []*types.Transaction,
29+
) (predicate.BlockResults, error) {
30+
var results predicate.BlockResults
31+
// TODO: Calculate tx predicates concurrently.
32+
for _, tx := range txs {
33+
txResults, err := CheckTxPredicates(rules, predicateContext, tx)
34+
if err != nil {
35+
return nil, err
36+
}
37+
results.Set(tx.Hash(), txResults)
38+
}
39+
return results, nil
40+
}
41+
42+
// CheckTxPredicates verifies the predicates of a transaction and returns the
43+
// results.
44+
//
45+
// Returning an error invalidates the transaction.
46+
func CheckTxPredicates(
47+
rules params.Rules,
48+
predicateContext *precompileconfig.PredicateContext,
49+
tx *types.Transaction,
50+
) (predicate.PrecompileResults, error) {
51+
// Check that the transaction can cover its IntrinsicGas, including the gas
52+
// required by the predicate, before verifying the predicate.
53+
accessList := tx.AccessList()
54+
intrinsicGas, err := IntrinsicGas(tx.Data(), accessList, tx.To() == nil, rules)
2655
if err != nil {
2756
return nil, err
2857
}
29-
if tx.Gas() < intrinsicGas {
30-
return nil, fmt.Errorf("%w for predicate verification (%d) < intrinsic gas (%d)", ErrIntrinsicGas, tx.Gas(), intrinsicGas)
58+
if gas := tx.Gas(); gas < intrinsicGas {
59+
return nil, fmt.Errorf("%w for predicate verification (%d) < intrinsic gas (%d)",
60+
ErrIntrinsicGas,
61+
gas,
62+
intrinsicGas,
63+
)
3164
}
3265

3366
rulesExtra := params.GetRulesExtra(rules)
34-
predicateResults := make(predicate.PrecompileResults)
3567
// Short circuit early if there are no precompile predicates to verify
3668
if !rulesExtra.PredicatersExist() {
37-
return predicateResults, nil
69+
return nil, nil
3870
}
3971

4072
// Prepare the predicate storage slots from the transaction's access list
41-
predicateArguments := predicate.FromAccessList(rulesExtra, tx.AccessList())
73+
predicateArguments := predicate.FromAccessList(rulesExtra, accessList)
4274

43-
// If there are no predicates to verify, return early and skip requiring the proposervm block
44-
// context to be populated.
75+
// If there are no predicates to verify, return early and skip requiring the
76+
// proposervm block context to be populated.
4577
if len(predicateArguments) == 0 {
46-
return predicateResults, nil
78+
return nil, nil
4779
}
4880

4981
if predicateContext == nil || predicateContext.ProposerVMBlockCtx == nil {
5082
return nil, ErrMissingPredicateContext
5183
}
5284

85+
var (
86+
txHash = tx.Hash()
87+
predicateResults = make(predicate.PrecompileResults, len(predicateArguments))
88+
)
5389
for address, predicates := range predicateArguments {
54-
// Since [address] is only added to [predicateArguments] when there's a valid predicate in the ruleset
55-
// there's no need to check if the predicate exists here.
56-
rules := params.GetRulesExtra(rules)
57-
predicaterContract := rules.Predicaters[address]
90+
// Since address is only added to predicateArguments when there's a
91+
// valid predicate in the ruleset there's no need to check if the
92+
// predicate exists here.
93+
predicaterContract := rulesExtra.Predicaters[address]
5894
bitset := set.NewBits()
5995
for i, predicate := range predicates {
6096
if err := predicaterContract.VerifyPredicate(predicateContext, predicate); err != nil {
6197
bitset.Add(i)
6298
}
6399
}
64-
log.Debug("predicate verify", "tx", tx.Hash(), "address", address, "res", bitset.Bytes())
100+
log.Debug("predicate verify",
101+
"tx", txHash,
102+
"address", address,
103+
"res", bitset.String(),
104+
)
65105
predicateResults[address] = bitset
66106
}
67107
return predicateResults, nil

0 commit comments

Comments
 (0)