blockchain sandbox: UTXO chain, p2p mining, attacker node
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"blockchain/config"
|
||||
"crypto/ed25519"
|
||||
"slices"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Mempool struct {
|
||||
transations []*Transaction
|
||||
mx sync.Mutex
|
||||
}
|
||||
|
||||
func NewMempool() *Mempool {
|
||||
return &Mempool{}
|
||||
}
|
||||
|
||||
func (m *Mempool) Add(tx *Transaction) {
|
||||
if !tx.Verify() {
|
||||
return
|
||||
}
|
||||
m.mx.Lock()
|
||||
m.transations = append(m.transations, tx)
|
||||
m.mx.Unlock()
|
||||
}
|
||||
|
||||
func (m *Mempool) Len() int {
|
||||
m.mx.Lock()
|
||||
defer m.mx.Unlock()
|
||||
|
||||
return len(m.transations)
|
||||
}
|
||||
|
||||
func (m *Mempool) CollectBlock(miner ed25519.PublicKey) []*Transaction {
|
||||
m.mx.Lock()
|
||||
defer m.mx.Unlock()
|
||||
|
||||
txs := []*Transaction{NewCoinbaseTransaction(miner, config.Default.Chain.MiningReward)}
|
||||
spent := make(map[string]struct{})
|
||||
|
||||
isSpent := func(s CoinSpend) bool {
|
||||
_, ok := spent[s.CoinID.Key()]
|
||||
return ok
|
||||
}
|
||||
|
||||
for _, tx := range m.transations {
|
||||
if slices.ContainsFunc(tx.Spends, isSpent) {
|
||||
continue
|
||||
}
|
||||
|
||||
txs = append(txs, tx)
|
||||
|
||||
for _, s := range tx.Spends {
|
||||
spent[s.CoinID.Key()] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
return txs
|
||||
}
|
||||
|
||||
func (m *Mempool) RemoveMined(block *Block) {
|
||||
spent := make(map[string]struct{})
|
||||
for _, tx := range block.Transactions {
|
||||
if tx.IsCoinbase() {
|
||||
continue
|
||||
}
|
||||
for _, s := range tx.Spends {
|
||||
spent[s.CoinID.Key()] = struct{}{}
|
||||
}
|
||||
}
|
||||
if len(spent) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
m.mx.Lock()
|
||||
defer m.mx.Unlock()
|
||||
|
||||
isSpent := func(s CoinSpend) bool {
|
||||
_, ok := spent[s.CoinID.Key()]
|
||||
return ok
|
||||
}
|
||||
|
||||
m.transations = slices.DeleteFunc(m.transations, func(tx *Transaction) bool {
|
||||
return slices.ContainsFunc(tx.Spends, isSpent)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user