2022-06-13 13:43:09 +00:00
package builder
import (
"sync"
"sync/atomic"
2022-10-14 23:12:38 +00:00
"time"
2022-06-13 13:43:09 +00:00
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/log/v3"
)
type BlockBuilderFunc func ( param * core . BlockBuilderParameters , interrupt * int32 ) ( * types . Block , error )
// BlockBuilder wraps a goroutine that builds Proof-of-Stake payloads (PoS "mining")
type BlockBuilder struct {
2022-12-01 08:15:01 +00:00
interrupt int32
syncCond * sync . Cond
block * types . Block
err error
2022-06-13 13:43:09 +00:00
}
2022-12-01 08:15:01 +00:00
func NewBlockBuilder ( build BlockBuilderFunc , param * core . BlockBuilderParameters ) * BlockBuilder {
2022-06-13 13:43:09 +00:00
b := new ( BlockBuilder )
b . syncCond = sync . NewCond ( new ( sync . Mutex ) )
go func ( ) {
2022-10-19 09:38:03 +00:00
log . Info ( "Building block..." )
2022-10-14 23:12:38 +00:00
t := time . Now ( )
2022-06-13 13:43:09 +00:00
block , err := build ( param , & b . interrupt )
2022-10-19 09:38:03 +00:00
if err != nil {
log . Warn ( "Failed to build a block" , "err" , err )
} else {
log . Info ( "Built block" , "hash" , block . Hash ( ) , "height" , block . NumberU64 ( ) , "txs" , len ( block . Transactions ( ) ) , "gas used %" , 100 * float64 ( block . GasUsed ( ) ) / float64 ( block . GasLimit ( ) ) , "time" , time . Since ( t ) )
}
2022-06-13 13:43:09 +00:00
b . syncCond . L . Lock ( )
defer b . syncCond . L . Unlock ( )
b . block = block
b . err = err
b . syncCond . Broadcast ( )
} ( )
return b
}
2022-12-01 08:15:01 +00:00
func ( b * BlockBuilder ) Stop ( ) ( * types . Block , error ) {
2022-06-13 13:43:09 +00:00
atomic . StoreInt32 ( & b . interrupt , 1 )
b . syncCond . L . Lock ( )
defer b . syncCond . L . Unlock ( )
for b . block == nil && b . err == nil {
b . syncCond . Wait ( )
}
2022-12-01 08:15:01 +00:00
return b . block , b . err
2022-06-13 13:43:09 +00:00
}
2022-08-15 08:19:45 +00:00
func ( b * BlockBuilder ) Block ( ) * types . Block {
b . syncCond . L . Lock ( )
defer b . syncCond . L . Unlock ( )
return b . block
}