github.com/annchain/OG@v0.0.9/og/syncer/sync_buffer.go (about) 1 // Copyright © 2019 Annchain Authors <EMAIL ADDRESS> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package syncer 15 16 import ( 17 "errors" 18 "fmt" 19 types2 "github.com/annchain/OG/arefactor/og/types" 20 "github.com/annchain/OG/og/types" 21 "github.com/annchain/OG/ogcore/pool" 22 23 "github.com/annchain/OG/protocol" 24 "github.com/sirupsen/logrus" 25 "sync" 26 "sync/atomic" 27 28 "github.com/annchain/OG/og" 29 ) 30 31 var MaxBufferSiza = 4096 * 16 32 33 type SyncBuffer struct { 34 Txs map[types2.Hash]types.Txi 35 TxsList types2.Hashes 36 Seq *types.Sequencer 37 mu sync.RWMutex 38 txPool pool.ITxPool 39 dag og.IDag 40 acceptTxs uint32 41 quitHandel bool 42 Verifiers []protocol.Verifier 43 } 44 45 type SyncBufferConfig struct { 46 TxPool pool.ITxPool 47 Verifiers []protocol.Verifier 48 Dag og.IDag 49 } 50 51 func DefaultSyncBufferConfig(txPool pool.ITxPool, dag og.IDag, Verifiers []protocol.Verifier) SyncBufferConfig { 52 config := SyncBufferConfig{ 53 TxPool: txPool, 54 Dag: dag, 55 Verifiers: Verifiers, 56 } 57 return config 58 } 59 60 func (s *SyncBuffer) Name() string { 61 return "SyncBuffer" 62 } 63 64 func NewSyncBuffer(config SyncBufferConfig) *SyncBuffer { 65 s := &SyncBuffer{ 66 Txs: make(map[types2.Hash]types.Txi), 67 txPool: config.TxPool, 68 dag: config.Dag, 69 Verifiers: config.Verifiers, 70 } 71 return s 72 } 73 74 func (s *SyncBuffer) Start() { 75 log.Info("Syncbuffer started") 76 } 77 78 func (s *SyncBuffer) Stop() { 79 log.Info("Syncbuffer will stop") 80 s.quitHandel = true 81 } 82 83 // range map is random value ,so store hashs using slice 84 func (s *SyncBuffer) addTxs(txs types.Txis, seq *types.Sequencer) error { 85 s.mu.Lock() 86 defer s.mu.Unlock() 87 s.Seq = seq 88 for _, tx := range txs { 89 if len(s.Txs) > MaxBufferSiza { 90 return fmt.Errorf("too much txs") 91 } 92 if tx == nil { 93 log.Debug("nil tx") 94 continue 95 } 96 if _, ok := s.Txs[tx.GetHash()]; !ok { 97 98 s.Txs[tx.GetHash()] = tx 99 } 100 s.TxsList = append(s.TxsList, tx.GetHash()) 101 } 102 return nil 103 104 } 105 106 func (s *SyncBuffer) AddTxs(seq *types.Sequencer, txs types.Txis) error { 107 if atomic.LoadUint32(&s.acceptTxs) == 0 { 108 atomic.StoreUint32(&s.acceptTxs, 1) 109 defer atomic.StoreUint32(&s.acceptTxs, 0) 110 s.clean() 111 if seq == nil { 112 err := fmt.Errorf("nil sequencer") 113 log.WithError(err).Debug("add txs error") 114 return err 115 } 116 if seq.Height != s.dag.LatestSequencer().Height+1 { 117 log.WithField("latests seq height ", s.dag.LatestSequencer().Height).WithField( 118 "seq height", seq.Height).Warn("id mismatch") 119 return nil 120 } 121 err := s.addTxs(txs, seq) 122 if err != nil { 123 log.WithError(err).Debug("add txs error") 124 return err 125 } 126 err = s.Handle() 127 if err != nil { 128 logrus.WithError(err).WithField("txs ", txs).WithField("seq ", seq).Warn("handle tx error") 129 } 130 return err 131 132 } else { 133 err := fmt.Errorf("addtx busy") 134 return err 135 } 136 } 137 138 func (s *SyncBuffer) Count() int { 139 s.mu.RLock() 140 defer s.mu.RUnlock() 141 142 return len(s.Txs) 143 } 144 145 func (s *SyncBuffer) Get(hash types2.Hash) types.Txi { 146 s.mu.RLock() 147 defer s.mu.RUnlock() 148 return s.Txs[hash] 149 150 } 151 152 func (s *SyncBuffer) GetAllKeys() types2.Hashes { 153 s.mu.RLock() 154 defer s.mu.RUnlock() 155 var keys types2.Hashes 156 for k := range s.Txs { 157 keys = append(keys, k) 158 } 159 return keys 160 } 161 162 func (s *SyncBuffer) clean() { 163 s.mu.Lock() 164 defer s.mu.Unlock() 165 for k := range s.Txs { 166 delete(s.Txs, k) 167 } 168 s.TxsList = nil 169 } 170 171 func (s *SyncBuffer) Handle() error { 172 if s.quitHandel { 173 return nil 174 } 175 count := s.Count() 176 log.WithField("txs len", count).WithField("seq", s.Seq).Trace("handle txs start") 177 err := s.verifyElders(s.Seq) 178 if err != nil { 179 log.WithField("txlist ", s.TxsList).WithField("seq ", s.Seq).WithError(err).Warn("handle fail") 180 return err 181 } 182 log.WithField("len ", len(s.Verifiers)).Debug("len sync buffer verifier") 183 for _, hash := range s.TxsList { 184 tx := s.Get(hash) 185 if tx == nil { 186 panic("never come here") 187 } 188 //if tx is already in txbool ,no need to verify again 189 if s.txPool.IsLocalHash(hash) { 190 continue 191 } 192 for _, verifier := range s.Verifiers { 193 if !verifier.Verify(tx) { 194 log.WithField("tx", tx).Warn("bad tx") 195 err = errors.New("bad tx format") 196 goto out 197 } 198 } 199 //need to feedback to buffer 200 err = s.txPool.AddRemoteTx(tx, false) 201 if err != nil { 202 //this transaction received by broadcast ,so don't return err 203 if err == types.ErrDuplicateTx { 204 err = nil 205 continue 206 } else { 207 goto out 208 } 209 } 210 } 211 212 out: 213 if err == nil { 214 log.WithField("id", s.Seq).Trace("before add seq") 215 for _, verifier := range s.Verifiers { 216 if !verifier.Verify(s.Seq) { 217 log.WithField("tx", s.Seq).Warn("bad seq") 218 err = errors.New("bad seq format") 219 } 220 } 221 if err == nil { 222 err = s.txPool.AddRemoteTx(s.Seq, false) 223 log.WithField("id", s.Seq).Trace("after add seq") 224 } 225 } 226 if err != nil { 227 log.WithField("seq ", s.Seq).WithError(err).Warn("handel fail") 228 //panic("handle fail for test") 229 } else { 230 log.WithField("txs len", count).WithField("seq ", s.Seq).Debug("handle txs done") 231 232 } 233 return err 234 } 235 236 func (s *SyncBuffer) verifyElders(seq types.Txi) error { 237 238 allKeys := s.GetAllKeys() 239 keysMap := make(map[types2.Hash]int) 240 for _, k := range allKeys { 241 keysMap[k] = 1 242 } 243 244 inSeekingPool := map[types2.Hash]int{} 245 seekingPool := types2.Hashes{} 246 for _, parentHash := range seq.GetParents() { 247 seekingPool = append(seekingPool, parentHash) 248 // seekingPool.PushBack(parentHash) 249 } 250 for len(seekingPool) > 0 { 251 elderHash := seekingPool[0] 252 seekingPool = seekingPool[1:] 253 // elderHash := seekingPool.Remove(seekingPool.Front()).(common.Hash) 254 255 elder := s.Get(elderHash) 256 if elder == nil { 257 if s.txPool.IsLocalHash(elderHash) { 258 continue 259 } 260 err := fmt.Errorf("parent not found") 261 log.WithField("hash", elderHash.String()).Warn("parent not found") 262 return err 263 } 264 delete(keysMap, elderHash) 265 for _, elderParentHash := range elder.GetParents() { 266 if _, in := inSeekingPool[elderParentHash]; !in { 267 seekingPool = append(seekingPool, elderParentHash) 268 // seekingPool.PushBack(elderParentHash) 269 inSeekingPool[elderParentHash] = 0 270 } 271 } 272 } 273 if len(keysMap) != 0 { 274 err := fmt.Errorf("txs number mismatch,redundent txs %d", len(allKeys)) 275 return err 276 } 277 return nil 278 }