Skip to content

Commit 76bc954

Browse files
Sokol v0: can process 1-st block (#2310)
1 parent 95ab850 commit 76bc954

File tree

13 files changed

+170
-44
lines changed

13 files changed

+170
-44
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,5 @@ docker-compose.dev.yml
6868

6969
/ethdb/*.fail
7070

71+
libmdbx/build/*
72+
tests/testdata/*

consensus/aura/aura.go

+21-7
Original file line numberDiff line numberDiff line change
@@ -196,16 +196,13 @@ func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, validators
196196
return e.finalityChecker, e.epochTransitionNumber, false
197197
}
198198
// extract other epoch set if it's not the same as the last.
199-
fmt.Printf("aa3: %x,%x\n", lastTransition.BlockHash, e.epochTransitionHash)
200199
if lastTransition.BlockHash != e.epochTransitionHash {
201-
fmt.Printf("aa2: %T\n", validators)
202200
proof, err := destructure_proofs(lastTransition.ProofRlp)
203201
if err != nil {
204202
panic(err)
205203
}
206204
first := proof.SignalNumber == 0
207205
// use signal number so multi-set first calculation is correct.
208-
fmt.Printf("aa1: %T\n", validators)
209206
list, _, err := validators.epochSet(first, proof.SignalNumber, proof.SetProof)
210207
if err != nil {
211208
panic(fmt.Errorf("proof produced by this engine; therefore it is valid; qed. %w", err))
@@ -512,15 +509,20 @@ func nextStepTimeDuration(info StepDurationInfo, time uint64) (uint64, uint64, b
512509
// Author implements consensus.Engine, returning the Ethereum address recovered
513510
// from the signature in the header's extra-data section.
514511
func (c *AuRa) Author(header *types.Header) (common.Address, error) {
512+
/*
513+
let message = keccak(empty_step_rlp(self.step, &self.parent_hash));
514+
let public = publickey::recover(&self.signature.into(), &message)?;
515+
Ok(publickey::public_to_address(&public))
516+
*/
515517
return common.Address{}, nil
516-
//return ecrecover(header, c.signatures)
517518
}
518519

519520
// VerifyHeader checks whether a header conforms to the consensus rules.
520521
func (c *AuRa) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header, _ bool) error {
521522
return nil
522523
}
523524

525+
//nolint
524526
func (c *AuRa) hasReceivedStepHashes(step uint64, author common.Address, newHash common.Hash) bool {
525527
/*
526528
self
@@ -531,6 +533,8 @@ func (c *AuRa) hasReceivedStepHashes(step uint64, author common.Address, newHash
531533
*/
532534
return false
533535
}
536+
537+
//nolint
534538
func (c *AuRa) insertReceivedStepHashes(step uint64, author common.Address, newHash common.Hash) {
535539
/*
536540
self.received_step_hashes
@@ -540,7 +544,9 @@ func (c *AuRa) insertReceivedStepHashes(step uint64, author common.Address, newH
540544
}
541545

542546
/// Phase 3 verification. Check block information against parent. Returns either a null `Ok` or a general error detailing the problem with import.
547+
//nolint
543548
func (c *AuRa) VerifyFamily(chain consensus.ChainHeaderReader, header *types.Header) error {
549+
return nil
544550
step, err := headerStep(header)
545551
if err != nil {
546552
return err
@@ -788,8 +794,17 @@ func (c *AuRa) Prepare(chain consensus.ChainHeaderReader, header *types.Header)
788794
//return nil
789795
}
790796

791-
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block
792-
// rewards given.
797+
func (c *AuRa) Initialize(cc *params.ChainConfig, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) {
798+
isEpochBegin := header.Number.Uint64() == 1
799+
if !isEpochBegin {
800+
return
801+
}
802+
err := c.cfg.Validators.onEpochBegin(isEpochBegin, header, syscall)
803+
if err != nil {
804+
log.Warn("aura initialize block: on epoch begin", "err", err)
805+
}
806+
}
807+
793808
func (c *AuRa) Finalize(cc *params.ChainConfig, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) {
794809
// accumulateRewards retreives rewards for a block and applies them to the coinbase accounts for miner and uncle miners
795810
beneficiaries, _, rewards, err := AccumulateRewards(cc, c, header, uncles, syscall)
@@ -1185,7 +1200,6 @@ func callBlockRewardAbi(contractAddr common.Address, syscall consensus.SystemCal
11851200
}
11861201
_ = res[0]
11871202
_ = res[1]
1188-
fmt.Printf("aaaaa: %#v, %#v\n", res[0], res[1])
11891203
return nil, nil
11901204
}
11911205

consensus/aura/config.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,14 @@ func newValidatorSetFromJson(j *ValidatorSetJson, posdaoTransition *uint64) Vali
5252
return &SimpleList{validators: j.List}
5353
}
5454
if j.SafeContract != nil {
55-
return &ValidatorSafeContract{contractAddress: *j.SafeContract}
55+
return &ValidatorSafeContract{contractAddress: *j.SafeContract, posdaoTransition: posdaoTransition}
5656
}
5757
if j.Contract != nil {
58-
return &ValidatorContract{contractAddress: *j.SafeContract, posdaoTransition: posdaoTransition}
58+
return &ValidatorContract{
59+
contractAddress: *j.SafeContract,
60+
validators: ValidatorSafeContract{contractAddress: *j.SafeContract, posdaoTransition: posdaoTransition},
61+
posdaoTransition: posdaoTransition,
62+
}
5963
}
6064
if j.Multi != nil {
6165
l := map[uint64]ValidatorSet{}

consensus/aura/validators.go

+36-15
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,14 @@ import (
99

1010
lru "github.com/hashicorp/golang-lru"
1111
"github.com/ledgerwatch/erigon/common"
12+
"github.com/ledgerwatch/erigon/consensus"
1213
"github.com/ledgerwatch/erigon/consensus/aura/aurainterfaces"
1314
"github.com/ledgerwatch/erigon/core/types"
1415
"github.com/ledgerwatch/erigon/log"
1516
"github.com/ledgerwatch/erigon/rlp"
1617
"go.uber.org/atomic"
1718
)
1819

19-
/// Kind of SystemOrCodeCall, this is either an on-chain address, or code.
20-
type SystemOrCodeCallKind uint8
21-
22-
const (
23-
SystemCallOnChain SystemOrCodeCallKind = 0
24-
CallHardCodedCode SystemOrCodeCallKind = 1
25-
)
26-
2720
//nolint
2821
type CallResults struct {
2922
data []byte
@@ -58,6 +51,15 @@ type ValidatorSet interface {
5851
// Returns a list of contract calls to be pushed onto the new block.
5952
//func generateEngineTransactions(_first bool, _header *types.Header, _call SystemCall) -> Result<Vec<(Address, Bytes)>, EthcoreError>
6053

54+
// Signalling that a new epoch has begun.
55+
//
56+
// All calls here will be from the `SYSTEM_ADDRESS`: 2^160 - 2
57+
// and will have an effect on the block's state.
58+
// The caller provided here may not generate proofs.
59+
//
60+
// `first` is true if this is the first block in the set.
61+
onEpochBegin(first bool, header *types.Header, caller consensus.SystemCall) error
62+
6163
// Called on the close of every block.
6264
onCloseBlock(_header *types.Header, _address common.Address) error
6365

@@ -279,10 +281,10 @@ func (s *Multi) genesisEpochData(header *types.Header, call Call) ([]byte, error
279281
return set.genesisEpochData(header, call)
280282
}
281283

282-
//func (s *Multi) onEpochBegin(first bool, header *types.Header, call SysCall) error {
283-
// first, set := s.get(header.Number.Uint64())
284-
// return set.onEpochBegin(first,header, address)
285-
//}
284+
func (s *Multi) onEpochBegin(_ bool, header *types.Header, caller consensus.SystemCall) error {
285+
setTransition, set := s.correctSetByNumber(header.Number.Uint64())
286+
return set.onEpochBegin(setTransition == header.Number.Uint64(), header, caller)
287+
}
286288

287289
type SimpleList struct {
288290
validators []common.Address
@@ -291,6 +293,9 @@ type SimpleList struct {
291293
func (s *SimpleList) epochSet(first bool, num uint64, proof []byte) (SimpleList, common.Hash, error) {
292294
return *s, common.Hash{}, nil
293295
}
296+
func (s *SimpleList) onEpochBegin(first bool, header *types.Header, caller consensus.SystemCall) error {
297+
return nil
298+
}
294299
func (s *SimpleList) onCloseBlock(_header *types.Header, _address common.Address) error { return nil }
295300
func (s *SimpleList) defaultCaller(blockHash common.Hash) (Call, error) {
296301
return nil, nil //simple list doesn't require calls
@@ -620,6 +625,22 @@ func (s *ValidatorSafeContract) genesisEpochData(header *types.Header, call Call
620625
return proveInitial(s.contractAddress, header, call)
621626
}
622627

628+
func (s *ValidatorSafeContract) onEpochBegin(first bool, header *types.Header, caller consensus.SystemCall) error {
629+
data := common.FromHex("75286211")
630+
_, err := caller(s.contractAddress, data)
631+
if err != nil {
632+
return err
633+
}
634+
/*
635+
let data = validator_set::functions::finalize_change::encode_input();
636+
caller(self.contract_address, data)
637+
.map(|_| ())
638+
.map_err(::engines::EngineError::FailedSystemCall)
639+
.map_err(Into::into)
640+
*/
641+
return nil
642+
}
643+
623644
func (s *ValidatorSafeContract) onCloseBlock(header *types.Header, ourAddress common.Address) error {
624645
// Skip the rest of the function unless there has been a transition to POSDAO AuRa.
625646
if s.posdaoTransition != nil && header.Number.Uint64() < *s.posdaoTransition {
@@ -676,18 +697,18 @@ type ValidatorContract struct {
676697
func (s *ValidatorContract) epochSet(first bool, num uint64, proof []byte) (SimpleList, common.Hash, error) {
677698
return s.validators.epochSet(first, num, proof)
678699
}
679-
680700
func (s *ValidatorContract) defaultCaller(blockHash common.Hash) (Call, error) {
681701
return s.validators.defaultCaller(blockHash)
682702
}
683-
684703
func (s *ValidatorContract) getWithCaller(parentHash common.Hash, nonce uint, caller Call) (common.Address, error) {
685704
return s.validators.getWithCaller(parentHash, nonce, caller)
686705
}
687-
688706
func (s *ValidatorContract) countWithCaller(parentHash common.Hash, caller Call) (uint64, error) {
689707
return s.validators.countWithCaller(parentHash, caller)
690708
}
709+
func (s *ValidatorContract) onEpochBegin(first bool, header *types.Header, caller consensus.SystemCall) error {
710+
return s.validators.onEpochBegin(first, header, caller)
711+
}
691712
func (s *ValidatorContract) onCloseBlock(header *types.Header, address common.Address) error {
692713
return s.validators.onCloseBlock(header, address)
693714
}

consensus/clique/clique.go

+3
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,9 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header
363363
return nil
364364
}
365365

366+
func (c *Clique) Initialize(_ *params.ChainConfig, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) {
367+
}
368+
366369
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block
367370
// rewards given.
368371
func (c *Clique) Finalize(_ *params.ChainConfig, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) {

consensus/consensus.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ type ChainReader interface {
5959
HasBlock(hash common.Hash, number uint64) bool
6060
}
6161

62-
type SystemCall func(address common.Address, in []byte) ([]byte, error)
62+
type SystemCall func(contract common.Address, data []byte) ([]byte, error)
63+
type Call func(contract common.Address, data []byte) ([]byte, error)
6364

6465
// Engine is an algorithm agnostic consensus engine.
6566
type Engine interface {
@@ -87,6 +88,9 @@ type Engine interface {
8788
// rules of a particular engine. The changes are executed inline.
8889
Prepare(chain ChainHeaderReader, header *types.Header) error
8990

91+
// Initialize runs any pre-transaction state modifications (e.g. epoch start)
92+
Initialize(config *params.ChainConfig, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall SystemCall)
93+
9094
// Finalize runs any post-transaction state modifications (e.g. block rewards)
9195
// but does not assemble the block.
9296
//

consensus/ethash/consensus.go

+3
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,9 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H
596596
return nil
597597
}
598598

599+
func (ethash *Ethash) Initialize(config *params.ChainConfig, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, _ consensus.SystemCall) {
600+
}
601+
599602
// Finalize implements consensus.Engine, accumulating the block and uncle rewards,
600603
// setting the final state on the header
601604
func (ethash *Ethash) Finalize(config *params.ChainConfig, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, _ consensus.SystemCall) {

core/blockchain.go

+77-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"os"
2424
"time"
2525

26-
"github.com/holiman/uint256"
2726
"github.com/ledgerwatch/erigon/common"
2827
"github.com/ledgerwatch/erigon/common/mclock"
2928
"github.com/ledgerwatch/erigon/common/u256"
@@ -106,6 +105,12 @@ func ExecuteBlockEphemerally(
106105
gp := new(GasPool)
107106
gp.AddGas(block.GasLimit())
108107

108+
if !vmConfig.ReadOnly {
109+
if err := InitializeBlockExecution(engine, block.Header(), block.Transactions(), block.Uncles(), stateWriter, chainConfig, ibs); err != nil {
110+
return nil, err
111+
}
112+
}
113+
109114
if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 {
110115
misc.ApplyDAOHardFork(ibs)
111116
}
@@ -167,6 +172,52 @@ func ExecuteBlockEphemerally(
167172
return receipts, nil
168173
}
169174

175+
// SystemAddress - sender address for internal state updates.
176+
var SystemAddress = common.HexToAddress("0xfffffffffffffffffffffffffffffffffffffffe")
177+
178+
func SysCallContract(contract common.Address, data []byte, chainConfig params.ChainConfig, ibs *state.IntraBlockState, header *types.Header, engine consensus.Engine) (result []byte, err error) {
179+
gp := new(GasPool)
180+
gp.AddGas(50_000_000)
181+
var gasUsed uint64
182+
183+
if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 {
184+
misc.ApplyDAOHardFork(ibs)
185+
}
186+
187+
noop := state.NewNoopWriter()
188+
tx, err := SysCallContractTx(contract, data, ibs)
189+
if err != nil {
190+
return nil, fmt.Errorf("SysCallContract: %w ", err)
191+
}
192+
// Set infinite balance to the fake caller account.
193+
fmt.Printf("call contract: %d,%x,%x\n", header.Number.Uint64(), contract, data)
194+
195+
vmConfig := vm.Config{NoReceipts: true, Debug: true, Tracer: vm.NewStructLogger(&vm.LogConfig{})}
196+
_, result, err = ApplyTransaction(&chainConfig, nil, engine, &SystemAddress, gp, ibs, noop, header, tx, &gasUsed, vmConfig, nil)
197+
if err != nil {
198+
return result, fmt.Errorf("SysCallContract: %w ", err)
199+
}
200+
ibs.SetNonce(SystemAddress, 0)
201+
202+
//w, err1 := os.Create(fmt.Sprintf("txtrace_before.json"))
203+
//if err1 != nil {
204+
// panic(err1)
205+
//}
206+
//encoder := json.NewEncoder(w)
207+
//logs := FormatLogs(vmConfig.Tracer.(*vm.StructLogger).StructLogs())
208+
//if err2 := encoder.Encode(logs); err2 != nil {
209+
// panic(err2)
210+
//}
211+
return result, nil
212+
}
213+
214+
// from the null sender, with 50M gas.
215+
func SysCallContractTx(contract common.Address, data []byte, ibs *state.IntraBlockState) (tx types.Transaction, err error) {
216+
//nonce := ibs.GetNonce(SystemAddress)
217+
tx = types.NewTransaction(0, contract, u256.Num0, 50_000_000, u256.Num0, data)
218+
return tx.FakeSign(SystemAddress)
219+
}
220+
170221
func CallContract(contract common.Address, data []byte, chainConfig params.ChainConfig, ibs *state.IntraBlockState, header *types.Header, engine consensus.Engine) (result []byte, err error) {
171222
gp := new(GasPool)
172223
gp.AddGas(50_000_000)
@@ -178,24 +229,33 @@ func CallContract(contract common.Address, data []byte, chainConfig params.Chain
178229
noop := state.NewNoopWriter()
179230
tx, err := CallContractTx(contract, data, ibs)
180231
if err != nil {
181-
return nil, fmt.Errorf("CallContract: %w ", err)
232+
return nil, fmt.Errorf("SysCallContract: %w ", err)
182233
}
183234
// Set infinite balance to the fake caller account.
184-
from := ibs.GetOrNewStateObject(common.Address{})
185-
from.SetBalance(uint256.NewInt(0).SetAllOne())
235+
fmt.Printf("call contract: %d,%x,%x\n", header.Number.Uint64(), contract, data)
186236

187-
_, result, err = ApplyTransaction(&chainConfig, nil, engine, nil, gp, ibs, noop, header, tx, &gasUsed, vm.Config{}, nil)
237+
vmConfig := vm.Config{NoReceipts: true, Debug: true, Tracer: vm.NewStructLogger(&vm.LogConfig{})}
238+
_, result, err = ApplyTransaction(&chainConfig, nil, engine, &SystemAddress, gp, ibs, noop, header, tx, &gasUsed, vmConfig, nil)
188239
if err != nil {
189-
return result, fmt.Errorf("CallContract: %w ", err)
240+
return result, fmt.Errorf("SysCallContract: %w ", err)
190241
}
242+
//w, err1 := os.Create(fmt.Sprintf("txtrace_before.json"))
243+
//if err1 != nil {
244+
// panic(err1)
245+
//}
246+
//encoder := json.NewEncoder(w)
247+
//logs := FormatLogs(vmConfig.Tracer.(*vm.StructLogger).StructLogs())
248+
//if err2 := encoder.Encode(logs); err2 != nil {
249+
// panic(err2)
250+
//}
191251
return result, nil
192252
}
193253

194254
// from the null sender, with 50M gas.
195255
func CallContractTx(contract common.Address, data []byte, ibs *state.IntraBlockState) (tx types.Transaction, err error) {
196-
var from common.Address
256+
from := common.Address{}
197257
nonce := ibs.GetNonce(from)
198-
tx = types.NewTransaction(nonce, contract, u256.Num0, 50_000_000, u256.Num1, data)
258+
tx = types.NewTransaction(nonce, contract, u256.Num0, 50_000_000, u256.Num0, data)
199259
return tx.FakeSign(from)
200260
}
201261

@@ -213,3 +273,12 @@ func FinalizeBlockExecution(engine consensus.Engine, header *types.Header, txs t
213273
}
214274
return nil
215275
}
276+
277+
func InitializeBlockExecution(engine consensus.Engine, header *types.Header, txs types.Transactions, uncles []*types.Header, stateWriter state.WriterWithChangeSets, cc *params.ChainConfig, ibs *state.IntraBlockState) error {
278+
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
279+
engine.Initialize(cc, header, ibs, txs, uncles, func(contract common.Address, data []byte) ([]byte, error) {
280+
return SysCallContract(contract, data, *cc, ibs, header, engine)
281+
})
282+
283+
return nil
284+
}

0 commit comments

Comments
 (0)