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
2023-02-14 15:05:27 +00:00
"github.com/ledgerwatch/log/v3"
2022-06-13 13:43:09 +00:00
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/types"
)
2023-02-14 15:05:27 +00:00
type BlockBuilderFunc func ( param * core . BlockBuilderParameters , interrupt * int32 ) ( * types . BlockWithReceipts , error )
2022-06-13 13:43:09 +00:00
// 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
2023-02-14 15:05:27 +00:00
result * types . BlockWithReceipts
2022-12-01 08:15:01 +00:00
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 {
2023-02-14 15:05:27 +00:00
builder := new ( BlockBuilder )
builder . syncCond = sync . NewCond ( new ( sync . Mutex ) )
2022-06-13 13:43:09 +00:00
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 ( )
2023-02-14 15:05:27 +00:00
result , err := build ( param , & builder . interrupt )
2022-10-19 09:38:03 +00:00
if err != nil {
log . Warn ( "Failed to build a block" , "err" , err )
} else {
2023-02-14 15:05:27 +00:00
block := result . Block
2022-10-19 09:38:03 +00:00
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
2023-02-14 15:05:27 +00:00
builder . syncCond . L . Lock ( )
defer builder . syncCond . L . Unlock ( )
builder . result = result
builder . err = err
builder . syncCond . Broadcast ( )
2022-06-13 13:43:09 +00:00
} ( )
2023-02-14 15:05:27 +00:00
return builder
2022-06-13 13:43:09 +00:00
}
2023-02-14 15:05:27 +00:00
func ( b * BlockBuilder ) Stop ( ) ( * types . BlockWithReceipts , error ) {
2022-06-13 13:43:09 +00:00
atomic . StoreInt32 ( & b . interrupt , 1 )
b . syncCond . L . Lock ( )
defer b . syncCond . L . Unlock ( )
2023-02-14 15:05:27 +00:00
for b . result == nil && b . err == nil {
2022-06-13 13:43:09 +00:00
b . syncCond . Wait ( )
}
2023-02-14 15:05:27 +00:00
return b . result , 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 ( )
2023-02-14 15:05:27 +00:00
if b . result == nil {
return nil
}
return b . result . Block
2022-08-15 08:19:45 +00:00
}