func (s *Store) readCommits(commitC <-chan *string, errorC <-chan error) {
	for data := range commitC {
		if data == nil {
			// done replaying log; new data incoming
			// OR signaled to load snapshot
			snapshot, err := s.snapshotter.Load()
			if err == snap.ErrNoSnapshot {
				return
			}
			if err != nil {
				log.Panic(err)
			}
			log.Printf("loading snapshot at term %d and index %d", snapshot.Metadata.Term, snapshot.Metadata.Index)
			if err := s.recoverFromSnapshot(snapshot.Data); err != nil {
				log.Panic(err)
			}
			continue
		}

		var nextTrans Transaction
		dec := gob.NewDecoder(bytes.NewBufferString(*data))
		if err := dec.Decode(&nextTrans); err != nil {
			log.Fatalf("could not decode message (%v)", err)
		}
		if nextTrans.Curr == "" {
			log.Printf("Dropping transaction with invalid currency")
			continue
		}

		if !nextTrans.Create {
			if !nextTrans.IsVerified() {
				log.Printf("Dropping transaction with bad signature")
				// discard transactions with invalid signatures
				continue
			}
			if err := s.CheckBalance(nextTrans.Src, nextTrans.Curr, nextTrans.Amount); err != nil {
				// discard transactions without enough funds
				log.Printf("Dropping transaction with bad balance: %s\n", err)
				continue
			}
		}

		s.mu.Lock()
		transfer := Account{nextTrans.Curr: nextTrans.Amount}
		destWallet := s.WalletStore[util.ToBytes(nextTrans.Dest)]
		if !nextTrans.Create {
			srcWallet := s.WalletStore[util.ToBytes(nextTrans.Src)]
			s.WalletStore[util.ToBytes(nextTrans.Src)] = srcWallet.Subtract(transfer)
		}
		s.WalletStore[util.ToBytes(nextTrans.Dest)] = destWallet.Subtract(transfer.Inverse())
		s.mu.Unlock()

		if walletFile, err := ReadWallet(); err == nil {
			if walletFile.Lookup(nextTrans.Src) != nil {
				fmt.Printf("Transfer of %v %s successfully sent to %x\n", nextTrans.Amount, nextTrans.Curr, nextTrans.Dest)
			}
			if walletFile.Lookup(nextTrans.Dest) != nil {
				if nextTrans.Create {
					fmt.Printf("You got money! Created %v %s successfully\n", nextTrans.Amount, nextTrans.Curr)
				} else {
					fmt.Printf("You got money! Transfer of %v %s successfully received from %x\n", nextTrans.Amount, nextTrans.Curr, nextTrans.Src)
				}
			}
		}
	}

	// after loading all the commits, we check the error stream
	// if all goes well, we should expect errorSent to be false
	if err, ok := <-errorC; ok {
		log.Fatal(err)
	}
}
// for each previous commit in the channel,
// apply it to the local state machine
for each previous commit in the channel,
apply it to the local state machine
// for each previous commit in the channel // apply it to the local state machine
func (s *Store) readCommits(commitC <-chan *string, errorC <-chan error) {
	for data := range commitC {
		if data == nil {
			snapshot, err := s.snapshotter.Load()
			if err == snap.ErrNoSnapshot {
				return
			}
			if err != nil {
				log.Panic(err)
			}
			log.Printf("loading snapshot at term %d and index %d", snapshot.Metadata.Term, snapshot.Metadata.Index)
			if err := s.recoverFromSnapshot(snapshot.Data); err != nil {
				log.Panic(err)
			}
			continue
		}
		var nextTrans Transaction
		dec := gob.NewDecoder(bytes.NewBufferString(*data))
		if err := dec.Decode(&nextTrans); err != nil {
			log.Fatalf("could not decode message (%v)", err)
		}
		if nextTrans.Curr == "" {
			log.Printf("Dropping transaction with invalid currency")
			continue
		}
		if !nextTrans.Create {
			if !nextTrans.IsVerified() {
				log.Printf("Dropping transaction with bad signature")
				continue
			}
			if err := s.CheckBalance(nextTrans.Src, nextTrans.Curr, nextTrans.Amount); err != nil {
				log.Printf("Dropping transaction with bad balance: %s\n", err)
				continue
			}
		}
		s.mu.Lock()
		transfer := Account{nextTrans.Curr: nextTrans.Amount}
		destWallet := s.WalletStore[util.ToBytes(nextTrans.Dest)]
		if !nextTrans.Create {
			srcWallet := s.WalletStore[util.ToBytes(nextTrans.Src)]
			s.WalletStore[util.ToBytes(nextTrans.Src)] = srcWallet.Subtract(transfer)
		}
		s.WalletStore[util.ToBytes(nextTrans.Dest)] = destWallet.Subtract(transfer.Inverse())
		s.mu.Unlock()
		if walletFile, err := ReadWallet(); err == nil {
			if walletFile.Lookup(nextTrans.Src) != nil {
				fmt.Printf("Transfer of %v %s successfully sent to %x\n", nextTrans.Amount, nextTrans.Curr, nextTrans.Dest)
			}
			if walletFile.Lookup(nextTrans.Dest) != nil {
				if nextTrans.Create {
					fmt.Printf("You got money! Created %v %s successfully\n", nextTrans.Amount, nextTrans.Curr)
				} else {
					fmt.Printf("You got money! Transfer of %v %s successfully received from %x\n", nextTrans.Amount, nextTrans.Curr, nextTrans.Src)
				}
			}
		}
	}
	if err, ok := <-errorC; ok {
		log.Fatal(err)
	}
}
func ( s * Store ) readCommits ( commitC <- chan * string , errorC <- chan error ) { for data := range commitC { if data == nil { snapshot , err := s . snapshotter . Load ( ) if err == snap . ErrNoSnapshot { return } if err != nil { log . Panic ( err ) } log . Printf ( " " , snapshot . Metadata . Term , snapshot . Metadata . Index ) if err := s . recoverFromSnapshot ( snapshot . Data ) ; err != nil { log . Panic ( err ) } continue } var nextTrans Transaction dec := gob . NewDecoder ( bytes . NewBufferString ( * data ) ) if err := dec . Decode ( & nextTrans ) ; err != nil { log . Fatalf ( " " , err ) } if nextTrans . Curr == " " { log . Printf ( " " ) continue } if ! nextTrans . Create { if ! nextTrans . IsVerified ( ) { log . Printf ( " " ) continue } if err := s . CheckBalance ( nextTrans . Src , nextTrans . Curr , nextTrans . Amount ) ; err != nil { log . Printf ( " \n " , err ) continue } } s . mu . Lock ( ) transfer := Account { nextTrans . Curr : nextTrans . Amount } destWallet := s . WalletStore [ util . ToBytes ( nextTrans . Dest ) ] if ! nextTrans . Create { srcWallet := s . WalletStore [ util . ToBytes ( nextTrans . Src ) ] s . WalletStore [ util . ToBytes ( nextTrans . Src ) ] = srcWallet . Subtract ( transfer ) } s . WalletStore [ util . ToBytes ( nextTrans . Dest ) ] = destWallet . Subtract ( transfer . Inverse ( ) ) s . mu . Unlock ( ) if walletFile , err := ReadWallet ( ) ; err == nil { if walletFile . Lookup ( nextTrans . Src ) != nil { fmt . Printf ( " \n " , nextTrans . Amount , nextTrans . Curr , nextTrans . Dest ) } if walletFile . Lookup ( nextTrans . Dest ) != nil { if nextTrans . Create { fmt . Printf ( " \n " , nextTrans . Amount , nextTrans . Curr ) } else { fmt . Printf ( " \n " , nextTrans . Amount , nextTrans . Curr , nextTrans . Src ) } } } } if err , ok := <- errorC ; ok { log . Fatal ( err ) } }
for each previous commit in the channel,
apply it to the local state machine
for each previous commit in the channel apply it to the local state machine
// done replaying log; new data incoming // OR signaled to load snapshot // discard transactions with invalid signatures // discard transactions without enough funds // after loading all the commits, we check the error stream // if all goes well, we should expect errorSent to be false