aboutsummaryrefslogtreecommitdiff
path: root/plugin/evm/vm.go
diff options
context:
space:
mode:
Diffstat (limited to 'plugin/evm/vm.go')
-rw-r--r--plugin/evm/vm.go150
1 files changed, 101 insertions, 49 deletions
diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go
index 1f26101..6a3fcd5 100644
--- a/plugin/evm/vm.go
+++ b/plugin/evm/vm.go
@@ -23,31 +23,34 @@ import (
"github.com/ava-labs/coreth/params"
"github.com/ava-labs/go-ethereum/common"
- ethcrypto "github.com/ava-labs/go-ethereum/crypto"
"github.com/ava-labs/go-ethereum/rlp"
"github.com/ava-labs/go-ethereum/rpc"
+
+ ethcrypto "github.com/ava-labs/go-ethereum/crypto"
+
geckorpc "github.com/gorilla/rpc/v2"
- "github.com/ava-labs/gecko/api/admin"
- "github.com/ava-labs/gecko/cache"
- "github.com/ava-labs/gecko/database"
- "github.com/ava-labs/gecko/ids"
- "github.com/ava-labs/gecko/snow"
- "github.com/ava-labs/gecko/snow/choices"
- "github.com/ava-labs/gecko/snow/consensus/snowman"
- "github.com/ava-labs/gecko/utils/codec"
- "github.com/ava-labs/gecko/utils/constants"
- "github.com/ava-labs/gecko/utils/crypto"
- "github.com/ava-labs/gecko/utils/formatting"
- geckojson "github.com/ava-labs/gecko/utils/json"
- "github.com/ava-labs/gecko/utils/logging"
- "github.com/ava-labs/gecko/utils/timer"
- "github.com/ava-labs/gecko/utils/units"
- "github.com/ava-labs/gecko/utils/wrappers"
- "github.com/ava-labs/gecko/vms/components/avax"
- "github.com/ava-labs/gecko/vms/secp256k1fx"
-
- commonEng "github.com/ava-labs/gecko/snow/engine/common"
+ "github.com/ava-labs/avalanche-go/api/admin"
+ "github.com/ava-labs/avalanche-go/cache"
+ "github.com/ava-labs/avalanche-go/database"
+ "github.com/ava-labs/avalanche-go/database/prefixdb"
+ "github.com/ava-labs/avalanche-go/ids"
+ "github.com/ava-labs/avalanche-go/snow"
+ "github.com/ava-labs/avalanche-go/snow/choices"
+ "github.com/ava-labs/avalanche-go/snow/consensus/snowman"
+ "github.com/ava-labs/avalanche-go/utils/codec"
+ "github.com/ava-labs/avalanche-go/utils/constants"
+ "github.com/ava-labs/avalanche-go/utils/crypto"
+ "github.com/ava-labs/avalanche-go/utils/formatting"
+ "github.com/ava-labs/avalanche-go/utils/logging"
+ "github.com/ava-labs/avalanche-go/utils/timer"
+ "github.com/ava-labs/avalanche-go/utils/units"
+ "github.com/ava-labs/avalanche-go/utils/wrappers"
+ "github.com/ava-labs/avalanche-go/vms/components/avax"
+ "github.com/ava-labs/avalanche-go/vms/secp256k1fx"
+
+ commonEng "github.com/ava-labs/avalanche-go/snow/engine/common"
+ geckojson "github.com/ava-labs/avalanche-go/utils/json"
)
var (
@@ -60,6 +63,7 @@ var (
const (
lastAcceptedKey = "snowman_lastAccepted"
+ acceptedPrefix = "snowman_accepted"
)
const (
@@ -67,7 +71,7 @@ const (
maxBlockTime = 1000 * time.Millisecond
batchSize = 250
maxUTXOsToFetch = 1024
- blockCacheSize = 1 << 17 // 131072
+ blockCacheSize = 1 << 10 // 1024
)
const (
@@ -157,6 +161,8 @@ type VM struct {
networkChan chan<- commonEng.Message
newTxPoolHeadChan chan core.NewTxPoolHeadEvent
+ acceptedDB database.Database
+
txPoolStabilizedHead common.Hash
txPoolStabilizedOk chan struct{}
txPoolStabilizedLock sync.Mutex
@@ -229,6 +235,8 @@ func (vm *VM) Initialize(
return err
}
+ vm.acceptedDB = prefixdb.New([]byte(acceptedPrefix), db)
+
vm.chainID = g.Config.ChainID
vm.txFee = txFee
@@ -598,40 +606,56 @@ func (vm *VM) tryBlockGen() error {
func (vm *VM) getCachedStatus(blockID ids.ID) choices.Status {
vm.metalock.Lock()
defer vm.metalock.Unlock()
- status := choices.Processing
if statusIntf, ok := vm.blockStatusCache.Get(blockID); ok {
- status = statusIntf.(choices.Status)
- } else {
- wrappedBlk := vm.getBlock(blockID)
- if wrappedBlk == nil {
- return choices.Unknown
+ return statusIntf.(choices.Status)
+ }
+
+ wrappedBlk := vm.getBlock(blockID)
+ if wrappedBlk == nil {
+ return choices.Unknown
+ }
+ blk := wrappedBlk.ethBlock
+
+ heightKey := blk.Number().Bytes()
+ acceptedIDBytes, err := vm.acceptedDB.Get(heightKey)
+ if err == nil {
+ if acceptedID, err := ids.ToID(acceptedIDBytes); err != nil {
+ vm.ctx.Log.Error("snowman-eth: acceptedID bytes didn't match expected value: %s", err)
+ } else {
+ if acceptedID.Equals(blockID) {
+ vm.blockStatusCache.Put(blockID, choices.Accepted)
+ return choices.Accepted
+ }
+ vm.blockStatusCache.Put(blockID, choices.Rejected)
+ return choices.Rejected
}
- blk := wrappedBlk.ethBlock
- acceptedBlk := vm.lastAccepted.ethBlock
-
- // TODO: There must be a better way of doing this.
- // Traverse up the chain from the lower block until the indices match
- highBlock := blk
- lowBlock := acceptedBlk
- if highBlock.Number().Cmp(lowBlock.Number()) < 0 {
- highBlock, lowBlock = lowBlock, highBlock
+ }
+
+ status := vm.getUncachedStatus(blk)
+ if status == choices.Accepted {
+ err := vm.acceptedDB.Put(heightKey, blockID.Bytes())
+ if err != nil {
+ vm.ctx.Log.Error("snowman-eth: failed to write back acceptedID bytes: %s", err)
}
- for highBlock.Number().Cmp(lowBlock.Number()) > 0 {
- parentBlock := vm.getBlock(ids.NewID(highBlock.ParentHash()))
- if parentBlock == nil {
- vm.blockStatusCache.Put(blockID, choices.Processing)
- return choices.Processing
+
+ tempBlock := wrappedBlk
+ for tempBlock.ethBlock != nil {
+ parentID := ids.NewID(tempBlock.ethBlock.ParentHash())
+ tempBlock = vm.getBlock(parentID)
+ if tempBlock == nil || tempBlock.ethBlock == nil {
+ break
}
- highBlock = parentBlock.ethBlock
- }
- if highBlock.Hash() == lowBlock.Hash() { // on the same branch
- if blk.Number().Cmp(acceptedBlk.Number()) <= 0 {
- status = choices.Accepted
+ heightKey := tempBlock.ethBlock.Number().Bytes()
+ _, err := vm.acceptedDB.Get(heightKey)
+ if err == nil {
+ break
+ }
+
+ if err := vm.acceptedDB.Put(heightKey, parentID.Bytes()); err != nil {
+ vm.ctx.Log.Error("snowman-eth: failed to write back acceptedID bytes: %s", err)
}
- } else { // on different branches
- status = choices.Rejected
}
}
@@ -639,6 +663,34 @@ func (vm *VM) getCachedStatus(blockID ids.ID) choices.Status {
return status
}
+func (vm *VM) getUncachedStatus(blk *types.Block) choices.Status {
+ acceptedBlk := vm.lastAccepted.ethBlock
+
+ // TODO: There must be a better way of doing this.
+ // Traverse up the chain from the lower block until the indices match
+ highBlock := blk
+ lowBlock := acceptedBlk
+ if highBlock.Number().Cmp(lowBlock.Number()) < 0 {
+ highBlock, lowBlock = lowBlock, highBlock
+ }
+ for highBlock.Number().Cmp(lowBlock.Number()) > 0 {
+ parentBlock := vm.getBlock(ids.NewID(highBlock.ParentHash()))
+ if parentBlock == nil {
+ return choices.Processing
+ }
+ highBlock = parentBlock.ethBlock
+ }
+
+ if highBlock.Hash() != lowBlock.Hash() { // on different branches
+ return choices.Rejected
+ }
+ // on the same branch
+ if blk.Number().Cmp(acceptedBlk.Number()) <= 0 {
+ return choices.Accepted
+ }
+ return choices.Processing
+}
+
func (vm *VM) getBlock(id ids.ID) *Block {
if blockIntf, ok := vm.blockCache.Get(id); ok {
return blockIntf.(*Block)