Implement basic mempool
This commit is contained in:
parent
d9a0fa9194
commit
7f85330953
5
consensus/policy/policy.go
Normal file
5
consensus/policy/policy.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package policy
|
||||||
|
|
||||||
|
const (
|
||||||
|
BlockMaxTransactionCount = 100
|
||||||
|
)
|
93
pool/mempool.go
Normal file
93
pool/mempool.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package pool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"sort"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Secured-Finance/dione/consensus/policy"
|
||||||
|
|
||||||
|
"github.com/Secured-Finance/dione/types"
|
||||||
|
|
||||||
|
"github.com/Secured-Finance/dione/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultTxTTL = 10 * time.Minute
|
||||||
|
DefaultTxPrefix = "tx_"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Mempool struct {
|
||||||
|
m sync.RWMutex
|
||||||
|
cache cache.Cache
|
||||||
|
txDescriptors []string // list of txs in cache
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMempool(c cache.Cache) (*Mempool, error) {
|
||||||
|
mp := &Mempool{
|
||||||
|
cache: c,
|
||||||
|
}
|
||||||
|
|
||||||
|
var txDesc []string
|
||||||
|
err := c.Get("tx_list", &txDesc)
|
||||||
|
if err != nil || err != cache.ErrNilValue {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
mp.txDescriptors = txDesc
|
||||||
|
|
||||||
|
return mp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mp *Mempool) StoreTx(tx *types.Transaction) error {
|
||||||
|
mp.m.Lock()
|
||||||
|
defer mp.m.Unlock()
|
||||||
|
|
||||||
|
hashStr := hex.EncodeToString(tx.Hash)
|
||||||
|
err := mp.cache.StoreWithTTL(DefaultTxPrefix+hashStr, tx, DefaultTxTTL)
|
||||||
|
mp.txDescriptors = append(mp.txDescriptors, hashStr)
|
||||||
|
mp.cache.Store("tx_list", mp.txDescriptors) // update tx list in cache
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mp *Mempool) GetTxsForNewBlock() []*types.Transaction {
|
||||||
|
mp.m.Lock()
|
||||||
|
defer mp.m.Unlock()
|
||||||
|
|
||||||
|
var txForBlock []*types.Transaction
|
||||||
|
var allTxs []*types.Transaction
|
||||||
|
|
||||||
|
for i, v := range mp.txDescriptors {
|
||||||
|
var tx types.Transaction
|
||||||
|
err := mp.cache.Get(DefaultTxPrefix+v, &tx)
|
||||||
|
if err != nil {
|
||||||
|
if err == cache.ErrNilValue {
|
||||||
|
// descriptor is broken
|
||||||
|
// delete it and update list
|
||||||
|
mp.txDescriptors = removeItemFromStringSlice(mp.txDescriptors, i)
|
||||||
|
mp.cache.Store("tx_list", mp.txDescriptors) // update tx list in cache
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
allTxs = append(allTxs, &tx)
|
||||||
|
}
|
||||||
|
sort.Slice(allTxs, func(i, j int) bool {
|
||||||
|
return allTxs[i].Timestamp.Before(allTxs[j].Timestamp)
|
||||||
|
})
|
||||||
|
|
||||||
|
for i := 0; i < policy.BlockMaxTransactionCount; i++ {
|
||||||
|
if len(allTxs) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
tx := allTxs[0] // get oldest tx
|
||||||
|
allTxs = allTxs[1:] // pop tx
|
||||||
|
txForBlock = append(txForBlock, tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
return txForBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeItemFromStringSlice(s []string, i int) []string {
|
||||||
|
s[len(s)-1], s[i] = s[i], s[len(s)-1]
|
||||||
|
return s[:len(s)-1]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user