Invalid receipts with empty LogField
entries may be assigned
Description
The buildLogFields
function in sdk/app.go converts log fields given in native types, packaged as LogFieldData
, into the LogField
type that is usable within the circuits. It is implemented as follows:
func buildLogFields(fs [NumMaxLogFields]LogFieldData) (fields [NumMaxLogFields]LogField) {
empty := LogFieldData{}
lastNonEmpty := fs[0]
for i := 0; i < NumMaxLogFields; i++ {
// Due to backend circuit's limitations, we must fill []LogField with valid data
// up to NumMaxLogFields. If the user actually only wants less NumMaxLogFields
// log fields, then we simply copy the previous log field in the list to fill the
// empty spots.
f := fs[i]
if i > 0 && f == empty {
f = lastNonEmpty
} else {
lastNonEmpty = f
}
fields[i] = LogField{
// ...
}
}
return
}
The comment explains that the backend requires valid data in each entry. The idea to deal with this is to populate empty entries with duplicates of a valid one. This is implemented by setting lastNonEmpty
to the first entry before the loop, updating it to the current entry whenever it is nonempty, and assigning lastNonEmpty
to the result at empty slots.
However, this will not work as intended if the very first entry is empty, and in this case, the first entry of the result will be empty as well.
Impact
The comment suggests that the backend will not be able to handle nonvalid LogFieldData
entries and due to this, buildLogFields
should ensure this does not happen. However, the current implementation fails to ensure this when the first LogFieldData
entry is an empty entry.
This could plausibly happen if the user looked up a transaction by transaction hash that did not happen to emit any logs.
Recommendations
We recommend to check whether the first entry is empty in buildLogFields
and panic if so, with an error message indicating that the user should not add receipts starting with an empty log field.
This will make it easier for the users to catch this issue early, before submitting to the Brevis backend, causing unnecessary costs. It may also be possible to catch this problem even earlier by filtering out such completely empty transactions.
Remediation
This issue has been acknowledged by Brevis, and a fix was implemented in commit 1b266347↗.