mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-09 06:24:27 +00:00
all: remove uses of untyped golang-lru
This commit is contained in:
parent
7491a7ba74
commit
82ff8c19a0
29 changed files with 226 additions and 320 deletions
32
XDCx/XDCx.go
32
XDCx/XDCx.go
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCxDAO"
|
"github.com/XinFinOrg/XDPoSChain/XDCxDAO"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/prque"
|
"github.com/XinFinOrg/XDPoSChain/common/prque"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||||
|
|
@ -17,7 +18,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/p2p"
|
"github.com/XinFinOrg/XDPoSChain/p2p"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rpc"
|
"github.com/XinFinOrg/XDPoSChain/rpc"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
"golang.org/x/sync/syncmap"
|
"golang.org/x/sync/syncmap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -59,8 +59,8 @@ type XDCX struct {
|
||||||
|
|
||||||
sdkNode bool
|
sdkNode bool
|
||||||
settings syncmap.Map // holds configuration settings that can be dynamically changed
|
settings syncmap.Map // holds configuration settings that can be dynamically changed
|
||||||
tokenDecimalCache *lru.Cache
|
tokenDecimalCache *lru.Cache[common.Address, *big.Int]
|
||||||
orderCache *lru.Cache
|
orderCache *lru.Cache[common.Hash, map[common.Hash]tradingstate.OrderHistoryItem]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (XDCx *XDCX) Protocols() []p2p.Protocol {
|
func (XDCx *XDCX) Protocols() []p2p.Protocol {
|
||||||
|
|
@ -94,19 +94,11 @@ func NewMongoDBEngine(cfg *Config) *XDCxDAO.MongoDatabase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg *Config) *XDCX {
|
func New(cfg *Config) *XDCX {
|
||||||
tokenDecimalCache, err := lru.New(defaultCacheLimit)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("[XDCx-New] fail to create new lru for token decimal", "error", err)
|
|
||||||
}
|
|
||||||
orderCache, err := lru.New(tradingstate.OrderCacheLimit)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("[XDCx-New] fail to create new lru for order", "error", err)
|
|
||||||
}
|
|
||||||
XDCX := &XDCX{
|
XDCX := &XDCX{
|
||||||
orderNonce: make(map[common.Address]*big.Int),
|
orderNonce: make(map[common.Address]*big.Int),
|
||||||
Triegc: prque.New(nil),
|
Triegc: prque.New(nil),
|
||||||
tokenDecimalCache: tokenDecimalCache,
|
tokenDecimalCache: lru.NewCache[common.Address, *big.Int](defaultCacheLimit),
|
||||||
orderCache: orderCache,
|
orderCache: lru.NewCache[common.Hash, map[common.Hash]tradingstate.OrderHistoryItem](tradingstate.OrderCacheLimit),
|
||||||
}
|
}
|
||||||
|
|
||||||
// default DBEngine: levelDB
|
// default DBEngine: levelDB
|
||||||
|
|
@ -607,12 +599,9 @@ func (XDCx *XDCX) GetTradingStateRoot(block *types.Block, author common.Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (XDCx *XDCX) UpdateOrderCache(baseToken, quoteToken common.Address, orderHash common.Hash, txhash common.Hash, lastState tradingstate.OrderHistoryItem) {
|
func (XDCx *XDCX) UpdateOrderCache(baseToken, quoteToken common.Address, orderHash common.Hash, txhash common.Hash, lastState tradingstate.OrderHistoryItem) {
|
||||||
var orderCacheAtTxHash map[common.Hash]tradingstate.OrderHistoryItem
|
orderCacheAtTxHash, ok := XDCx.orderCache.Get(txhash)
|
||||||
c, ok := XDCx.orderCache.Get(txhash)
|
if !ok || orderCacheAtTxHash == nil {
|
||||||
if !ok || c == nil {
|
|
||||||
orderCacheAtTxHash = make(map[common.Hash]tradingstate.OrderHistoryItem)
|
orderCacheAtTxHash = make(map[common.Hash]tradingstate.OrderHistoryItem)
|
||||||
} else {
|
|
||||||
orderCacheAtTxHash = c.(map[common.Hash]tradingstate.OrderHistoryItem)
|
|
||||||
}
|
}
|
||||||
orderKey := tradingstate.GetOrderHistoryKey(baseToken, quoteToken, orderHash)
|
orderKey := tradingstate.GetOrderHistoryKey(baseToken, quoteToken, orderHash)
|
||||||
_, ok = orderCacheAtTxHash[orderKey]
|
_, ok = orderCacheAtTxHash[orderKey]
|
||||||
|
|
@ -629,16 +618,15 @@ func (XDCx *XDCX) RollbackReorgTxMatch(txhash common.Hash) error {
|
||||||
items := db.GetListItemByTxHash(txhash, &tradingstate.OrderItem{})
|
items := db.GetListItemByTxHash(txhash, &tradingstate.OrderItem{})
|
||||||
if items != nil {
|
if items != nil {
|
||||||
for _, order := range items.([]*tradingstate.OrderItem) {
|
for _, order := range items.([]*tradingstate.OrderItem) {
|
||||||
c, ok := XDCx.orderCache.Get(txhash)
|
orderCacheAtTxHash, ok := XDCx.orderCache.Get(txhash)
|
||||||
log.Debug("XDCx reorg: rollback order", "txhash", txhash.Hex(), "order", tradingstate.ToJSON(order), "orderHistoryItem", c)
|
log.Debug("XDCx reorg: rollback order", "txhash", txhash.Hex(), "order", tradingstate.ToJSON(order), "orderHistoryItem", orderCacheAtTxHash)
|
||||||
if !ok {
|
if !ok || orderCacheAtTxHash == nil {
|
||||||
log.Debug("XDCx reorg: remove order due to no orderCache", "order", tradingstate.ToJSON(order))
|
log.Debug("XDCx reorg: remove order due to no orderCache", "order", tradingstate.ToJSON(order))
|
||||||
if err := db.DeleteObject(order.Hash, &tradingstate.OrderItem{}); err != nil {
|
if err := db.DeleteObject(order.Hash, &tradingstate.OrderItem{}); err != nil {
|
||||||
log.Crit("SDKNode: failed to remove reorg order", "err", err.Error(), "order", tradingstate.ToJSON(order))
|
log.Crit("SDKNode: failed to remove reorg order", "err", err.Error(), "order", tradingstate.ToJSON(order))
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
orderCacheAtTxHash := c.(map[common.Hash]tradingstate.OrderHistoryItem)
|
|
||||||
orderHistoryItem := orderCacheAtTxHash[tradingstate.GetOrderHistoryKey(order.BaseToken, order.QuoteToken, order.Hash)]
|
orderHistoryItem := orderCacheAtTxHash[tradingstate.GetOrderHistoryKey(order.BaseToken, order.QuoteToken, order.Hash)]
|
||||||
if (orderHistoryItem == tradingstate.OrderHistoryItem{}) {
|
if (orderHistoryItem == tradingstate.OrderHistoryItem{}) {
|
||||||
log.Debug("XDCx reorg: remove order due to empty orderHistory", "order", tradingstate.ToJSON(order))
|
log.Debug("XDCx reorg: remove order due to empty orderHistory", "order", tradingstate.ToJSON(order))
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,14 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/core"
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain"
|
"github.com/XinFinOrg/XDPoSChain"
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi"
|
"github.com/XinFinOrg/XDPoSChain/accounts/abi"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/contracts/XDCx/contract"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/core"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetTokenAbi return token abi
|
// GetTokenAbi return token abi
|
||||||
|
|
@ -45,8 +44,8 @@ func RunContract(chain consensus.ChainContext, statedb *state.StateDB, contractA
|
||||||
}
|
}
|
||||||
|
|
||||||
func (XDCx *XDCX) GetTokenDecimal(chain consensus.ChainContext, statedb *state.StateDB, tokenAddr common.Address) (*big.Int, error) {
|
func (XDCx *XDCX) GetTokenDecimal(chain consensus.ChainContext, statedb *state.StateDB, tokenAddr common.Address) (*big.Int, error) {
|
||||||
if tokenDecimal, ok := XDCx.tokenDecimalCache.Get(tokenAddr); ok {
|
if tokenDecimal, ok := XDCx.tokenDecimalCache.Get(tokenAddr); ok && tokenDecimal != nil {
|
||||||
return tokenDecimal.(*big.Int), nil
|
return tokenDecimal, nil
|
||||||
}
|
}
|
||||||
if tokenAddr == common.XDCNativeAddressBinary {
|
if tokenAddr == common.XDCNativeAddressBinary {
|
||||||
XDCx.tokenDecimalCache.Add(tokenAddr, common.BasePrice)
|
XDCx.tokenDecimalCache.Add(tokenAddr, common.BasePrice)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/trie"
|
"github.com/XinFinOrg/XDPoSChain/trie"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Trie cache generation limit after which to evic trie nodes from memory.
|
// Trie cache generation limit after which to evic trie nodes from memory.
|
||||||
|
|
@ -33,9 +32,6 @@ const (
|
||||||
// Number of past tries to keep. This value is chosen such that
|
// Number of past tries to keep. This value is chosen such that
|
||||||
// reasonable chain reorg depths will hit an existing trie.
|
// reasonable chain reorg depths will hit an existing trie.
|
||||||
maxPastTries = 12
|
maxPastTries = 12
|
||||||
|
|
||||||
// Number of codehash->size associations to keep.
|
|
||||||
codeSizeCacheSize = 100000
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Database wraps access to tries and contract code.
|
// Database wraps access to tries and contract code.
|
||||||
|
|
@ -79,18 +75,15 @@ type Trie interface {
|
||||||
// intermediate trie-node memory pool between the low level storage layer and the
|
// intermediate trie-node memory pool between the low level storage layer and the
|
||||||
// high level trie abstraction.
|
// high level trie abstraction.
|
||||||
func NewDatabase(db ethdb.Database) Database {
|
func NewDatabase(db ethdb.Database) Database {
|
||||||
csc, _ := lru.New(codeSizeCacheSize)
|
|
||||||
return &cachingDB{
|
return &cachingDB{
|
||||||
db: trie.NewDatabase(db),
|
db: trie.NewDatabase(db),
|
||||||
codeSizeCache: csc,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type cachingDB struct {
|
type cachingDB struct {
|
||||||
db *trie.Database
|
db *trie.Database
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
pastTries []*XDCXTrie
|
pastTries []*XDCXTrie
|
||||||
codeSizeCache *lru.Cache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenTrie opens the main account trie.
|
// OpenTrie opens the main account trie.
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,8 @@ import (
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type BatchItem struct {
|
type BatchItem struct {
|
||||||
|
|
@ -21,7 +19,6 @@ type BatchItem struct {
|
||||||
type BatchDatabase struct {
|
type BatchDatabase struct {
|
||||||
db ethdb.Database
|
db ethdb.Database
|
||||||
emptyKey []byte
|
emptyKey []byte
|
||||||
cacheItems *lru.Cache // Cache for reading
|
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
cacheLimit int
|
cacheLimit int
|
||||||
Debug bool
|
Debug bool
|
||||||
|
|
@ -44,11 +41,8 @@ func NewBatchDatabaseWithEncode(datadir string, cacheLimit int) *BatchDatabase {
|
||||||
itemCacheLimit = cacheLimit
|
itemCacheLimit = cacheLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheItems, _ := lru.New(itemCacheLimit)
|
|
||||||
|
|
||||||
batchDB := &BatchDatabase{
|
batchDB := &BatchDatabase{
|
||||||
db: db,
|
db: db,
|
||||||
cacheItems: cacheItems,
|
|
||||||
emptyKey: EmptyKey(), // pre alloc for comparison
|
emptyKey: EmptyKey(), // pre alloc for comparison
|
||||||
cacheLimit: itemCacheLimit,
|
cacheLimit: itemCacheLimit,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,11 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
|
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/globalsign/mgo"
|
"github.com/globalsign/mgo"
|
||||||
"github.com/globalsign/mgo/bson"
|
"github.com/globalsign/mgo/bson"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -32,7 +32,7 @@ type MongoDatabase struct {
|
||||||
Session *mgo.Session
|
Session *mgo.Session
|
||||||
dbName string
|
dbName string
|
||||||
emptyKey []byte
|
emptyKey []byte
|
||||||
cacheItems *lru.Cache // Cache for reading
|
cacheItems *lru.Cache[string, interface{}] // Cache for reading
|
||||||
orderBulk *mgo.Bulk
|
orderBulk *mgo.Bulk
|
||||||
tradeBulk *mgo.Bulk
|
tradeBulk *mgo.Bulk
|
||||||
epochPriceBulk *mgo.Bulk
|
epochPriceBulk *mgo.Bulk
|
||||||
|
|
@ -64,12 +64,11 @@ func NewMongoDatabase(session *mgo.Session, dbName string, mongoURL string, repl
|
||||||
if cacheLimit > 0 {
|
if cacheLimit > 0 {
|
||||||
itemCacheLimit = cacheLimit
|
itemCacheLimit = cacheLimit
|
||||||
}
|
}
|
||||||
cacheItems, _ := lru.New(itemCacheLimit)
|
|
||||||
|
|
||||||
db := &MongoDatabase{
|
db := &MongoDatabase{
|
||||||
Session: session,
|
Session: session,
|
||||||
dbName: dbName,
|
dbName: dbName,
|
||||||
cacheItems: cacheItems,
|
cacheItems: lru.NewCache[string, interface{}](itemCacheLimit),
|
||||||
}
|
}
|
||||||
if err := db.EnsureIndexes(); err != nil {
|
if err := db.EnsureIndexes(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCxDAO"
|
"github.com/XinFinOrg/XDPoSChain/XDCxDAO"
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
|
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/prque"
|
"github.com/XinFinOrg/XDPoSChain/common/prque"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||||
|
|
@ -20,7 +21,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/p2p"
|
"github.com/XinFinOrg/XDPoSChain/p2p"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rpc"
|
"github.com/XinFinOrg/XDPoSChain/rpc"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -42,8 +42,8 @@ type Lending struct {
|
||||||
orderNonce map[common.Address]*big.Int
|
orderNonce map[common.Address]*big.Int
|
||||||
|
|
||||||
XDCx *XDCx.XDCX
|
XDCx *XDCx.XDCX
|
||||||
lendingItemHistory *lru.Cache
|
lendingItemHistory *lru.Cache[common.Hash, map[common.Hash]lendingstate.LendingItemHistoryItem]
|
||||||
lendingTradeHistory *lru.Cache
|
lendingTradeHistory *lru.Cache[common.Hash, map[common.Hash]lendingstate.LendingTradeHistoryItem]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Lending) Protocols() []p2p.Protocol {
|
func (l *Lending) Protocols() []p2p.Protocol {
|
||||||
|
|
@ -62,13 +62,11 @@ func (l *Lending) Stop() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(XDCx *XDCx.XDCX) *Lending {
|
func New(XDCx *XDCx.XDCX) *Lending {
|
||||||
itemCache, _ := lru.New(defaultCacheLimit)
|
|
||||||
lendingTradeCache, _ := lru.New(defaultCacheLimit)
|
|
||||||
lending := &Lending{
|
lending := &Lending{
|
||||||
orderNonce: make(map[common.Address]*big.Int),
|
orderNonce: make(map[common.Address]*big.Int),
|
||||||
Triegc: prque.New(nil),
|
Triegc: prque.New(nil),
|
||||||
lendingItemHistory: itemCache,
|
lendingItemHistory: lru.NewCache[common.Hash, map[common.Hash]lendingstate.LendingItemHistoryItem](defaultCacheLimit),
|
||||||
lendingTradeHistory: lendingTradeCache,
|
lendingTradeHistory: lru.NewCache[common.Hash, map[common.Hash]lendingstate.LendingTradeHistoryItem](defaultCacheLimit),
|
||||||
}
|
}
|
||||||
lending.StateCache = lendingstate.NewDatabase(XDCx.GetLevelDB())
|
lending.StateCache = lendingstate.NewDatabase(XDCx.GetLevelDB())
|
||||||
lending.XDCx = XDCx
|
lending.XDCx = XDCx
|
||||||
|
|
@ -705,12 +703,9 @@ func (l *Lending) GetLendingStateRoot(block *types.Block, author common.Address)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Lending) UpdateLendingItemCache(LendingToken, CollateralToken common.Address, hash common.Hash, txhash common.Hash, lastState lendingstate.LendingItemHistoryItem) {
|
func (l *Lending) UpdateLendingItemCache(LendingToken, CollateralToken common.Address, hash common.Hash, txhash common.Hash, lastState lendingstate.LendingItemHistoryItem) {
|
||||||
var lendingCacheAtTxHash map[common.Hash]lendingstate.LendingItemHistoryItem
|
lendingCacheAtTxHash, ok := l.lendingItemHistory.Get(txhash)
|
||||||
c, ok := l.lendingItemHistory.Get(txhash)
|
if !ok || lendingCacheAtTxHash == nil {
|
||||||
if !ok || c == nil {
|
|
||||||
lendingCacheAtTxHash = make(map[common.Hash]lendingstate.LendingItemHistoryItem)
|
lendingCacheAtTxHash = make(map[common.Hash]lendingstate.LendingItemHistoryItem)
|
||||||
} else {
|
|
||||||
lendingCacheAtTxHash = c.(map[common.Hash]lendingstate.LendingItemHistoryItem)
|
|
||||||
}
|
}
|
||||||
orderKey := lendingstate.GetLendingItemHistoryKey(LendingToken, CollateralToken, hash)
|
orderKey := lendingstate.GetLendingItemHistoryKey(LendingToken, CollateralToken, hash)
|
||||||
_, ok = lendingCacheAtTxHash[orderKey]
|
_, ok = lendingCacheAtTxHash[orderKey]
|
||||||
|
|
@ -722,11 +717,9 @@ func (l *Lending) UpdateLendingItemCache(LendingToken, CollateralToken common.Ad
|
||||||
|
|
||||||
func (l *Lending) UpdateLendingTradeCache(hash common.Hash, txhash common.Hash, lastState lendingstate.LendingTradeHistoryItem) {
|
func (l *Lending) UpdateLendingTradeCache(hash common.Hash, txhash common.Hash, lastState lendingstate.LendingTradeHistoryItem) {
|
||||||
var lendingCacheAtTxHash map[common.Hash]lendingstate.LendingTradeHistoryItem
|
var lendingCacheAtTxHash map[common.Hash]lendingstate.LendingTradeHistoryItem
|
||||||
c, ok := l.lendingTradeHistory.Get(txhash)
|
lendingCacheAtTxHash, ok := l.lendingTradeHistory.Get(txhash)
|
||||||
if !ok || c == nil {
|
if !ok || lendingCacheAtTxHash == nil {
|
||||||
lendingCacheAtTxHash = make(map[common.Hash]lendingstate.LendingTradeHistoryItem)
|
lendingCacheAtTxHash = make(map[common.Hash]lendingstate.LendingTradeHistoryItem)
|
||||||
} else {
|
|
||||||
lendingCacheAtTxHash = c.(map[common.Hash]lendingstate.LendingTradeHistoryItem)
|
|
||||||
}
|
}
|
||||||
_, ok = lendingCacheAtTxHash[hash]
|
_, ok = lendingCacheAtTxHash[hash]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -743,16 +736,15 @@ func (l *Lending) RollbackLendingData(txhash common.Hash) error {
|
||||||
items := db.GetListItemByTxHash(txhash, &lendingstate.LendingItem{})
|
items := db.GetListItemByTxHash(txhash, &lendingstate.LendingItem{})
|
||||||
if items != nil {
|
if items != nil {
|
||||||
for _, item := range items.([]*lendingstate.LendingItem) {
|
for _, item := range items.([]*lendingstate.LendingItem) {
|
||||||
c, ok := l.lendingItemHistory.Get(txhash)
|
cacheAtTxHash, ok := l.lendingItemHistory.Get(txhash)
|
||||||
log.Debug("XDCxlending reorg: rollback lendingItem", "txhash", txhash.Hex(), "item", lendingstate.ToJSON(item), "lendingItemHistory", c)
|
log.Debug("XDCxlending reorg: rollback lendingItem", "txhash", txhash.Hex(), "item", lendingstate.ToJSON(item), "lendingItemHistory", cacheAtTxHash)
|
||||||
if !ok {
|
if !ok || cacheAtTxHash == nil {
|
||||||
log.Debug("XDCxlending reorg: remove item due to no lendingItemHistory", "item", lendingstate.ToJSON(item))
|
log.Debug("XDCxlending reorg: remove item due to no lendingItemHistory", "item", lendingstate.ToJSON(item))
|
||||||
if err := db.DeleteObject(item.Hash, &lendingstate.LendingItem{}); err != nil {
|
if err := db.DeleteObject(item.Hash, &lendingstate.LendingItem{}); err != nil {
|
||||||
return fmt.Errorf("failed to remove reorg LendingItem. Err: %v . Item: %s", err.Error(), lendingstate.ToJSON(item))
|
return fmt.Errorf("failed to remove reorg LendingItem. Err: %v . Item: %s", err.Error(), lendingstate.ToJSON(item))
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cacheAtTxHash := c.(map[common.Hash]lendingstate.LendingItemHistoryItem)
|
|
||||||
lendingItemHistory := cacheAtTxHash[lendingstate.GetLendingItemHistoryKey(item.LendingToken, item.CollateralToken, item.Hash)]
|
lendingItemHistory := cacheAtTxHash[lendingstate.GetLendingItemHistoryKey(item.LendingToken, item.CollateralToken, item.Hash)]
|
||||||
if (lendingItemHistory == lendingstate.LendingItemHistoryItem{}) {
|
if (lendingItemHistory == lendingstate.LendingItemHistoryItem{}) {
|
||||||
log.Debug("XDCxlending reorg: remove item due to empty lendingItemHistory", "item", lendingstate.ToJSON(item))
|
log.Debug("XDCxlending reorg: remove item due to empty lendingItemHistory", "item", lendingstate.ToJSON(item))
|
||||||
|
|
@ -776,16 +768,15 @@ func (l *Lending) RollbackLendingData(txhash common.Hash) error {
|
||||||
items = db.GetListItemByTxHash(txhash, &lendingstate.LendingTrade{})
|
items = db.GetListItemByTxHash(txhash, &lendingstate.LendingTrade{})
|
||||||
if items != nil {
|
if items != nil {
|
||||||
for _, trade := range items.([]*lendingstate.LendingTrade) {
|
for _, trade := range items.([]*lendingstate.LendingTrade) {
|
||||||
c, ok := l.lendingTradeHistory.Get(txhash)
|
cacheAtTxHash, ok := l.lendingTradeHistory.Get(txhash)
|
||||||
log.Debug("XDCxlending reorg: rollback LendingTrade", "txhash", txhash.Hex(), "trade", lendingstate.ToJSON(trade), "LendingTradeHistory", c)
|
log.Debug("XDCxlending reorg: rollback LendingTrade", "txhash", txhash.Hex(), "trade", lendingstate.ToJSON(trade), "LendingTradeHistory", cacheAtTxHash)
|
||||||
if !ok {
|
if !ok || cacheAtTxHash == nil {
|
||||||
log.Debug("XDCxlending reorg: remove trade due to no LendingTradeHistory", "trade", lendingstate.ToJSON(trade))
|
log.Debug("XDCxlending reorg: remove trade due to no LendingTradeHistory", "trade", lendingstate.ToJSON(trade))
|
||||||
if err := db.DeleteObject(trade.Hash, &lendingstate.LendingTrade{}); err != nil {
|
if err := db.DeleteObject(trade.Hash, &lendingstate.LendingTrade{}); err != nil {
|
||||||
return fmt.Errorf("failed to remove reorg LendingTrade. Err: %v . Trade: %s", err.Error(), lendingstate.ToJSON(trade))
|
return fmt.Errorf("failed to remove reorg LendingTrade. Err: %v . Trade: %s", err.Error(), lendingstate.ToJSON(trade))
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cacheAtTxHash := c.(map[common.Hash]lendingstate.LendingTradeHistoryItem)
|
|
||||||
lendingTradeHistoryItem := cacheAtTxHash[trade.Hash]
|
lendingTradeHistoryItem := cacheAtTxHash[trade.Hash]
|
||||||
if (lendingTradeHistoryItem == lendingstate.LendingTradeHistoryItem{}) {
|
if (lendingTradeHistoryItem == lendingstate.LendingTradeHistoryItem{}) {
|
||||||
log.Debug("XDCxlending reorg: remove trade due to empty LendingTradeHistory", "trade", lendingstate.ToJSON(trade))
|
log.Debug("XDCxlending reorg: remove trade due to empty LendingTradeHistory", "trade", lendingstate.ToJSON(trade))
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/trie"
|
"github.com/XinFinOrg/XDPoSChain/trie"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Trie cache generation limit after which to evic trie nodes from memory.
|
// Trie cache generation limit after which to evic trie nodes from memory.
|
||||||
|
|
@ -33,9 +32,6 @@ const (
|
||||||
// Number of past tries to keep. This value is chosen such that
|
// Number of past tries to keep. This value is chosen such that
|
||||||
// reasonable chain reorg depths will hit an existing trie.
|
// reasonable chain reorg depths will hit an existing trie.
|
||||||
maxPastTries = 12
|
maxPastTries = 12
|
||||||
|
|
||||||
// Number of codehash->size associations to keep.
|
|
||||||
codeSizeCacheSize = 100000
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Database wraps access to tries and contract code.
|
// Database wraps access to tries and contract code.
|
||||||
|
|
@ -78,18 +74,16 @@ type Trie interface {
|
||||||
// intermediate trie-node memory pool between the low level storage layer and the
|
// intermediate trie-node memory pool between the low level storage layer and the
|
||||||
// high level trie abstraction.
|
// high level trie abstraction.
|
||||||
func NewDatabase(db ethdb.Database) Database {
|
func NewDatabase(db ethdb.Database) Database {
|
||||||
csc, _ := lru.New(codeSizeCacheSize)
|
|
||||||
return &cachingDB{
|
return &cachingDB{
|
||||||
db: trie.NewDatabase(db),
|
db: trie.NewDatabase(db),
|
||||||
codeSizeCache: csc,
|
// codeSizeCache: csc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type cachingDB struct {
|
type cachingDB struct {
|
||||||
db *trie.Database
|
db *trie.Database
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
pastTries []*XDCXTrie
|
pastTries []*XDCXTrie
|
||||||
codeSizeCache *lru.Cache
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenTrie opens the main account trie.
|
// OpenTrie opens the main account trie.
|
||||||
|
|
|
||||||
|
|
@ -22,20 +22,19 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/engines/engine_v1"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/engines/engine_v1"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/engines/engine_v2"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/engines/engine_v2"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||||
"github.com/XinFinOrg/XDPoSChain/event"
|
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/clique"
|
"github.com/XinFinOrg/XDPoSChain/consensus/clique"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/event"
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rpc"
|
"github.com/XinFinOrg/XDPoSChain/rpc"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -60,7 +59,7 @@ type XDPoS struct {
|
||||||
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
||||||
|
|
||||||
// Transaction cache, only make sense for adaptor level
|
// Transaction cache, only make sense for adaptor level
|
||||||
signingTxsCache *lru.Cache
|
signingTxsCache *lru.Cache[common.Hash, []*types.Transaction]
|
||||||
|
|
||||||
// Share Channel
|
// Share Channel
|
||||||
MinePeriodCh chan int // Miner wait Period Channel
|
MinePeriodCh chan int // Miner wait Period Channel
|
||||||
|
|
@ -109,17 +108,12 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS {
|
||||||
minePeriodCh := make(chan int)
|
minePeriodCh := make(chan int)
|
||||||
newRoundCh := make(chan types.Round, newRoundChanSize)
|
newRoundCh := make(chan types.Round, newRoundChanSize)
|
||||||
|
|
||||||
// Allocate the snapshot caches and create the engine
|
|
||||||
signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit)
|
|
||||||
|
|
||||||
return &XDPoS{
|
return &XDPoS{
|
||||||
config: config,
|
config: config,
|
||||||
db: db,
|
db: db,
|
||||||
|
MinePeriodCh: minePeriodCh,
|
||||||
MinePeriodCh: minePeriodCh,
|
NewRoundCh: newRoundCh,
|
||||||
NewRoundCh: newRoundCh,
|
signingTxsCache: lru.NewCache[common.Hash, []*types.Transaction](utils.BlockSignersCacheLimit),
|
||||||
|
|
||||||
signingTxsCache: signingTxsCache,
|
|
||||||
EngineV1: engine_v1.New(chainConfig, db),
|
EngineV1: engine_v1.New(chainConfig, db),
|
||||||
EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh),
|
EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh),
|
||||||
}
|
}
|
||||||
|
|
@ -138,22 +132,16 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS {
|
||||||
minePeriodCh := make(chan int)
|
minePeriodCh := make(chan int)
|
||||||
newRoundCh := make(chan types.Round, newRoundChanSize)
|
newRoundCh := make(chan types.Round, newRoundChanSize)
|
||||||
|
|
||||||
// Allocate the snapshot caches and create the engine
|
|
||||||
signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit)
|
|
||||||
|
|
||||||
fakeEngine = &XDPoS{
|
fakeEngine = &XDPoS{
|
||||||
config: conf,
|
config: conf,
|
||||||
db: db,
|
db: db,
|
||||||
|
MinePeriodCh: minePeriodCh,
|
||||||
MinePeriodCh: minePeriodCh,
|
NewRoundCh: newRoundCh,
|
||||||
NewRoundCh: newRoundCh,
|
|
||||||
|
|
||||||
GetXDCXService: func() utils.TradingService { return nil },
|
GetXDCXService: func() utils.TradingService { return nil },
|
||||||
GetLendingService: func() utils.LendingService { return nil },
|
GetLendingService: func() utils.LendingService { return nil },
|
||||||
|
signingTxsCache: lru.NewCache[common.Hash, []*types.Transaction](utils.BlockSignersCacheLimit),
|
||||||
signingTxsCache: signingTxsCache,
|
EngineV1: engine_v1.NewFaker(db, chainConfig),
|
||||||
EngineV1: engine_v1.NewFaker(db, chainConfig),
|
EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh),
|
||||||
EngineV2: engine_v2.New(chainConfig, db, minePeriodCh, newRoundCh),
|
|
||||||
}
|
}
|
||||||
return fakeEngine
|
return fakeEngine
|
||||||
}
|
}
|
||||||
|
|
@ -554,7 +542,7 @@ func (x *XDPoS) CacheSigningTxs(hash common.Hash, txs []*types.Transaction) []*t
|
||||||
return signTxs
|
return signTxs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *XDPoS) GetCachedSigningTxs(hash common.Hash) (interface{}, bool) {
|
func (x *XDPoS) GetCachedSigningTxs(hash common.Hash) ([]*types.Transaction, bool) {
|
||||||
return x.signingTxsCache.Get(hash)
|
return x.signingTxsCache.Get(hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ import (
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/clique"
|
"github.com/XinFinOrg/XDPoSChain/consensus/clique"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/misc"
|
"github.com/XinFinOrg/XDPoSChain/consensus/misc"
|
||||||
|
|
@ -26,7 +26,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -44,10 +43,10 @@ type XDPoS_v1 struct {
|
||||||
config *params.XDPoSConfig // Consensus engine configuration parameters
|
config *params.XDPoSConfig // Consensus engine configuration parameters
|
||||||
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
||||||
|
|
||||||
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
|
recents *lru.Cache[common.Hash, *SnapshotV1] // Snapshots for recent block to speed up reorgs
|
||||||
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
signatures *utils.SigLRU // Signatures of recent blocks to speed up mining
|
||||||
validatorSignatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
validatorSignatures *utils.SigLRU // Signatures of recent blocks to speed up mining
|
||||||
verifiedHeaders *lru.ARCCache
|
verifiedHeaders *lru.Cache[common.Hash, struct{}]
|
||||||
proposals map[common.Address]bool // Current list of proposals we are pushing
|
proposals map[common.Address]bool // Current list of proposals we are pushing
|
||||||
|
|
||||||
signer common.Address // Ethereum address of the signing key
|
signer common.Address // Ethereum address of the signing key
|
||||||
|
|
@ -92,20 +91,16 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database) *XDPoS_v1 {
|
||||||
conf.Epoch = utils.EpochLength
|
conf.Epoch = utils.EpochLength
|
||||||
}
|
}
|
||||||
|
|
||||||
recents, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
signatures, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
validatorSignatures, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
verifiedHeaders, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
return &XDPoS_v1{
|
return &XDPoS_v1{
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
|
|
||||||
config: &conf,
|
config: &conf,
|
||||||
db: db,
|
db: db,
|
||||||
|
|
||||||
recents: recents,
|
recents: lru.NewCache[common.Hash, *SnapshotV1](utils.InmemorySnapshots),
|
||||||
signatures: signatures,
|
signatures: lru.NewCache[common.Hash, common.Address](utils.InmemorySnapshots),
|
||||||
verifiedHeaders: verifiedHeaders,
|
verifiedHeaders: lru.NewCache[common.Hash, struct{}](utils.InmemorySnapshots),
|
||||||
validatorSignatures: validatorSignatures,
|
validatorSignatures: lru.NewCache[common.Hash, common.Address](utils.InmemorySnapshots),
|
||||||
proposals: make(map[common.Address]bool),
|
proposals: make(map[common.Address]bool),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +140,7 @@ func (x *XDPoS_v1) verifyHeaderWithCache(chain consensus.ChainReader, header *ty
|
||||||
}
|
}
|
||||||
err := x.verifyHeader(chain, header, parents, fullVerify)
|
err := x.verifyHeader(chain, header, parents, fullVerify)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
x.verifiedHeaders.Add(header.Hash(), true)
|
x.verifiedHeaders.Add(header.Hash(), struct{}{})
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -483,8 +478,8 @@ func (x *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash com
|
||||||
)
|
)
|
||||||
for {
|
for {
|
||||||
// If an in-memory SnapshotV1 was found, use that
|
// If an in-memory SnapshotV1 was found, use that
|
||||||
if s, ok := x.recents.Get(hash); ok {
|
if s, ok := x.recents.Get(hash); ok && s != nil {
|
||||||
snap = s.(*SnapshotV1)
|
snap = s
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// If an on-disk checkpoint snapshot can be found, use that
|
// If an on-disk checkpoint snapshot can be found, use that
|
||||||
|
|
@ -979,7 +974,7 @@ func (x *XDPoS_v1) RecoverValidator(header *types.Header) (common.Address, error
|
||||||
// If the signature's already cached, return that
|
// If the signature's already cached, return that
|
||||||
hash := header.Hash()
|
hash := header.Hash()
|
||||||
if address, known := x.validatorSignatures.Get(hash); known {
|
if address, known := x.validatorSignatures.Get(hash); known {
|
||||||
return address.(common.Address), nil
|
return address, nil
|
||||||
}
|
}
|
||||||
// Retrieve the signature from the header.Validator
|
// Retrieve the signature from the header.Validator
|
||||||
// len equals 65 bytes
|
// len equals 65 bytes
|
||||||
|
|
@ -1044,20 +1039,15 @@ func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS_v1 {
|
||||||
// Set any missing consensus parameters to their defaults
|
// Set any missing consensus parameters to their defaults
|
||||||
conf := chainConfig.XDPoS
|
conf := chainConfig.XDPoS
|
||||||
|
|
||||||
// Allocate the snapshot caches and create the engine
|
|
||||||
recents, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
signatures, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
validatorSignatures, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
verifiedHeaders, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
fakeEngine = &XDPoS_v1{
|
fakeEngine = &XDPoS_v1{
|
||||||
chainConfig: chainConfig,
|
chainConfig: chainConfig,
|
||||||
|
|
||||||
config: conf,
|
config: conf,
|
||||||
db: db,
|
db: db,
|
||||||
recents: recents,
|
recents: lru.NewCache[common.Hash, *SnapshotV1](utils.InmemorySnapshots),
|
||||||
signatures: signatures,
|
signatures: lru.NewCache[common.Hash, common.Address](utils.InmemorySnapshots),
|
||||||
verifiedHeaders: verifiedHeaders,
|
verifiedHeaders: lru.NewCache[common.Hash, struct{}](utils.InmemorySnapshots),
|
||||||
validatorSignatures: validatorSignatures,
|
validatorSignatures: lru.NewCache[common.Hash, common.Address](utils.InmemorySnapshots),
|
||||||
proposals: make(map[common.Address]bool),
|
proposals: make(map[common.Address]bool),
|
||||||
}
|
}
|
||||||
return fakeEngine
|
return fakeEngine
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Vote represents a single vote that an authorized signer made to modify the
|
// Vote represents a single vote that an authorized signer made to modify the
|
||||||
|
|
@ -32,7 +31,7 @@ import (
|
||||||
// Snapshot is the state of the authorization voting at a given point in time.
|
// Snapshot is the state of the authorization voting at a given point in time.
|
||||||
type SnapshotV1 struct {
|
type SnapshotV1 struct {
|
||||||
config *params.XDPoSConfig // Consensus engine parameters to fine tune behavior
|
config *params.XDPoSConfig // Consensus engine parameters to fine tune behavior
|
||||||
sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover
|
sigcache *utils.SigLRU // Cache of recent block signatures to speed up ecrecover
|
||||||
|
|
||||||
Number uint64 `json:"number"` // Block number where the snapshot was created
|
Number uint64 `json:"number"` // Block number where the snapshot was created
|
||||||
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
|
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
|
||||||
|
|
@ -45,7 +44,7 @@ type SnapshotV1 struct {
|
||||||
// newSnapshot creates a new snapshot with the specified startup parameters. This
|
// newSnapshot creates a new snapshot with the specified startup parameters. This
|
||||||
// method does not initialize the set of recent signers, so only ever use if for
|
// method does not initialize the set of recent signers, so only ever use if for
|
||||||
// the genesis block.
|
// the genesis block.
|
||||||
func newSnapshot(config *params.XDPoSConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, signers []common.Address) *SnapshotV1 {
|
func newSnapshot(config *params.XDPoSConfig, sigcache *utils.SigLRU, number uint64, hash common.Hash, signers []common.Address) *SnapshotV1 {
|
||||||
snap := &SnapshotV1{
|
snap := &SnapshotV1{
|
||||||
config: config,
|
config: config,
|
||||||
sigcache: sigcache,
|
sigcache: sigcache,
|
||||||
|
|
@ -62,7 +61,7 @@ func newSnapshot(config *params.XDPoSConfig, sigcache *lru.ARCCache, number uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadSnapshot loads an existing snapshot from the database.
|
// loadSnapshot loads an existing snapshot from the database.
|
||||||
func loadSnapshot(config *params.XDPoSConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*SnapshotV1, error) {
|
func loadSnapshot(config *params.XDPoSConfig, sigcache *utils.SigLRU, db ethdb.Database, hash common.Hash) (*SnapshotV1, error) {
|
||||||
blob, err := db.Get(append([]byte("XDPoS-"), hash[:]...))
|
blob, err := db.Get(append([]byte("XDPoS-"), hash[:]...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
"golang.org/x/crypto/sha3"
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -87,11 +86,11 @@ func sigHash(header *types.Header) (hash common.Hash) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ecrecover extracts the Ethereum account address from a signed header.
|
// ecrecover extracts the Ethereum account address from a signed header.
|
||||||
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
func ecrecover(header *types.Header, sigcache *utils.SigLRU) (common.Address, error) {
|
||||||
// If the signature's already cached, return that
|
// If the signature's already cached, return that
|
||||||
hash := header.Hash()
|
hash := header.Hash()
|
||||||
if address, known := sigcache.Get(hash); known {
|
if address, known := sigcache.Get(hash); known {
|
||||||
return address.(common.Address), nil
|
return address, nil
|
||||||
}
|
}
|
||||||
// Retrieve the signature from the header extra-data
|
// Retrieve the signature from the header extra-data
|
||||||
if len(header.Extra) < utils.ExtraSeal {
|
if len(header.Extra) < utils.ExtraSeal {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/countdown"
|
"github.com/XinFinOrg/XDPoSChain/common/countdown"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/clique"
|
"github.com/XinFinOrg/XDPoSChain/consensus/clique"
|
||||||
|
|
@ -21,7 +22,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type XDPoS_v2 struct {
|
type XDPoS_v2 struct {
|
||||||
|
|
@ -32,14 +32,14 @@ type XDPoS_v2 struct {
|
||||||
isInitilised bool // status of v2 variables
|
isInitilised bool // status of v2 variables
|
||||||
whosTurn common.Address // Record waiting for who to mine
|
whosTurn common.Address // Record waiting for who to mine
|
||||||
|
|
||||||
snapshots *lru.ARCCache // Snapshots for gap block
|
snapshots *lru.Cache[common.Hash, *SnapshotV2] // Snapshots for gap block
|
||||||
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
signatures *utils.SigLRU // Signatures of recent blocks to speed up mining
|
||||||
epochSwitches *lru.ARCCache // infos of epoch: master nodes, epoch switch block info, parent of that info
|
epochSwitches *lru.Cache[common.Hash, *types.EpochSwitchInfo] // infos of epoch: master nodes, epoch switch block info, parent of that info
|
||||||
verifiedHeaders *lru.ARCCache
|
verifiedHeaders *lru.Cache[common.Hash, struct{}]
|
||||||
|
|
||||||
// only contains epoch switch block info
|
// only contains epoch switch block info
|
||||||
// input: round, output: infos of epoch switch block and next epoch switch block info
|
// input: round, output: infos of epoch switch block and next epoch switch block info
|
||||||
round2epochBlockInfo *lru.ARCCache
|
round2epochBlockInfo *lru.Cache[types.Round, *types.BlockInfo]
|
||||||
|
|
||||||
signer common.Address // Ethereum address of the signing key
|
signer common.Address // Ethereum address of the signing key
|
||||||
signFn clique.SignerFn // Signer function to authorize hashes with
|
signFn clique.SignerFn // Signer function to authorize hashes with
|
||||||
|
|
@ -78,12 +78,6 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan i
|
||||||
duration := time.Duration(config.V2.CurrentConfig.TimeoutPeriod) * time.Second
|
duration := time.Duration(config.V2.CurrentConfig.TimeoutPeriod) * time.Second
|
||||||
timeoutTimer := countdown.NewCountDown(duration)
|
timeoutTimer := countdown.NewCountDown(duration)
|
||||||
|
|
||||||
snapshots, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
signatures, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
epochSwitches, _ := lru.NewARC(int(utils.InmemoryEpochs))
|
|
||||||
verifiedHeaders, _ := lru.NewARC(utils.InmemorySnapshots)
|
|
||||||
round2epochBlockInfo, _ := lru.NewARC(utils.InmemoryRound2Epochs)
|
|
||||||
|
|
||||||
timeoutPool := utils.NewPool()
|
timeoutPool := utils.NewPool()
|
||||||
votePool := utils.NewPool()
|
votePool := utils.NewPool()
|
||||||
engine := &XDPoS_v2{
|
engine := &XDPoS_v2{
|
||||||
|
|
@ -93,17 +87,17 @@ func New(chainConfig *params.ChainConfig, db ethdb.Database, minePeriodCh chan i
|
||||||
db: db,
|
db: db,
|
||||||
isInitilised: false,
|
isInitilised: false,
|
||||||
|
|
||||||
signatures: signatures,
|
signatures: lru.NewCache[common.Hash, common.Address](utils.InmemorySnapshots),
|
||||||
|
|
||||||
verifiedHeaders: verifiedHeaders,
|
verifiedHeaders: lru.NewCache[common.Hash, struct{}](utils.InmemorySnapshots),
|
||||||
snapshots: snapshots,
|
snapshots: lru.NewCache[common.Hash, *SnapshotV2](utils.InmemorySnapshots),
|
||||||
epochSwitches: epochSwitches,
|
epochSwitches: lru.NewCache[common.Hash, *types.EpochSwitchInfo](int(utils.InmemoryEpochs)),
|
||||||
timeoutWorker: timeoutTimer,
|
timeoutWorker: timeoutTimer,
|
||||||
BroadcastCh: make(chan interface{}),
|
BroadcastCh: make(chan interface{}),
|
||||||
minePeriodCh: minePeriodCh,
|
minePeriodCh: minePeriodCh,
|
||||||
newRoundCh: newRoundCh,
|
newRoundCh: newRoundCh,
|
||||||
|
|
||||||
round2epochBlockInfo: round2epochBlockInfo,
|
round2epochBlockInfo: lru.NewCache[types.Round, *types.BlockInfo](utils.InmemoryRound2Epochs),
|
||||||
|
|
||||||
timeoutPool: timeoutPool,
|
timeoutPool: timeoutPool,
|
||||||
votePool: votePool,
|
votePool: votePool,
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,8 @@ func (x *XDPoS_v2) getPreviousEpochSwitchInfoByHash(chain consensus.ChainReader,
|
||||||
// Given header and its hash, get epoch switch info from the epoch switch block of that epoch,
|
// Given header and its hash, get epoch switch info from the epoch switch block of that epoch,
|
||||||
// header is allow to be nil.
|
// header is allow to be nil.
|
||||||
func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types.Header, hash common.Hash) (*types.EpochSwitchInfo, error) {
|
func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types.Header, hash common.Hash) (*types.EpochSwitchInfo, error) {
|
||||||
e, ok := x.epochSwitches.Get(hash)
|
epochSwitchInfo, ok := x.epochSwitches.Get(hash)
|
||||||
if ok {
|
if ok && epochSwitchInfo != nil {
|
||||||
epochSwitchInfo := e.(*types.EpochSwitchInfo)
|
|
||||||
log.Debug("[getEpochSwitchInfo] cache hit", "number", epochSwitchInfo.EpochSwitchBlockInfo.Number, "hash", hash.Hex())
|
log.Debug("[getEpochSwitchInfo] cache hit", "number", epochSwitchInfo.EpochSwitchBlockInfo.Number, "hash", hash.Hex())
|
||||||
return epochSwitchInfo, nil
|
return epochSwitchInfo, nil
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +87,7 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types
|
||||||
x.epochSwitches.Add(hash, epochSwitchInfo)
|
x.epochSwitches.Add(hash, epochSwitchInfo)
|
||||||
return epochSwitchInfo, nil
|
return epochSwitchInfo, nil
|
||||||
}
|
}
|
||||||
epochSwitchInfo, err := x.getEpochSwitchInfo(chain, nil, h.ParentHash)
|
epochSwitchInfo, err = x.getEpochSwitchInfo(chain, nil, h.ParentHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[getEpochSwitchInfo] recursive error", "err", err, "hash", hash.Hex(), "number", h.Number.Uint64())
|
log.Error("[getEpochSwitchInfo] recursive error", "err", err, "hash", hash.Hex(), "number", h.Number.Uint64())
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -84,8 +84,7 @@ func (x *XDPoS_v2) getSnapshot(chain consensus.ChainReader, number uint64, isGap
|
||||||
log.Debug("get snapshot from gap block", "number", gapBlockNum, "hash", gapBlockHash.Hex())
|
log.Debug("get snapshot from gap block", "number", gapBlockNum, "hash", gapBlockHash.Hex())
|
||||||
|
|
||||||
// If an in-memory SnapshotV2 was found, use that
|
// If an in-memory SnapshotV2 was found, use that
|
||||||
if s, ok := x.snapshots.Get(gapBlockHash); ok {
|
if snap, ok := x.snapshots.Get(gapBlockHash); ok && snap != nil {
|
||||||
snap := s.(*SnapshotV2)
|
|
||||||
log.Trace("Loaded snapshot from memory", "number", gapBlockNum, "hash", gapBlockHash)
|
log.Trace("Loaded snapshot from memory", "number", gapBlockNum, "hash", gapBlockHash)
|
||||||
return snap, nil
|
return snap, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
"golang.org/x/crypto/sha3"
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -47,11 +46,11 @@ func sigHash(header *types.Header) (hash common.Hash) {
|
||||||
return hash
|
return hash
|
||||||
}
|
}
|
||||||
|
|
||||||
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
func ecrecover(header *types.Header, sigcache *utils.SigLRU) (common.Address, error) {
|
||||||
// If the signature's already cached, return that
|
// If the signature's already cached, return that
|
||||||
hash := header.Hash()
|
hash := header.Hash()
|
||||||
if address, known := sigcache.Get(hash); known {
|
if address, known := sigcache.Get(hash); known {
|
||||||
return address.(common.Address), nil
|
return address, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recover the public key and the Ethereum address
|
// Recover the public key and the Ethereum address
|
||||||
|
|
@ -224,9 +223,8 @@ func (x *XDPoS_v2) CalculateMissingRounds(chain consensus.ChainReader, header *t
|
||||||
func (x *XDPoS_v2) getBlockByEpochNumberInCache(chain consensus.ChainReader, estRound types.Round) *types.BlockInfo {
|
func (x *XDPoS_v2) getBlockByEpochNumberInCache(chain consensus.ChainReader, estRound types.Round) *types.BlockInfo {
|
||||||
epochSwitchInCache := make([]*types.BlockInfo, 0)
|
epochSwitchInCache := make([]*types.BlockInfo, 0)
|
||||||
for r := estRound; r < estRound+types.Round(x.config.Epoch); r++ {
|
for r := estRound; r < estRound+types.Round(x.config.Epoch); r++ {
|
||||||
info, ok := x.round2epochBlockInfo.Get(r)
|
blockInfo, ok := x.round2epochBlockInfo.Get(r)
|
||||||
if ok {
|
if ok && blockInfo != nil {
|
||||||
blockInfo := info.(*types.BlockInfo)
|
|
||||||
epochSwitchInCache = append(epochSwitchInCache, blockInfo)
|
epochSwitchInCache = append(epochSwitchInCache, blockInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,6 @@ func (x *XDPoS_v2) verifyHeader(chain consensus.ChainReader, header *types.Heade
|
||||||
return utils.ErrNotItsTurn
|
return utils.ErrNotItsTurn
|
||||||
}
|
}
|
||||||
|
|
||||||
x.verifiedHeaders.Add(header.Hash(), true)
|
x.verifiedHeaders.Add(header.Hash(), struct{}{})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
||||||
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
|
"github.com/XinFinOrg/XDPoSChain/XDCxlending/lendingstate"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/prque"
|
"github.com/XinFinOrg/XDPoSChain/common/prque"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/clique"
|
"github.com/XinFinOrg/XDPoSChain/consensus/clique"
|
||||||
|
|
@ -79,3 +80,5 @@ type EpochNumInfo struct {
|
||||||
EpochFirstBlockNumber *big.Int `json:"firstBlock"`
|
EpochFirstBlockNumber *big.Int `json:"firstBlock"`
|
||||||
EpochLastBlockNumber *big.Int `json:"lastBlock"`
|
EpochLastBlockNumber *big.Int `json:"lastBlock"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SigLRU = lru.Cache[common.Hash, common.Address]
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
|
"github.com/XinFinOrg/XDPoSChain/common/hexutil"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/misc"
|
"github.com/XinFinOrg/XDPoSChain/consensus/misc"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/state"
|
"github.com/XinFinOrg/XDPoSChain/core/state"
|
||||||
|
|
@ -39,7 +40,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rpc"
|
"github.com/XinFinOrg/XDPoSChain/rpc"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
"golang.org/x/crypto/sha3"
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -173,11 +173,11 @@ func sigHash(header *types.Header) (hash common.Hash) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ecrecover extracts the Ethereum account address from a signed header.
|
// ecrecover extracts the Ethereum account address from a signed header.
|
||||||
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
func ecrecover(header *types.Header, sigcache *sigLRU) (common.Address, error) {
|
||||||
// If the signature's already cached, return that
|
// If the signature's already cached, return that
|
||||||
hash := header.Hash()
|
hash := header.Hash()
|
||||||
if address, known := sigcache.Get(hash); known {
|
if address, known := sigcache.Get(hash); known {
|
||||||
return address.(common.Address), nil
|
return address, nil
|
||||||
}
|
}
|
||||||
// Retrieve the signature from the header extra-data
|
// Retrieve the signature from the header extra-data
|
||||||
if len(header.Extra) < extraSeal {
|
if len(header.Extra) < extraSeal {
|
||||||
|
|
@ -203,8 +203,8 @@ type Clique struct {
|
||||||
config *params.CliqueConfig // Consensus engine configuration parameters
|
config *params.CliqueConfig // Consensus engine configuration parameters
|
||||||
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
db ethdb.Database // Database to store and retrieve snapshot checkpoints
|
||||||
|
|
||||||
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
|
recents *lru.Cache[common.Hash, *Snapshot] // Snapshots for recent block to speed up reorgs
|
||||||
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
|
signatures *sigLRU // Signatures of recent blocks to speed up mining
|
||||||
|
|
||||||
proposals map[common.Address]bool // Current list of proposals we are pushing
|
proposals map[common.Address]bool // Current list of proposals we are pushing
|
||||||
|
|
||||||
|
|
@ -221,15 +221,12 @@ func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
|
||||||
if conf.Epoch == 0 {
|
if conf.Epoch == 0 {
|
||||||
conf.Epoch = epochLength
|
conf.Epoch = epochLength
|
||||||
}
|
}
|
||||||
// Allocate the snapshot caches and create the engine
|
|
||||||
recents, _ := lru.NewARC(inmemorySnapshots)
|
|
||||||
signatures, _ := lru.NewARC(inmemorySignatures)
|
|
||||||
|
|
||||||
return &Clique{
|
return &Clique{
|
||||||
config: &conf,
|
config: &conf,
|
||||||
db: db,
|
db: db,
|
||||||
recents: recents,
|
recents: lru.NewCache[common.Hash, *Snapshot](inmemorySnapshots),
|
||||||
signatures: signatures,
|
signatures: lru.NewCache[common.Hash, common.Address](inmemorySignatures),
|
||||||
proposals: make(map[common.Address]bool),
|
proposals: make(map[common.Address]bool),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -396,8 +393,8 @@ func (c *Clique) snapshot(chain consensus.ChainReader, number uint64, hash commo
|
||||||
)
|
)
|
||||||
for {
|
for {
|
||||||
// If an in-memory snapshot was found, use that
|
// If an in-memory snapshot was found, use that
|
||||||
if s, ok := c.recents.Get(hash); ok {
|
if s, ok := c.recents.Get(hash); ok && s != nil {
|
||||||
snap = s.(*Snapshot)
|
snap = s
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// If an on-disk checkpoint snapshot can be found, use that
|
// If an on-disk checkpoint snapshot can be found, use that
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Vote represents a single vote that an authorized signer made to modify the
|
// Vote represents a single vote that an authorized signer made to modify the
|
||||||
|
|
@ -43,10 +43,12 @@ type Tally struct {
|
||||||
Votes int `json:"votes"` // Number of votes until now wanting to pass the proposal
|
Votes int `json:"votes"` // Number of votes until now wanting to pass the proposal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type sigLRU = lru.Cache[common.Hash, common.Address]
|
||||||
|
|
||||||
// Snapshot is the state of the authorization voting at a given point in time.
|
// Snapshot is the state of the authorization voting at a given point in time.
|
||||||
type Snapshot struct {
|
type Snapshot struct {
|
||||||
config *params.CliqueConfig // Consensus engine parameters to fine tune behavior
|
config *params.CliqueConfig // Consensus engine parameters to fine tune behavior
|
||||||
sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover
|
sigcache *sigLRU // Cache of recent block signatures to speed up ecrecover
|
||||||
|
|
||||||
Number uint64 `json:"number"` // Block number where the snapshot was created
|
Number uint64 `json:"number"` // Block number where the snapshot was created
|
||||||
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
|
Hash common.Hash `json:"hash"` // Block hash where the snapshot was created
|
||||||
|
|
@ -59,7 +61,7 @@ type Snapshot struct {
|
||||||
// newSnapshot creates a new snapshot with the specified startup parameters. This
|
// newSnapshot creates a new snapshot with the specified startup parameters. This
|
||||||
// method does not initialize the set of recent signers, so only ever use if for
|
// method does not initialize the set of recent signers, so only ever use if for
|
||||||
// the genesis block.
|
// the genesis block.
|
||||||
func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, signers []common.Address) *Snapshot {
|
func newSnapshot(config *params.CliqueConfig, sigcache *sigLRU, number uint64, hash common.Hash, signers []common.Address) *Snapshot {
|
||||||
snap := &Snapshot{
|
snap := &Snapshot{
|
||||||
config: config,
|
config: config,
|
||||||
sigcache: sigcache,
|
sigcache: sigcache,
|
||||||
|
|
@ -76,7 +78,7 @@ func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uin
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadSnapshot loads an existing snapshot from the database.
|
// loadSnapshot loads an existing snapshot from the database.
|
||||||
func loadSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
|
func loadSnapshot(config *params.CliqueConfig, sigcache *sigLRU, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
|
||||||
blob, err := db.Get(append([]byte("clique-"), hash[:]...))
|
blob, err := db.Get(append([]byte("clique-"), hash[:]...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,12 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
lrupkg "github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/metrics"
|
"github.com/XinFinOrg/XDPoSChain/metrics"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rpc"
|
"github.com/XinFinOrg/XDPoSChain/rpc"
|
||||||
mmap "github.com/edsrzf/mmap-go"
|
mmap "github.com/edsrzf/mmap-go"
|
||||||
"github.com/hashicorp/golang-lru/simplelru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrInvalidDumpMagic = errors.New("invalid dump magic")
|
var ErrInvalidDumpMagic = errors.New("invalid dump magic")
|
||||||
|
|
@ -144,34 +144,45 @@ func memoryMapAndGenerate(path string, size uint64, generator func(buffer []uint
|
||||||
return memoryMap(path)
|
return memoryMap(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type cacheOrDataset interface {
|
||||||
|
*cache | *dataset
|
||||||
|
}
|
||||||
|
|
||||||
// lru tracks caches or datasets by their last use time, keeping at most N of them.
|
// lru tracks caches or datasets by their last use time, keeping at most N of them.
|
||||||
type lru struct {
|
type lru[T cacheOrDataset] struct {
|
||||||
what string
|
what string
|
||||||
new func(epoch uint64) interface{}
|
new func(epoch uint64) T
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
// Items are kept in a LRU cache, but there is a special case:
|
// Items are kept in a LRU cache, but there is a special case:
|
||||||
// We always keep an item for (highest seen epoch) + 1 as the 'future item'.
|
// We always keep an item for (highest seen epoch) + 1 as the 'future item'.
|
||||||
cache *simplelru.LRU
|
cache lrupkg.BasicLRU[uint64, T]
|
||||||
future uint64
|
future uint64
|
||||||
futureItem interface{}
|
futureItem T
|
||||||
}
|
}
|
||||||
|
|
||||||
// newlru create a new least-recently-used cache for ither the verification caches
|
// newlru create a new least-recently-used cache for either the verification caches
|
||||||
// or the mining datasets.
|
// or the mining datasets.
|
||||||
func newlru(what string, maxItems int, new func(epoch uint64) interface{}) *lru {
|
func newlru[T cacheOrDataset](maxItems int, new func(epoch uint64) T) *lru[T] {
|
||||||
if maxItems <= 0 {
|
var what string
|
||||||
maxItems = 1
|
switch any(T(nil)).(type) {
|
||||||
|
case *cache:
|
||||||
|
what = "cache"
|
||||||
|
case *dataset:
|
||||||
|
what = "dataset"
|
||||||
|
default:
|
||||||
|
panic("unknown type")
|
||||||
|
}
|
||||||
|
return &lru[T]{
|
||||||
|
what: what,
|
||||||
|
new: new,
|
||||||
|
cache: lrupkg.NewBasicLRU[uint64, T](maxItems),
|
||||||
}
|
}
|
||||||
cache, _ := simplelru.NewLRU(maxItems, func(key, value interface{}) {
|
|
||||||
log.Trace("Evicted ethash "+what, "epoch", key)
|
|
||||||
})
|
|
||||||
return &lru{what: what, new: new, cache: cache}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get retrieves or creates an item for the given epoch. The first return value is always
|
// get retrieves or creates an item for the given epoch. The first return value is always
|
||||||
// non-nil. The second return value is non-nil if lru thinks that an item will be useful in
|
// non-nil. The second return value is non-nil if lru thinks that an item will be useful in
|
||||||
// the near future.
|
// the near future.
|
||||||
func (lru *lru) get(epoch uint64) (item, future interface{}) {
|
func (lru *lru[T]) get(epoch uint64) (item, future T) {
|
||||||
lru.mu.Lock()
|
lru.mu.Lock()
|
||||||
defer lru.mu.Unlock()
|
defer lru.mu.Unlock()
|
||||||
|
|
||||||
|
|
@ -205,9 +216,8 @@ type cache struct {
|
||||||
once sync.Once // Ensures the cache is generated only once
|
once sync.Once // Ensures the cache is generated only once
|
||||||
}
|
}
|
||||||
|
|
||||||
// newCache creates a new ethash verification cache and returns it as a plain Go
|
// newCache creates a new ethash verification cache.
|
||||||
// interface to be usable in an LRU cache.
|
func newCache(epoch uint64) *cache {
|
||||||
func newCache(epoch uint64) interface{} {
|
|
||||||
return &cache{epoch: epoch}
|
return &cache{epoch: epoch}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,7 +293,7 @@ type dataset struct {
|
||||||
|
|
||||||
// newDataset creates a new ethash mining dataset and returns it as a plain Go
|
// newDataset creates a new ethash mining dataset and returns it as a plain Go
|
||||||
// interface to be usable in an LRU cache.
|
// interface to be usable in an LRU cache.
|
||||||
func newDataset(epoch uint64) interface{} {
|
func newDataset(epoch uint64) *dataset {
|
||||||
return &dataset{epoch: epoch}
|
return &dataset{epoch: epoch}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -394,13 +404,13 @@ type Config struct {
|
||||||
type Ethash struct {
|
type Ethash struct {
|
||||||
config Config
|
config Config
|
||||||
|
|
||||||
caches *lru // In memory caches to avoid regenerating too often
|
caches *lru[*cache] // In memory caches to avoid regenerating too often
|
||||||
datasets *lru // In memory datasets to avoid regenerating too often
|
datasets *lru[*dataset] // In memory datasets to avoid regenerating too often
|
||||||
|
|
||||||
// Mining related fields
|
// Mining related fields
|
||||||
rand *rand.Rand // Properly seeded random source for nonces
|
rand *rand.Rand // Properly seeded random source for nonces
|
||||||
threads int // Number of threads to mine on if mining
|
threads int // Number of threads to mine on if mining
|
||||||
update chan struct{} // Notification channel to update mining parameters
|
update chan struct{} // Notification channel to update mining parameters
|
||||||
hashrate *metrics.Meter // Meter tracking the average hashrate
|
hashrate *metrics.Meter // Meter tracking the average hashrate
|
||||||
|
|
||||||
// The fields below are hooks for testing
|
// The fields below are hooks for testing
|
||||||
|
|
@ -425,8 +435,8 @@ func New(config Config) *Ethash {
|
||||||
}
|
}
|
||||||
return &Ethash{
|
return &Ethash{
|
||||||
config: config,
|
config: config,
|
||||||
caches: newlru("cache", config.CachesInMem, newCache),
|
caches: newlru(config.CachesInMem, newCache),
|
||||||
datasets: newlru("dataset", config.DatasetsInMem, newDataset),
|
datasets: newlru(config.DatasetsInMem, newDataset),
|
||||||
update: make(chan struct{}),
|
update: make(chan struct{}),
|
||||||
hashrate: metrics.NewMeter(),
|
hashrate: metrics.NewMeter(),
|
||||||
}
|
}
|
||||||
|
|
@ -494,15 +504,13 @@ func NewShared() *Ethash {
|
||||||
// stored on disk, and finally generating one if none can be found.
|
// stored on disk, and finally generating one if none can be found.
|
||||||
func (ethash *Ethash) cache(block uint64) *cache {
|
func (ethash *Ethash) cache(block uint64) *cache {
|
||||||
epoch := block / epochLength
|
epoch := block / epochLength
|
||||||
currentI, futureI := ethash.caches.get(epoch)
|
current, future := ethash.caches.get(epoch)
|
||||||
current := currentI.(*cache)
|
|
||||||
|
|
||||||
// Wait for generation finish.
|
// Wait for generation finish.
|
||||||
current.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == ModeTest)
|
current.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == ModeTest)
|
||||||
|
|
||||||
// If we need a new future cache, now's a good time to regenerate it.
|
// If we need a new future cache, now's a good time to regenerate it.
|
||||||
if futureI != nil {
|
if future != nil {
|
||||||
future := futureI.(*cache)
|
|
||||||
go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == ModeTest)
|
go future.generate(ethash.config.CacheDir, ethash.config.CachesOnDisk, ethash.config.PowMode == ModeTest)
|
||||||
}
|
}
|
||||||
return current
|
return current
|
||||||
|
|
@ -513,15 +521,13 @@ func (ethash *Ethash) cache(block uint64) *cache {
|
||||||
// stored on disk, and finally generating one if none can be found.
|
// stored on disk, and finally generating one if none can be found.
|
||||||
func (ethash *Ethash) dataset(block uint64) *dataset {
|
func (ethash *Ethash) dataset(block uint64) *dataset {
|
||||||
epoch := block / epochLength
|
epoch := block / epochLength
|
||||||
currentI, futureI := ethash.datasets.get(epoch)
|
current, future := ethash.datasets.get(epoch)
|
||||||
current := currentI.(*dataset)
|
|
||||||
|
|
||||||
// Wait for generation finish.
|
// Wait for generation finish.
|
||||||
current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest)
|
current.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest)
|
||||||
|
|
||||||
// If we need a new future dataset, now's a good time to regenerate it.
|
// If we need a new future dataset, now's a good time to regenerate it.
|
||||||
if futureI != nil {
|
if future != nil {
|
||||||
future := futureI.(*dataset)
|
|
||||||
go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest)
|
go future.generate(ethash.config.DatasetDir, ethash.config.DatasetsOnDisk, ethash.config.PowMode == ModeTest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -331,20 +331,19 @@ func GetRewardForCheckpoint(c *XDPoS.XDPoS, chain consensus.ChainReader, header
|
||||||
for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- {
|
for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- {
|
||||||
header = chain.GetHeader(header.ParentHash, i)
|
header = chain.GetHeader(header.ParentHash, i)
|
||||||
mapBlkHash[i] = header.Hash()
|
mapBlkHash[i] = header.Hash()
|
||||||
signData, ok := c.GetCachedSigningTxs(header.Hash())
|
signingTxs, ok := c.GetCachedSigningTxs(header.Hash())
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i)
|
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i)
|
||||||
block := chain.GetBlock(header.Hash(), i)
|
block := chain.GetBlock(header.Hash(), i)
|
||||||
txs := block.Transactions()
|
txs := block.Transactions()
|
||||||
if !chain.Config().IsTIPSigning(header.Number) {
|
if !chain.Config().IsTIPSigning(header.Number) {
|
||||||
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i)
|
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i)
|
||||||
signData = c.CacheNoneTIPSigningTxs(header, txs, receipts)
|
signingTxs = c.CacheNoneTIPSigningTxs(header, txs, receipts)
|
||||||
} else {
|
} else {
|
||||||
signData = c.CacheSigningTxs(header.Hash(), txs)
|
signingTxs = c.CacheSigningTxs(header.Hash(), txs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
txs := signData.([]*types.Transaction)
|
for _, tx := range signingTxs {
|
||||||
for _, tx := range txs {
|
|
||||||
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
||||||
from := *tx.From()
|
from := *tx.From()
|
||||||
data[blkHash] = append(data[blkHash], from)
|
data[blkHash] = append(data[blkHash], from)
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -22,21 +21,18 @@ var (
|
||||||
}
|
}
|
||||||
transferFuncHex = common.Hex2Bytes("0xa9059cbb")
|
transferFuncHex = common.Hex2Bytes("0xa9059cbb")
|
||||||
transferFromFuncHex = common.Hex2Bytes("0x23b872dd")
|
transferFromFuncHex = common.Hex2Bytes("0x23b872dd")
|
||||||
cache, _ = lru.NewARC(128)
|
cache = lru.NewCache[common.Hash, map[common.Address]*big.Int](128)
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetTRC21FeeCapacityFromStateWithCache(trieRoot common.Hash, statedb *StateDB) map[common.Address]*big.Int {
|
func GetTRC21FeeCapacityFromStateWithCache(trieRoot common.Hash, statedb *StateDB) map[common.Address]*big.Int {
|
||||||
if statedb == nil {
|
if statedb == nil {
|
||||||
return map[common.Address]*big.Int{}
|
return map[common.Address]*big.Int{}
|
||||||
}
|
}
|
||||||
data, _ := cache.Get(trieRoot)
|
info, ok := cache.Get(trieRoot)
|
||||||
var info map[common.Address]*big.Int
|
if !ok || info == nil {
|
||||||
if data != nil {
|
|
||||||
info = data.(map[common.Address]*big.Int)
|
|
||||||
} else {
|
|
||||||
info = GetTRC21FeeCapacityFromState(statedb)
|
info = GetTRC21FeeCapacityFromState(statedb)
|
||||||
|
cache.Add(trieRoot, info)
|
||||||
}
|
}
|
||||||
cache.Add(trieRoot, info)
|
|
||||||
tokensFee := map[common.Address]*big.Int{}
|
tokensFee := map[common.Address]*big.Int{}
|
||||||
for key, value := range info {
|
for key, value := range info {
|
||||||
tokensFee[key] = big.NewInt(0).SetBytes(value.Bytes())
|
tokensFee[key] = big.NewInt(0).SetBytes(value.Bytes())
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,8 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/common/prque"
|
"github.com/XinFinOrg/XDPoSChain/common/prque"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||||
|
|
@ -135,7 +134,8 @@ type Fetcher struct {
|
||||||
queue *prque.Prque // Queue containing the import operations (block number sorted)
|
queue *prque.Prque // Queue containing the import operations (block number sorted)
|
||||||
queues map[string]int // Per peer block counts to prevent memory exhaustion
|
queues map[string]int // Per peer block counts to prevent memory exhaustion
|
||||||
queued map[common.Hash]*inject // Set of already queued blocks (to dedup imports)
|
queued map[common.Hash]*inject // Set of already queued blocks (to dedup imports)
|
||||||
knowns *lru.ARCCache
|
knowns *lru.Cache[common.Hash, struct{}]
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
getBlock blockRetrievalFn // Retrieves a block from the local chain
|
getBlock blockRetrievalFn // Retrieves a block from the local chain
|
||||||
verifyHeader headerVerifierFn // Checks if a block's headers have a valid proof of work
|
verifyHeader headerVerifierFn // Checks if a block's headers have a valid proof of work
|
||||||
|
|
@ -157,7 +157,6 @@ type Fetcher struct {
|
||||||
|
|
||||||
// New creates a block fetcher to retrieve blocks based on hash announcements.
|
// New creates a block fetcher to retrieve blocks based on hash announcements.
|
||||||
func New(getBlock blockRetrievalFn, verifyHeader headerVerifierFn, handleProposedBlock proposeBlockHandlerFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertBlock blockInsertFn, prepareBlock blockPrepareFn, dropPeer peerDropFn) *Fetcher {
|
func New(getBlock blockRetrievalFn, verifyHeader headerVerifierFn, handleProposedBlock proposeBlockHandlerFn, broadcastBlock blockBroadcasterFn, chainHeight chainHeightFn, insertBlock blockInsertFn, prepareBlock blockPrepareFn, dropPeer peerDropFn) *Fetcher {
|
||||||
knownBlocks, _ := lru.NewARC(blockLimit)
|
|
||||||
return &Fetcher{
|
return &Fetcher{
|
||||||
notify: make(chan *announce),
|
notify: make(chan *announce),
|
||||||
inject: make(chan *inject),
|
inject: make(chan *inject),
|
||||||
|
|
@ -174,7 +173,7 @@ func New(getBlock blockRetrievalFn, verifyHeader headerVerifierFn, handlePropose
|
||||||
queue: prque.New(nil),
|
queue: prque.New(nil),
|
||||||
queues: make(map[string]int),
|
queues: make(map[string]int),
|
||||||
queued: make(map[common.Hash]*inject),
|
queued: make(map[common.Hash]*inject),
|
||||||
knowns: knownBlocks,
|
knowns: lru.NewCache[common.Hash, struct{}](blockLimit),
|
||||||
getBlock: getBlock,
|
getBlock: getBlock,
|
||||||
verifyHeader: verifyHeader,
|
verifyHeader: verifyHeader,
|
||||||
handleProposedBlock: handleProposedBlock,
|
handleProposedBlock: handleProposedBlock,
|
||||||
|
|
@ -641,7 +640,7 @@ func (f *Fetcher) enqueue(peer string, block *types.Block) {
|
||||||
}
|
}
|
||||||
f.queues[peer] = count
|
f.queues[peer] = count
|
||||||
f.queued[hash] = op
|
f.queued[hash] = op
|
||||||
f.knowns.Add(hash, true)
|
f.knowns.Add(hash, struct{}{})
|
||||||
f.queue.Push(op, -int64(block.NumberU64()))
|
f.queue.Push(op, -int64(block.NumberU64()))
|
||||||
if f.queueChangeHook != nil {
|
if f.queueChangeHook != nil {
|
||||||
f.queueChangeHook(op.block.Hash(), true)
|
f.queueChangeHook(op.block.Hash(), true)
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,8 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus/misc"
|
"github.com/XinFinOrg/XDPoSChain/consensus/misc"
|
||||||
|
|
@ -104,14 +103,14 @@ type ProtocolManager struct {
|
||||||
// wait group is used for graceful shutdowns during downloading
|
// wait group is used for graceful shutdowns during downloading
|
||||||
// and processing
|
// and processing
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
knownTxs *lru.Cache
|
knownTxs *lru.Cache[common.Hash, struct{}]
|
||||||
knowOrderTxs *lru.Cache
|
knowOrderTxs *lru.Cache[common.Hash, struct{}]
|
||||||
knowLendingTxs *lru.Cache
|
knowLendingTxs *lru.Cache[common.Hash, struct{}]
|
||||||
|
|
||||||
// V2 messages
|
// V2 messages
|
||||||
knownVotes *lru.Cache
|
knownVotes *lru.Cache[common.Hash, struct{}]
|
||||||
knownSyncInfos *lru.Cache
|
knownSyncInfos *lru.Cache[common.Hash, struct{}]
|
||||||
knownTimeouts *lru.Cache
|
knownTimeouts *lru.Cache[common.Hash, struct{}]
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProtocolManagerEx add order pool to protocol
|
// NewProtocolManagerEx add order pool to protocol
|
||||||
|
|
@ -128,14 +127,6 @@ func NewProtocolManagerEx(config *params.ChainConfig, mode downloader.SyncMode,
|
||||||
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
// NewProtocolManager returns a new ethereum sub protocol manager. The Ethereum sub protocol manages peers capable
|
||||||
// with the ethereum network.
|
// with the ethereum network.
|
||||||
func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, networkID uint64, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
|
func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, networkID uint64, mux *event.TypeMux, txpool txPool, engine consensus.Engine, blockchain *core.BlockChain, chaindb ethdb.Database) (*ProtocolManager, error) {
|
||||||
knownTxs, _ := lru.New(maxKnownTxs)
|
|
||||||
knowOrderTxs, _ := lru.New(maxKnownOrderTxs)
|
|
||||||
knowLendingTxs, _ := lru.New(maxKnownLendingTxs)
|
|
||||||
|
|
||||||
knownVotes, _ := lru.New(maxKnownVote)
|
|
||||||
knownSyncInfos, _ := lru.New(maxKnownSyncInfo)
|
|
||||||
knownTimeouts, _ := lru.New(maxKnownTimeout)
|
|
||||||
|
|
||||||
// Create the protocol manager with the base fields
|
// Create the protocol manager with the base fields
|
||||||
manager := &ProtocolManager{
|
manager := &ProtocolManager{
|
||||||
networkId: networkID,
|
networkId: networkID,
|
||||||
|
|
@ -148,12 +139,12 @@ func NewProtocolManager(config *params.ChainConfig, mode downloader.SyncMode, ne
|
||||||
noMorePeers: make(chan struct{}),
|
noMorePeers: make(chan struct{}),
|
||||||
txsyncCh: make(chan *txsync),
|
txsyncCh: make(chan *txsync),
|
||||||
quitSync: make(chan struct{}),
|
quitSync: make(chan struct{}),
|
||||||
knownTxs: knownTxs,
|
knownTxs: lru.NewCache[common.Hash, struct{}](maxKnownTxs),
|
||||||
knowOrderTxs: knowOrderTxs,
|
knowOrderTxs: lru.NewCache[common.Hash, struct{}](maxKnownOrderTxs),
|
||||||
knowLendingTxs: knowLendingTxs,
|
knowLendingTxs: lru.NewCache[common.Hash, struct{}](maxKnownLendingTxs),
|
||||||
knownVotes: knownVotes,
|
knownVotes: lru.NewCache[common.Hash, struct{}](maxKnownVote),
|
||||||
knownSyncInfos: knownSyncInfos,
|
knownSyncInfos: lru.NewCache[common.Hash, struct{}](maxKnownSyncInfo),
|
||||||
knownTimeouts: knownTimeouts,
|
knownTimeouts: lru.NewCache[common.Hash, struct{}](maxKnownTimeout),
|
||||||
orderpool: nil,
|
orderpool: nil,
|
||||||
lendingpool: nil,
|
lendingpool: nil,
|
||||||
orderTxSub: nil,
|
orderTxSub: nil,
|
||||||
|
|
@ -776,9 +767,10 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
return errResp(ErrDecode, "transaction %d is nil", i)
|
return errResp(ErrDecode, "transaction %d is nil", i)
|
||||||
}
|
}
|
||||||
p.MarkTransaction(tx.Hash())
|
p.MarkTransaction(tx.Hash())
|
||||||
exist, _ := pm.knownTxs.ContainsOrAdd(tx.Hash(), true)
|
if pm.knownTxs.Contains(tx.Hash()) {
|
||||||
if exist {
|
|
||||||
log.Trace("Discard known tx", "hash", tx.Hash(), "nonce", tx.Nonce(), "to", tx.To())
|
log.Trace("Discard known tx", "hash", tx.Hash(), "nonce", tx.Nonce(), "to", tx.To())
|
||||||
|
} else {
|
||||||
|
pm.knownTxs.Add(tx.Hash(), struct{}{})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -801,11 +793,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
return errResp(ErrDecode, "transaction %d is nil", i)
|
return errResp(ErrDecode, "transaction %d is nil", i)
|
||||||
}
|
}
|
||||||
p.MarkOrderTransaction(tx.Hash())
|
p.MarkOrderTransaction(tx.Hash())
|
||||||
exist, _ := pm.knowOrderTxs.ContainsOrAdd(tx.Hash(), true)
|
if pm.knowOrderTxs.Contains(tx.Hash()) {
|
||||||
if exist {
|
|
||||||
log.Trace("Discard known tx", "hash", tx.Hash(), "nonce", tx.Nonce())
|
log.Trace("Discard known tx", "hash", tx.Hash(), "nonce", tx.Nonce())
|
||||||
|
} else {
|
||||||
|
pm.knowOrderTxs.Add(tx.Hash(), struct{}{})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if pm.orderpool != nil {
|
if pm.orderpool != nil {
|
||||||
|
|
@ -829,11 +821,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
return errResp(ErrDecode, "transaction %d is nil", i)
|
return errResp(ErrDecode, "transaction %d is nil", i)
|
||||||
}
|
}
|
||||||
p.MarkLendingTransaction(tx.Hash())
|
p.MarkLendingTransaction(tx.Hash())
|
||||||
exist, _ := pm.knowLendingTxs.ContainsOrAdd(tx.Hash(), true)
|
if pm.knowLendingTxs.Contains(tx.Hash()) {
|
||||||
if exist {
|
|
||||||
log.Trace("Discard known tx", "hash", tx.Hash(), "nonce", tx.Nonce())
|
log.Trace("Discard known tx", "hash", tx.Hash(), "nonce", tx.Nonce())
|
||||||
|
} else {
|
||||||
|
pm.knowLendingTxs.Add(tx.Hash(), struct{}{})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if pm.lendingpool != nil {
|
if pm.lendingpool != nil {
|
||||||
|
|
@ -850,11 +842,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
}
|
}
|
||||||
p.MarkVote(vote.Hash())
|
p.MarkVote(vote.Hash())
|
||||||
|
|
||||||
exist, _ := pm.knownVotes.ContainsOrAdd(vote.Hash(), true)
|
if pm.knownVotes.Contains(vote.Hash()) {
|
||||||
if !exist {
|
|
||||||
go pm.bft.Vote(p.id, &vote)
|
|
||||||
} else {
|
|
||||||
log.Trace("Discarded vote, known vote", "vote hash", vote.Hash(), "voted block hash", vote.ProposedBlockInfo.Hash.Hex(), "number", vote.ProposedBlockInfo.Number, "round", vote.ProposedBlockInfo.Round)
|
log.Trace("Discarded vote, known vote", "vote hash", vote.Hash(), "voted block hash", vote.ProposedBlockInfo.Hash.Hex(), "number", vote.ProposedBlockInfo.Number, "round", vote.ProposedBlockInfo.Round)
|
||||||
|
} else {
|
||||||
|
pm.knownVotes.Add(vote.Hash(), struct{}{})
|
||||||
|
go pm.bft.Vote(p.id, &vote)
|
||||||
}
|
}
|
||||||
|
|
||||||
case msg.Code == TimeoutMsg:
|
case msg.Code == TimeoutMsg:
|
||||||
|
|
@ -868,12 +860,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
}
|
}
|
||||||
p.MarkTimeout(timeout.Hash())
|
p.MarkTimeout(timeout.Hash())
|
||||||
|
|
||||||
exist, _ := pm.knownTimeouts.ContainsOrAdd(timeout.Hash(), true)
|
if pm.knownTimeouts.Contains(timeout.Hash()) {
|
||||||
|
|
||||||
if !exist {
|
|
||||||
go pm.bft.Timeout(p.id, &timeout)
|
|
||||||
} else {
|
|
||||||
log.Trace("Discarded Timeout, known Timeout", "Signature", timeout.Signature, "hash", timeout.Hash(), "round", timeout.Round)
|
log.Trace("Discarded Timeout, known Timeout", "Signature", timeout.Signature, "hash", timeout.Hash(), "round", timeout.Round)
|
||||||
|
} else {
|
||||||
|
pm.knownTimeouts.Add(timeout.Hash(), struct{}{})
|
||||||
|
go pm.bft.Timeout(p.id, &timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
case msg.Code == SyncInfoMsg:
|
case msg.Code == SyncInfoMsg:
|
||||||
|
|
@ -887,11 +878,11 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
|
||||||
}
|
}
|
||||||
p.MarkSyncInfo(syncInfo.Hash())
|
p.MarkSyncInfo(syncInfo.Hash())
|
||||||
|
|
||||||
exist, _ := pm.knownSyncInfos.ContainsOrAdd(syncInfo.Hash(), true)
|
if pm.knownSyncInfos.Contains(syncInfo.Hash()) {
|
||||||
if !exist {
|
|
||||||
go pm.bft.SyncInfo(p.id, &syncInfo)
|
|
||||||
} else {
|
|
||||||
log.Trace("Discarded SyncInfo, known SyncInfo", "hash", syncInfo.Hash())
|
log.Trace("Discarded SyncInfo, known SyncInfo", "hash", syncInfo.Hash())
|
||||||
|
} else {
|
||||||
|
pm.knownSyncInfos.Add(syncInfo.Hash(), struct{}{})
|
||||||
|
go pm.bft.SyncInfo(p.id, &syncInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -141,15 +141,14 @@ func AttachConsensusV1Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
||||||
if blockNumber%common.MergeSignRange == 0 {
|
if blockNumber%common.MergeSignRange == 0 {
|
||||||
mapBlockHash[bhash] = true
|
mapBlockHash[bhash] = true
|
||||||
}
|
}
|
||||||
signData, ok := adaptor.GetCachedSigningTxs(bhash)
|
signingTxs, ok := adaptor.GetCachedSigningTxs(bhash)
|
||||||
if !ok {
|
if !ok {
|
||||||
block := chain.GetBlock(bhash, blockNumber)
|
block := chain.GetBlock(bhash, blockNumber)
|
||||||
txs := block.Transactions()
|
txs := block.Transactions()
|
||||||
signData = adaptor.CacheSigningTxs(bhash, txs)
|
signingTxs = adaptor.CacheSigningTxs(bhash, txs)
|
||||||
}
|
}
|
||||||
txs := signData.([]*types.Transaction)
|
|
||||||
// Check signer signed?
|
// Check signer signed?
|
||||||
for _, tx := range txs {
|
for _, tx := range signingTxs {
|
||||||
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
||||||
from := *tx.From()
|
from := *tx.From()
|
||||||
if mapBlockHash[blkHash] {
|
if mapBlockHash[blkHash] {
|
||||||
|
|
|
||||||
|
|
@ -115,15 +115,14 @@ func AttachConsensusV2Hooks(adaptor *XDPoS.XDPoS, bc *core.BlockChain, chainConf
|
||||||
if blockNumber%common.MergeSignRange == 0 {
|
if blockNumber%common.MergeSignRange == 0 {
|
||||||
mapBlockHash[bhash] = true
|
mapBlockHash[bhash] = true
|
||||||
}
|
}
|
||||||
signData, ok := adaptor.GetCachedSigningTxs(bhash)
|
signingTxs, ok := adaptor.GetCachedSigningTxs(bhash)
|
||||||
if !ok {
|
if !ok {
|
||||||
block := chain.GetBlock(bhash, blockNumber)
|
block := chain.GetBlock(bhash, blockNumber)
|
||||||
txs := block.Transactions()
|
txs := block.Transactions()
|
||||||
signData = adaptor.CacheSigningTxs(bhash, txs)
|
signingTxs = adaptor.CacheSigningTxs(bhash, txs)
|
||||||
}
|
}
|
||||||
txs := signData.([]*types.Transaction)
|
|
||||||
// Check signer signed?
|
// Check signer signed?
|
||||||
for _, tx := range txs {
|
for _, tx := range signingTxs {
|
||||||
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
||||||
from := *tx.From()
|
from := *tx.From()
|
||||||
if mapBlockHash[blkHash] {
|
if mapBlockHash[blkHash] {
|
||||||
|
|
@ -245,15 +244,14 @@ func GetSigningTxCount(c *XDPoS.XDPoS, chain consensus.ChainReader, header *type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mapBlkHash[i] = header.Hash()
|
mapBlkHash[i] = header.Hash()
|
||||||
signData, ok := c.GetCachedSigningTxs(header.Hash())
|
signingTxs, ok := c.GetCachedSigningTxs(header.Hash())
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i)
|
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i)
|
||||||
block := chain.GetBlock(header.Hash(), i)
|
block := chain.GetBlock(header.Hash(), i)
|
||||||
txs := block.Transactions()
|
txs := block.Transactions()
|
||||||
signData = c.CacheSigningTxs(header.Hash(), txs)
|
signingTxs = c.CacheSigningTxs(header.Hash(), txs)
|
||||||
}
|
}
|
||||||
txs := signData.([]*types.Transaction)
|
for _, tx := range signingTxs {
|
||||||
for _, tx := range txs {
|
|
||||||
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
||||||
from := *tx.From()
|
from := *tx.From()
|
||||||
data[blkHash] = append(data[blkHash], from)
|
data[blkHash] = append(data[blkHash], from)
|
||||||
|
|
|
||||||
1
go.mod
1
go.mod
|
|
@ -15,7 +15,6 @@ require (
|
||||||
github.com/golang/protobuf v1.5.3
|
github.com/golang/protobuf v1.5.3
|
||||||
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb
|
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/hashicorp/golang-lru v0.5.4
|
|
||||||
github.com/holiman/uint256 v1.2.4
|
github.com/holiman/uint256 v1.2.4
|
||||||
github.com/huin/goupnp v1.3.0
|
github.com/huin/goupnp v1.3.0
|
||||||
github.com/jackpal/go-nat-pmp v1.0.2
|
github.com/jackpal/go-nat-pmp v1.0.2
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -92,8 +92,6 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
|
||||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
|
||||||
github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=
|
github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=
|
||||||
github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
|
github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/common/lru"
|
||||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core"
|
"github.com/XinFinOrg/XDPoSChain/core"
|
||||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||||
|
|
@ -35,7 +36,6 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/log"
|
"github.com/XinFinOrg/XDPoSChain/log"
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rlp"
|
"github.com/XinFinOrg/XDPoSChain/rlp"
|
||||||
lru "github.com/hashicorp/golang-lru"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -59,9 +59,9 @@ type LightChain struct {
|
||||||
mu sync.RWMutex
|
mu sync.RWMutex
|
||||||
chainmu sync.RWMutex
|
chainmu sync.RWMutex
|
||||||
|
|
||||||
bodyCache *lru.Cache // Cache for the most recent block bodies
|
bodyCache *lru.Cache[common.Hash, *types.Body]
|
||||||
bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format
|
bodyRLPCache *lru.Cache[common.Hash, rlp.RawValue]
|
||||||
blockCache *lru.Cache // Cache for the most recent entire blocks
|
blockCache *lru.Cache[common.Hash, *types.Block]
|
||||||
|
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
running int32 // running must be called automically
|
running int32 // running must be called automically
|
||||||
|
|
@ -76,17 +76,13 @@ type LightChain struct {
|
||||||
// available in the database. It initialises the default Ethereum header
|
// available in the database. It initialises the default Ethereum header
|
||||||
// validator.
|
// validator.
|
||||||
func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine) (*LightChain, error) {
|
func NewLightChain(odr OdrBackend, config *params.ChainConfig, engine consensus.Engine) (*LightChain, error) {
|
||||||
bodyCache, _ := lru.New(bodyCacheLimit)
|
|
||||||
bodyRLPCache, _ := lru.New(bodyCacheLimit)
|
|
||||||
blockCache, _ := lru.New(blockCacheLimit)
|
|
||||||
|
|
||||||
bc := &LightChain{
|
bc := &LightChain{
|
||||||
chainDb: odr.Database(),
|
chainDb: odr.Database(),
|
||||||
odr: odr,
|
odr: odr,
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
bodyCache: bodyCache,
|
bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
|
||||||
bodyRLPCache: bodyRLPCache,
|
bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit),
|
||||||
blockCache: blockCache,
|
blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit),
|
||||||
engine: engine,
|
engine: engine,
|
||||||
}
|
}
|
||||||
var err error
|
var err error
|
||||||
|
|
@ -218,9 +214,8 @@ func (lc *LightChain) State() (*state.StateDB, error) {
|
||||||
// or ODR service by hash, caching it if found.
|
// or ODR service by hash, caching it if found.
|
||||||
func (lc *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.Body, error) {
|
func (lc *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.Body, error) {
|
||||||
// Short circuit if the body's already in the cache, retrieve otherwise
|
// Short circuit if the body's already in the cache, retrieve otherwise
|
||||||
if cached, ok := lc.bodyCache.Get(hash); ok {
|
if cached, ok := lc.bodyCache.Get(hash); ok && cached != nil {
|
||||||
body := cached.(*types.Body)
|
return cached, nil
|
||||||
return body, nil
|
|
||||||
}
|
}
|
||||||
body, err := GetBody(ctx, lc.odr, hash, lc.hc.GetBlockNumber(hash))
|
body, err := GetBody(ctx, lc.odr, hash, lc.hc.GetBlockNumber(hash))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -236,7 +231,7 @@ func (lc *LightChain) GetBody(ctx context.Context, hash common.Hash) (*types.Bod
|
||||||
func (lc *LightChain) GetBodyRLP(ctx context.Context, hash common.Hash) (rlp.RawValue, error) {
|
func (lc *LightChain) GetBodyRLP(ctx context.Context, hash common.Hash) (rlp.RawValue, error) {
|
||||||
// Short circuit if the body's already in the cache, retrieve otherwise
|
// Short circuit if the body's already in the cache, retrieve otherwise
|
||||||
if cached, ok := lc.bodyRLPCache.Get(hash); ok {
|
if cached, ok := lc.bodyRLPCache.Get(hash); ok {
|
||||||
return cached.(rlp.RawValue), nil
|
return cached, nil
|
||||||
}
|
}
|
||||||
body, err := GetBodyRLP(ctx, lc.odr, hash, lc.hc.GetBlockNumber(hash))
|
body, err := GetBodyRLP(ctx, lc.odr, hash, lc.hc.GetBlockNumber(hash))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -258,8 +253,8 @@ func (lc *LightChain) HasBlock(hash common.Hash, number uint64) bool {
|
||||||
// caching it if found.
|
// caching it if found.
|
||||||
func (lc *LightChain) GetBlock(ctx context.Context, hash common.Hash, number uint64) (*types.Block, error) {
|
func (lc *LightChain) GetBlock(ctx context.Context, hash common.Hash, number uint64) (*types.Block, error) {
|
||||||
// Short circuit if the block's already in the cache, retrieve otherwise
|
// Short circuit if the block's already in the cache, retrieve otherwise
|
||||||
if block, ok := lc.blockCache.Get(hash); ok {
|
if block, ok := lc.blockCache.Get(hash); ok && block != nil {
|
||||||
return block.(*types.Block), nil
|
return block, nil
|
||||||
}
|
}
|
||||||
block, err := GetBlock(ctx, lc.odr, hash, number)
|
block, err := GetBlock(ctx, lc.odr, hash, number)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue