Skip to content

Commit

Permalink
dao: fix transaction application log decoding
Browse files Browse the repository at this point in the history
Conflict record stub has value of 5 bytes length: 1 byte for
storage.ExecTransaction prefix and 4 bytes for the block index LE. This
scheme was implemented in #3138, and this commit should be a part of
this PR.

Also, transaction.DummyVersion is removed since it's unused anymore.

Close #3426. The reason of `failed to locate application log: EOF` error
during genesis AER request is in the following: genesis executable was
overwritten by conflict record stub produced by transaction
0x289c235dcdab8be7426d05f0fbb5e86c619f81481ea136493fa95deee5dbb7cc (ref.
 #3427). As a consequence, an attempt to decode transaction AER was
initited, but conflict record scheme was changed in #3138.

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
  • Loading branch information
AnnaShaleva committed May 15, 2024
1 parent e6ceee0 commit 0c446d9
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 7 deletions.
9 changes: 5 additions & 4 deletions pkg/core/dao/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ func (dao *Simple) GetTxExecResult(hash util.Uint256) (uint32, *transaction.Tran
// decodeTxAndExecResult decodes transaction, its height and execution result from
// the given executable bytes. It performs no executable prefix check.
func decodeTxAndExecResult(buf []byte) (uint32, *transaction.Transaction, *state.AppExecResult, error) {
if len(buf) >= 6 && buf[5] == transaction.DummyVersion {
if len(buf) == 1+4 { // conflict record stub.
return 0, nil, nil, storage.ErrKeyNotFound
}
r := io.NewBinReaderFromBuf(buf)
Expand Down Expand Up @@ -605,7 +605,7 @@ func (dao *Simple) DeleteHeaderHashes(since uint32, batchSize int) {
}

// GetTransaction returns Transaction and its height by the given hash
// if it exists in the store. It does not return dummy transactions.
// if it exists in the store. It does not return conflict record stubs.
func (dao *Simple) GetTransaction(hash util.Uint256) (*transaction.Transaction, uint32, error) {
key := dao.makeExecutableKey(hash)
b, err := dao.Store.Get(key)
Expand Down Expand Up @@ -844,8 +844,9 @@ func (dao *Simple) StoreAsCurrentBlock(block *block.Block) {
dao.Store.Put(dao.mkKeyPrefix(storage.SYSCurrentBlock), buf.Bytes())
}

// StoreAsTransaction stores the given TX as DataTransaction. It also stores transactions
// the given tx has conflicts with as DataTransaction with dummy version. It can reuse the given
// StoreAsTransaction stores the given TX as DataTransaction. It also stores conflict records
// (hashes of transactions the given tx has conflicts with) as DataTransaction with value containing
// only five bytes: 1-byte [storage.ExecTransaction] executable prefix + 4-bytes-LE block index. It can reuse the given
// buffer for the purpose of value serialization.
func (dao *Simple) StoreAsTransaction(tx *transaction.Transaction, index uint32, aer *state.AppExecResult) error {
key := dao.makeExecutableKey(tx.Hash())
Expand Down
4 changes: 1 addition & 3 deletions pkg/core/transaction/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ const (
// MaxAttributes is maximum number of attributes including signers that can be contained
// within a transaction. It is set to be 16.
MaxAttributes = 16
// DummyVersion represents reserved transaction version for trimmed transactions.
DummyVersion = 255
)

// ErrInvalidWitnessNum returns when the number of witnesses does not match signers.
Expand Down Expand Up @@ -408,7 +406,7 @@ var (

// isValid checks whether decoded/unmarshalled transaction has all fields valid.
func (t *Transaction) isValid() error {
if t.Version > 0 && t.Version != DummyVersion {
if t.Version > 0 {
return ErrInvalidVersion
}
if t.SystemFee < 0 {
Expand Down

0 comments on commit 0c446d9

Please sign in to comment.