Example #1
0
func NewMempool(proxyAppCtx proxy.AppContext) *Mempool {
	mempool := &Mempool{
		proxyAppCtx: proxyAppCtx,
		txs:         clist.New(),
		counter:     0,
		height:      0,
		expected:    nil,

		cacheMap:  make(map[string]struct{}, cacheSize),
		cacheList: list.New(),
	}
	proxyAppCtx.SetResponseCallback(mempool.resCb)
	return mempool
}
Example #2
0
// Execute the block to mutate State.
// Also, execute txs on the proxyAppCtx and validate apphash
// Rolls back before executing transactions.
// Rolls back if invalid, but never commits.
func (s *State) ExecBlock(proxyAppCtx proxy.AppContext, block *types.Block, blockPartsHeader types.PartSetHeader) error {

	// Validate the block.
	err := s.validateBlock(block)
	if err != nil {
		return err
	}

	// Update the validator set
	valSet := s.Validators.Copy()
	// Update valSet with signatures from block.
	updateValidatorsWithBlock(s.LastValidators, valSet, block)
	// TODO: Update the validator set (e.g. block.Data.ValidatorUpdates?)
	nextValSet := valSet.Copy()

	// First, rollback.
	proxyAppCtx.RollbackSync()

	// Execute, or rollback. (Does not commit)
	err = s.execBlockOnProxyApp(proxyAppCtx, block)
	if err != nil {
		proxyAppCtx.RollbackSync()
		return err
	}

	// All good!
	nextValSet.IncrementAccum(1)
	s.Validators = nextValSet
	s.LastValidators = valSet
	s.LastAppHash = block.AppHash
	s.LastBlockHeight = block.Height
	s.LastBlockHash = block.Hash()
	s.LastBlockParts = blockPartsHeader
	s.LastBlockTime = block.Time

	return nil
}
Example #3
0
// Executes transactions on proxyAppCtx.
func (s *State) execBlockOnProxyApp(proxyAppCtx proxy.AppContext, block *types.Block) error {
	// Execute transactions and get hash
	var invalidTxErr error
	proxyCb := func(req tmsp.Request, res tmsp.Response) {
		switch res := res.(type) {
		case tmsp.ResponseAppendTx:
			reqAppendTx := req.(tmsp.RequestAppendTx)
			if res.RetCode != tmsp.RetCodeOK {
				if invalidTxErr == nil {
					invalidTxErr = InvalidTxError{reqAppendTx.TxBytes, res.RetCode}
				}
			}
		case tmsp.ResponseEvent:
			s.evc.FireEvent(types.EventStringApp(), types.EventDataApp{res.Key, res.Data})
		}
	}
	proxyAppCtx.SetResponseCallback(proxyCb)
	for _, tx := range block.Data.Txs {
		proxyAppCtx.AppendTxAsync(tx)
		if err := proxyAppCtx.Error(); err != nil {
			return err
		}
	}
	hash, err := proxyAppCtx.GetHashSync()
	if err != nil {
		log.Warn("Error computing proxyAppCtx hash", "error", err)
		return err
	}
	if invalidTxErr != nil {
		log.Warn("Invalid transaction in block")
		return invalidTxErr
	}

	// Check that appHash matches
	if !bytes.Equal(block.AppHash, hash) {
		log.Warn(Fmt("App hash in proposal was %X, computed %X instead", block.AppHash, hash))
		return InvalidAppHashError{block.AppHash, hash}
	}

	return nil
}
Example #4
0
// Commits block on proxyAppCtx.
func (s *State) Commit(proxyAppCtx proxy.AppContext) error {
	err := proxyAppCtx.CommitSync()
	return err
}