go-ethereum/libevm/precompiles/parallel/eventual.go
Arran Schlosberg 98a792673a
feat: parallel package for precompile pre-processing (#228)
## Why this should be merged

EVM parallel co-processors that interface with the regular transaction
path via precompiles.

## How this works

Introduces the `parallel.Processor`, which orchestrates a set of
`parallel.Handler`s. Each `Handler` performs arbitrary, strongly typed
processing of any sub-set of transactions in a block and makes its
results available to a precompile and/or a post-block method for
persisting state. Although stateful, `Handler`s can only read the
pre-block and post-block state, which isolates them from conflicts with
the regular transaction path.

There is deliberately no support for a precompile to "write" to a
`Handler`, only to "read". This is because the transaction might still
revert, which would also have to be communicated to the `Handler`,
resulting in unnecessary complexity. Logs/events are the recommended
approach for precompile -> `Handler` communication, to be read from the
`types.Receipts` at the end of the block.

## How this was tested

Integration tests covering:

1. Selection of transactions to process + end-to-end plumbing of data
through a `Handler`.
2. Registration as a precompile, exercised with actual transaction
processing, and demonstrating log + return-data correctness.

---------

Signed-off-by: Arran Schlosberg <519948+ARR4N@users.noreply.github.com>
2026-02-18 12:02:13 +00:00

52 lines
1.8 KiB
Go

// Copyright 2025-2026 the libevm authors.
//
// The libevm additions to go-ethereum are free software: you can redistribute
// them and/or modify them under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// The libevm additions are distributed in the hope that they will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
// General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see
// <http://www.gnu.org/licenses/>.
package parallel
// An eventual type holds a value that is set at some unknown point in the
// future and used, possibly concurrently, by one or more peekers or a single
// taker (together, "getters"). The zero value is NOT ready for use.
type eventual[T any] struct {
ch chan T
}
// eventually returns a new eventual value.
func eventually[T any]() eventual[T] {
return eventual[T]{
ch: make(chan T, 1),
}
}
// put sets the value, unblocking any current and future getters. put itself is
// non-blocking, however it is NOT possible to overwrite the value without an
// intervening call to [eventual.take].
func (e eventual[T]) put(v T) {
e.ch <- v
}
// peek returns the value after making it available for other getters. Although
// the act of peeking is threadsafe, the returned value might not be.
func (e eventual[T]) peek() T {
v := <-e.ch
e.ch <- v
return v
}
// take returns the value and resets e to its default state as if immediately
// after construction.
func (e eventual[T]) take() T {
return <-e.ch
}