update kvstore to mark transactions as replacements

This commit is contained in:
William Banfield
2022-08-18 14:05:11 -04:00
parent b3a507bb08
commit 8bcfc626ca
3 changed files with 26 additions and 3 deletions

View File

@@ -7,4 +7,5 @@ const (
CodeTypeBadNonce uint32 = 2
CodeTypeUnauthorized uint32 = 3
CodeTypeUnknownError uint32 = 4
CodeTypeExecuted uint32 = 5
)

View File

@@ -68,6 +68,7 @@ type Application struct {
state State
RetainBlocks int64 // blocks to retain after commit (via ResponseCommit.RetainHeight)
txToRemove map[string]struct{}
}
func NewApplication() *Application {
@@ -87,6 +88,9 @@ func (app *Application) Info(req types.RequestInfo) (resInfo types.ResponseInfo)
// tx is either "key=value" or just arbitrary bytes
func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx {
if isReplacedTx(req.Tx) {
app.txToRemove[string(req.Tx)] = struct{}{}
}
var key, value []byte
parts := bytes.Split(req.Tx, []byte("="))
if len(parts) == 2 {
@@ -117,6 +121,11 @@ func (app *Application) DeliverTx(req types.RequestDeliverTx) types.ResponseDeli
}
func (app *Application) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx {
if req.Type == types.CheckTxType_Recheck {
if _, ok := app.txToRemove[string(req.Tx)]; ok {
return types.ResponseCheckTx{Code: code.CodeTypeExecuted, GasWanted: 1}
}
}
return types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1}
}
@@ -126,6 +135,9 @@ func (app *Application) Commit() types.ResponseCommit {
binary.PutVarint(appHash, app.state.Size)
app.state.AppHash = appHash
app.state.Height++
// empty out the set of transactions to remove via rechecktx
app.txToRemove = map[string]struct{}{}
saveState(app.state)
resp := types.ResponseCommit{Data: appHash}

View File

@@ -45,7 +45,10 @@ func NewPersistentKVStoreApplication(dbDir string) *PersistentKVStoreApplication
state := loadState(db)
return &PersistentKVStoreApplication{
app: &Application{state: state},
app: &Application{
state: state,
txToRemove: map[string]struct{}{},
},
valAddrToPubKeyMap: make(map[string]pc.PublicKey),
logger: log.NewNopLogger(),
}
@@ -302,12 +305,19 @@ func (app *PersistentKVStoreApplication) updateValidator(v types.ValidatorUpdate
// -----------------------------
const PreparePrefix = "prepare"
const (
PreparePrefix = "prepare"
ReplacePrefix = "replace"
)
func isPrepareTx(tx []byte) bool {
return bytes.HasPrefix(tx, []byte(PreparePrefix))
}
func isReplacedTx(tx []byte) bool {
return bytes.HasPrefix(tx, []byte(ReplacePrefix))
}
// execPrepareTx is noop. tx data is considered as placeholder
// and is substitute at the PrepareProposal.
func (app *PersistentKVStoreApplication) execPrepareTx(tx []byte) types.ResponseDeliverTx {
@@ -323,7 +333,7 @@ func (app *PersistentKVStoreApplication) substPrepareTx(blockData [][]byte, maxT
for _, tx := range blockData {
txMod := tx
if isPrepareTx(tx) {
txMod = bytes.TrimPrefix(tx, []byte(PreparePrefix))
txMod = bytes.Replace(tx, []byte(PreparePrefix), []byte(ReplacePrefix), 1)
}
totalBytes += int64(len(txMod))
if totalBytes > maxTxBytes {