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) }) }