Skip to content

Commit 6f61b14

Browse files
Warp preparation (#573)
* Add warp precompile preparation * Update hash slice packing * Remove unnecessary local var * Add VM type assertion * Enable Warp API by default
1 parent 8f8ae38 commit 6f61b14

File tree

16 files changed

+73
-61
lines changed

16 files changed

+73
-61
lines changed

accounts/abi/bind/precompilebind/precompile_module_template.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const ConfigKey = "{{decapitalise .Contract.Type}}Config"
2828
2929
// ContractAddress is the defined address of the precompile contract.
3030
// This should be unique across all precompile contracts.
31-
// See params/precompile_modules.go for registered precompile contracts and more information.
31+
// See precompile/registry/registry.go for registered precompile contracts and more information.
3232
var ContractAddress = common.HexToAddress("{ASUITABLEHEXADDRESS}") // SET A SUITABLE HEX ADDRESS HERE
3333
3434
// Module is the precompile module. It is used to register the precompile contract.

core/predicate_check.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
package core
55

66
import (
7-
"errors"
87
"fmt"
98

109
"github.com/ava-labs/subnet-evm/core/types"
@@ -14,8 +13,6 @@ import (
1413
"github.com/ethereum/go-ethereum/common"
1514
)
1615

17-
var errNilProposerVMBlockCtxWithProposerPredicate = errors.New("engine cannot specify nil ProposerVM block context with non-empty proposer predicates")
18-
1916
// CheckPredicates checks that all precompile predicates are satisfied within the current [predicateContext] for [tx]
2017
func CheckPredicates(rules params.Rules, predicateContext *precompileconfig.ProposerPredicateContext, tx *types.Transaction) error {
2118
if err := checkPrecompilePredicates(rules, &predicateContext.PrecompilePredicateContext, tx); err != nil {
@@ -43,7 +40,8 @@ func checkPrecompilePredicates(rules params.Rules, predicateContext *precompilec
4340
return fmt.Errorf("predicate %s failed verification for tx %s: specified %s in access list multiple times", address, tx.Hash(), address)
4441
}
4542
precompileAddressChecks[address] = struct{}{}
46-
if err := predicater.VerifyPredicate(predicateContext, utils.HashSliceToBytes(accessTuple.StorageKeys)); err != nil {
43+
predicateBytes := utils.HashSliceToBytes(accessTuple.StorageKeys)
44+
if err := predicater.VerifyPredicate(predicateContext, predicateBytes); err != nil {
4745
return fmt.Errorf("predicate %s failed verification for tx %s: %w", address, tx.Hash(), err)
4846
}
4947
}
@@ -56,10 +54,6 @@ func checkProposerPrecompilePredicates(rules params.Rules, predicateContext *pre
5654
if len(rules.ProposerPredicates) == 0 {
5755
return nil
5856
}
59-
// If a proposer predicate is specified, reuqire that the ProposerVMBlockCtx is non-nil.
60-
if predicateContext.ProposerVMBlockCtx == nil {
61-
return errNilProposerVMBlockCtxWithProposerPredicate
62-
}
6357
precompilePredicates := rules.ProposerPredicates
6458
// Track addresses that we've performed a predicate check for
6559
precompileAddressChecks := make(map[common.Address]struct{})
@@ -74,7 +68,8 @@ func checkProposerPrecompilePredicates(rules params.Rules, predicateContext *pre
7468
return fmt.Errorf("predicate %s failed verification for tx %s: specified %s in access list multiple times", address, tx.Hash(), address)
7569
}
7670
precompileAddressChecks[address] = struct{}{}
77-
if err := predicater.VerifyPredicate(predicateContext, utils.HashSliceToBytes(accessTuple.StorageKeys)); err != nil {
71+
predicateBytes := utils.HashSliceToBytes(accessTuple.StorageKeys)
72+
if err := predicater.VerifyPredicate(predicateContext, predicateBytes); err != nil {
7873
return fmt.Errorf("predicate %s failed verification for tx %s: %w", address, tx.Hash(), err)
7974
}
8075
}

core/predicate_check_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,10 @@ func TestCheckPredicate(t *testing.T) {
148148
}),
149149
expectedErr: fmt.Errorf("unexpected bytes: 0x%x", common.Hash{2}.Bytes()),
150150
},
151-
"proposer predicate with empty proposer block ctx": {
151+
"proposer predicate with empty proposer block ctx passes": {
152152
address: common.HexToAddress("0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"),
153153
proposerPredicater: &mockProposerPredicater{predicateFunc: func(_ *precompileconfig.ProposerPredicateContext, b []byte) error { return nil }},
154154
emptyProposerBlockCtx: true,
155-
expectedErr: errNilProposerVMBlockCtxWithProposerPredicate,
156155
},
157156
} {
158157
test := test

miner/worker.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ func (w *worker) handleResult(env *environment, block *types.Block, createdAt ti
368368
logs = append(logs, receipt.Logs...)
369369
}
370370

371-
log.Info("Commit new mining work", "number", block.Number(), "hash", hash, "uncles", 0, "txs", env.tcount,
371+
log.Info("Commit new mining work", "number", block.Number(), "hash", hash, "timestamp", block.Time(), "uncles", 0, "txs", env.tcount,
372372
"gas", block.GasUsed(), "fees", totalFees(block, receipts), "elapsed", common.PrettyDuration(time.Since(env.start)))
373373

374374
// Note: the miner no longer emits a NewMinedBlock event. Instead the caller
@@ -409,7 +409,7 @@ func (w *worker) enforcePredicates(
409409
) map[common.Address]types.Transactions {
410410
// Short circuit early if there are no precompile predicates to verify and return the
411411
// unmodified pending transactions.
412-
if len(rules.PredicatePrecompiles) == 0 {
412+
if !rules.PredicatesExist() {
413413
return pending
414414
}
415415
result := make(map[common.Address]types.Transactions, len(pending))

params/precompile_upgrade.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ type PrecompileUpgrade struct {
2727

2828
// UnmarshalJSON unmarshals the json into the correct precompile config type
2929
// based on the key. Keys are defined in each precompile module, and registered in
30-
// params/precompile_modules.go.
3130
// precompile/registry/registry.go.
3231
// Ex: {"feeManagerConfig": {...}} where "feeManagerConfig" is the key
3332
func (u *PrecompileUpgrade) UnmarshalJSON(data []byte) error {

plugin/evm/block.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ func (b *Block) Accept(context.Context) error {
8989
// contract.Accepter
9090
// This function assumes that the Accept function will ONLY operate on state maintained in the VM's versiondb.
9191
// This ensures that any DB operations are performed atomically with marking the block as accepted.
92-
// Passes in sharedMemoryWriter to accumulate any requests from shared memory to commit on block accept.
9392
func (b *Block) handlePrecompileAccept(sharedMemoryWriter *sharedMemoryWriter) error {
9493
rules := b.vm.chainConfig.AvalancheRules(b.ethBlock.Number(), b.ethBlock.Timestamp())
9594
// Short circuit early if there are no precompile accepters to execute
@@ -113,6 +112,7 @@ func (b *Block) handlePrecompileAccept(sharedMemoryWriter *sharedMemoryWriter) e
113112
acceptCtx := &precompileconfig.AcceptContext{
114113
SnowCtx: b.vm.ctx,
115114
SharedMemory: sharedMemoryWriter,
115+
Warp: b.vm.warpBackend,
116116
}
117117
if err := accepter.Accept(acceptCtx, log.TxHash, txIndex, log.Topics, log.Data); err != nil {
118118
return err

plugin/evm/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const (
4747
defaultPopulateMissingTriesParallelism = 1024
4848
defaultStateSyncServerTrieCache = 64 // MB
4949
defaultAcceptedCacheSize = 32 // blocks
50+
defaultWarpAPIEnabled = true
5051

5152
// defaultStateSyncMinBlocks is the minimum number of blocks the blockchain
5253
// should be ahead of local last accepted to perform state sync.
@@ -224,6 +225,7 @@ func (c *Config) SetDefaults() {
224225
c.RPCGasCap = defaultRpcGasCap
225226
c.RPCTxFeeCap = defaultRpcTxFeeCap
226227
c.MetricsExpensiveEnabled = defaultMetricsExpensiveEnabled
228+
c.WarpAPIEnabled = defaultWarpAPIEnabled
227229

228230
c.TxPoolJournal = core.DefaultTxPoolConfig.Journal
229231
c.TxPoolRejournal = Duration{core.DefaultTxPoolConfig.Rejournal}

plugin/evm/vm.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ import (
7777
)
7878

7979
var (
80-
_ block.ChainVM = &VM{}
81-
_ block.HeightIndexedChainVM = &VM{}
80+
_ block.ChainVM = &VM{}
81+
_ block.HeightIndexedChainVM = &VM{}
82+
_ block.BuildBlockWithContextChainVM = &VM{}
8283
)
8384

8485
const (

precompile/precompileconfig/config.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/ava-labs/avalanchego/ids"
1212
"github.com/ava-labs/avalanchego/snow"
1313
"github.com/ava-labs/avalanchego/snow/engine/snowman/block"
14+
"github.com/ava-labs/avalanchego/vms/platformvm/warp"
1415
"github.com/ethereum/go-ethereum/common"
1516
)
1617

@@ -76,10 +77,15 @@ type SharedMemoryWriter interface {
7677
AddSharedMemoryRequests(chainID ids.ID, requests *atomic.Requests)
7778
}
7879

80+
type WarpMessageWriter interface {
81+
AddMessage(unsignedMessage *warp.UnsignedMessage) error
82+
}
83+
7984
// AcceptContext defines the context passed in to a precompileconfig's Accepter
8085
type AcceptContext struct {
8186
SnowCtx *snow.Context
8287
SharedMemory SharedMemoryWriter
88+
Warp WarpMessageWriter
8389
}
8490

8591
// Accepter is an optional interface for StatefulPrecompiledContracts to implement.

utils/bytes.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,26 @@ func IncrOne(bytes []byte) {
1919
}
2020
}
2121

22-
// HashSliceToBytes serializes a []common.Hash into a []byte
22+
// HashSliceToBytes serializes a []common.Hash into a tightly packed byte array.
2323
func HashSliceToBytes(hashes []common.Hash) []byte {
2424
bytes := make([]byte, common.HashLength*len(hashes))
2525
for i, hash := range hashes {
2626
copy(bytes[i*common.HashLength:], hash[:])
2727
}
2828
return bytes
2929
}
30+
31+
// BytesToHashSlice packs [b] into a slice of hash values with zero padding
32+
// to the right if the length of b is not a multiple of 32.
33+
func BytesToHashSlice(b []byte) []common.Hash {
34+
var (
35+
numHashes = (len(b) + 31) / 32
36+
hashes = make([]common.Hash, numHashes)
37+
)
38+
39+
for i := range hashes {
40+
start := i * common.HashLength
41+
copy(hashes[i][:], b[start:])
42+
}
43+
return hashes
44+
}

0 commit comments

Comments
 (0)