aura-dev merged

This commit is contained in:
priom 2018-09-08 10:30:28 -04:00
commit 85240a47ba
7 changed files with 127 additions and 131 deletions

View file

@ -145,7 +145,7 @@ var (
Name: "dev",
Usage: "Ephemeral proof-of-authority network with a pre-funded developer account, mining enabled",
}
GoerliFlag = cli.BoolFlag{
GoerliFLag = cli.BoolFlag{
Name: "goerli",
Usage: "Goerli network: pre-configured proof-of-authority test network",
}

View file

@ -27,8 +27,7 @@ import (
// mechanisms of the proof-of-authority scheme.
type API struct {
chain consensus.ChainReader
//clique *Clique
//aura *Aura
aura *Aura
}
// GetSnapshot retrieves the state snapshot at a given block.
@ -44,7 +43,7 @@ func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) {
if header == nil {
return nil, errUnknownBlock
}
return api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
return api.aura.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
}
// GetSnapshotAtHash retrieves the state snapshot at a given block.
@ -53,7 +52,7 @@ func (api *API) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) {
if header == nil {
return nil, errUnknownBlock
}
return api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
return api.aura.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
}
// GetSigners retrieves the list of authorized signers at the specified block.
@ -69,7 +68,7 @@ func (api *API) GetSigners(number *rpc.BlockNumber) ([]common.Address, error) {
if header == nil {
return nil, errUnknownBlock
}
snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
snap, err := api.aura.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
if err != nil {
return nil, err
}
@ -82,7 +81,7 @@ func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) {
if header == nil {
return nil, errUnknownBlock
}
snap, err := api.clique.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
snap, err := api.aura.snapshot(api.chain, header.Number.Uint64(), header.Hash(), nil)
if err != nil {
return nil, err
}
@ -91,11 +90,11 @@ func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) {
// Proposals returns the current proposals the node tries to uphold and vote on.
func (api *API) Proposals() map[common.Address]bool {
api.clique.lock.RLock()
defer api.clique.lock.RUnlock()
api.aura.lock.RLock()
defer api.aura.lock.RUnlock()
proposals := make(map[common.Address]bool)
for address, auth := range api.clique.proposals {
for address, auth := range api.aura.proposals {
proposals[address] = auth
}
return proposals
@ -104,17 +103,17 @@ func (api *API) Proposals() map[common.Address]bool {
// Propose injects a new authorization proposal that the signer will attempt to
// push through.
func (api *API) Propose(address common.Address, auth bool) {
api.clique.lock.Lock()
defer api.clique.lock.Unlock()
api.aura.lock.Lock()
defer api.aura.lock.Unlock()
api.clique.proposals[address] = auth
api.aura.proposals[address] = auth
}
// Discard drops a currently running proposal, stopping the signer from casting
// further votes (either for or against).
func (api *API) Discard(address common.Address) {
api.clique.lock.Lock()
defer api.clique.lock.Unlock()
api.aura.lock.Lock()
defer api.aura.lock.Unlock()
delete(api.clique.proposals, address)
delete(api.aura.proposals, address)
}

View file

@ -56,13 +56,7 @@ var (
extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity
extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal
nonceAuthVote = hexutil.MustDecode("0xffffffffffffffff") // Magic nonce number to vote on adding a new signer
nonceDropVote = hexutil.MustDecode("0x0000000000000000") // Magic nonce number to vote on removing a signer.
uncleHash = types.CalcUncleHash(nil) // Always Keccak256(RLP([])) as uncles are meaningless outside of PoW.
diffInTurn = big.NewInt(2) // Block difficulty for in-turn signatures
diffNoTurn = big.NewInt(1) // Block difficulty for out-of-turn signatures
)
// Various error messages to mark blocks invalid. These should be private to
@ -98,6 +92,10 @@ var (
// their extra-data fields.
errExtraSigners = errors.New("non-checkpoint block contains extra signer list")
// errInvalidValidatorSeal is returned if the extra data field length is not
// equal to the length of a seal
errInvalidExtraData = errors.New("extra data field in block header is invalid")
// errInvalidCheckpointSigners is returned if a checkpoint block contains an
// invalid list of signers (i.e. non divisible by 20 bytes, or not the correct
// ones).
@ -193,7 +191,7 @@ func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, er
// Clique is the proof-of-authority consensus engine proposed to support the
// Ethereum testnet following the Ropsten attacks.
type Aura struct {
config *params.CliqueConfig // Consensus engine configuration parameters
config *params.AuraConfig // Consensus engine configuration parameters
db ethdb.Database // Database to store and retrieve snapshot checkpoints
recents *lru.ARCCache // Snapshots for recent block to speed up reorgs
@ -206,9 +204,9 @@ type Aura struct {
lock sync.RWMutex // Protects the signer fields
}
// New creates a Clique proof-of-authority consensus engine with the initial
// New creates a Aura proof-of-authority consensus engine with the initial
// signers set to the ones provided by the user.
func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
func New(config *params.AuraConfig, db ethdb.Database) *Aura {
// Set any missing consensus parameters to their defaults
conf := *config
if conf.Epoch == 0 {
@ -229,25 +227,25 @@ func New(config *params.CliqueConfig, db ethdb.Database) *Clique {
// Author implements consensus.Engine, returning the Ethereum address recovered
// from the signature in the header's extra-data section.
func (c *Aura) Author(header *types.Header) (common.Address, error) {
return ecrecover(header, c.signatures)
func (a *Aura) Author(header *types.Header) (common.Address, error) {
return ecrecover(header, a.signatures)
}
// VerifyHeader checks whether a header conforms to the consensus rules.
func (c *Aura) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
return c.verifyHeader(chain, header, nil)
func (a *Aura) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
return a.verifyHeader(chain, header, nil)
}
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
// method returns a quit channel to abort the operations and a results channel to
// retrieve the async verifications (the order is that of the input slice).
func (c *Aura) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
func (a *Aura) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
abort := make(chan struct{})
results := make(chan error, len(headers))
go func() {
for i, header := range headers {
err := c.verifyHeader(chain, header, headers[:i])
err := a.verifyHeader(chain, header, headers[:i])
select {
case <-abort:
@ -263,7 +261,7 @@ func (c *Aura) VerifyHeaders(chain consensus.ChainReader, headers []*types.Heade
// caller may optionally pass in a batch of parents (ascending order) to avoid
// looking those up from the database. This is useful for concurrently verifying
// a batch of new headers.
func (c *Aura) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
func (a *Aura) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
if header.Number == nil {
return errUnknownBlock
}
@ -273,32 +271,21 @@ func (c *Aura) verifyHeader(chain consensus.ChainReader, header *types.Header, p
if header.Time.Cmp(big.NewInt(time.Now().Unix())) > 0 {
return consensus.ErrFutureBlock
}
// TODO: Are any of these necessary checks?
// Checkpoint blocks need to enforce zero beneficiary
checkpoint := (number % c.config.Epoch) == 0
if checkpoint && header.Coinbase != (common.Address{}) {
return errInvalidCheckpointBeneficiary
}
//checkpoint := (number % a.config.Epoch) == 0
//if checkpoint && header.Coinbase != (common.Address{}) {
// return errInvalidCheckpointBeneficiary
//}
// Nonces must be 0x00..0 or 0xff..f, zeroes enforced on checkpoints
if !bytes.Equal(header.Nonce[:], nonceAuthVote) && !bytes.Equal(header.Nonce[:], nonceDropVote) {
return errInvalidVote
}
if checkpoint && !bytes.Equal(header.Nonce[:], nonceDropVote) {
return errInvalidCheckpointVote
}
// Check that the extra-data contains both the vanity and signature
if len(header.Extra) < extraVanity {
return errMissingVanity
}
if len(header.Extra) < extraVanity+extraSeal {
return errMissingSignature
}
// Ensure that the extra-data contains a signer list on checkpoint, but none otherwise
signersBytes := len(header.Extra) - extraVanity - extraSeal
if !checkpoint && signersBytes != 0 {
return errExtraSigners
}
if checkpoint && signersBytes%common.AddressLength != 0 {
return errInvalidCheckpointSigners
//if !bytes.Equal(header.Nonce[:], nonceAuthVote) && !bytes.Equal(header.Nonce[:], nonceDropVote) {
// return errInvalidVote
//}
// Ensure that the extra-data contains a single signature
signersBytes := len(header.Extra) - extraSeal
if signersBytes != 0 {
return errInvalidExtraData
}
// Ensure that the mix digest is zero as we don't have fork protection currently
if header.MixDigest != (common.Hash{}) {
@ -308,9 +295,9 @@ func (c *Aura) verifyHeader(chain consensus.ChainReader, header *types.Header, p
if header.UncleHash != uncleHash {
return errInvalidUncleHash
}
// Ensure that the block's difficulty is meaningful (may not be correct at this point)
// Ensure that the block's difficulty is correct (it should be constant)
if number > 0 {
if header.Difficulty == nil || (header.Difficulty.Cmp(diffInTurn) != 0 && header.Difficulty.Cmp(diffNoTurn) != 0) {
if header.Difficulty != chain.Config().Difficulty {
return errInvalidDifficulty
}
}
@ -319,14 +306,14 @@ func (c *Aura) verifyHeader(chain consensus.ChainReader, header *types.Header, p
return err
}
// All basic checks passed, verify cascading fields
return c.verifyCascadingFields(chain, header, parents)
return a.verifyCascadingFields(chain, header, parents)
}
// verifyCascadingFields verifies all the header fields that are not standalone,
// rather depend on a batch of previous headers. The caller may optionally pass
// in a batch of parents (ascending order) to avoid looking those up from the
// database. This is useful for concurrently verifying a batch of new headers.
func (c *Aura) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
func (a *Aura) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
// The genesis block is the always valid dead-end
number := header.Number.Uint64()
if number == 0 {
@ -342,16 +329,16 @@ func (c *Aura) verifyCascadingFields(chain consensus.ChainReader, header *types.
if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
return consensus.ErrUnknownAncestor
}
if parent.Time.Uint64()+c.config.Period > header.Time.Uint64() {
if parent.Time.Uint64()+a.config.Period > header.Time.Uint64() {
return ErrInvalidTimestamp
}
// Retrieve the snapshot needed to verify this header and cache it
snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
snap, err := a.snapshot(chain, number-1, header.ParentHash, parents)
if err != nil {
return err
}
// If the block is a checkpoint block, verify the signer list
if number%c.config.Epoch == 0 {
if number%a.config.Epoch == 0 {
signers := make([]byte, len(snap.Signers)*common.AddressLength)
for i, signer := range snap.signers() {
copy(signers[i*common.AddressLength:], signer[:])
@ -362,11 +349,11 @@ func (c *Aura) verifyCascadingFields(chain consensus.ChainReader, header *types.
}
}
// All basic checks passed, verify the seal and return
return c.verifySeal(chain, header, parents)
return a.verifySeal(chain, header, parents)
}
// snapshot retrieves the authorization snapshot at a given point in time.
func (c *Aura) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) {
func (a *Aura) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) {
// Search for a snapshot in memory or on disk for checkpoints
var (
headers []*types.Header
@ -374,20 +361,20 @@ func (c *Aura) snapshot(chain consensus.ChainReader, number uint64, hash common.
)
for snap == nil {
// If an in-memory snapshot was found, use that
if s, ok := c.recents.Get(hash); ok {
if s, ok := a.recents.Get(hash); ok {
snap = s.(*Snapshot)
break
}
// If an on-disk checkpoint snapshot can be found, use that
if number%checkpointInterval == 0 {
if s, err := loadSnapshot(c.config, c.signatures, c.db, hash); err == nil {
if s, err := loadSnapshot(a.config, a.signatures, a.db, hash); err == nil {
log.Trace("Loaded voting snapshot from disk", "number", number, "hash", hash)
snap = s
break
}
}
// If we're at an checkpoint block, make a snapshot if it's known
if number%c.config.Epoch == 0 {
if number%a.config.Epoch == 0 {
checkpoint := chain.GetHeaderByNumber(number)
if checkpoint != nil {
hash := checkpoint.Hash()
@ -396,8 +383,8 @@ func (c *Aura) snapshot(chain consensus.ChainReader, number uint64, hash common.
for i := 0; i < len(signers); i++ {
copy(signers[i][:], checkpoint.Extra[extraVanity+i*common.AddressLength:])
}
snap = newSnapshot(c.config, c.signatures, number, hash, signers)
if err := snap.store(c.db); err != nil {
snap = newSnapshot(a.config, a.signatures, number, hash, signers)
if err := snap.store(a.db); err != nil {
return nil, err
}
log.Info("Stored checkpoint snapshot to disk", "number", number, "hash", hash)
@ -431,11 +418,11 @@ func (c *Aura) snapshot(chain consensus.ChainReader, number uint64, hash common.
if err != nil {
return nil, err
}
c.recents.Add(snap.Hash, snap)
a.recents.Add(snap.Hash, snap)
// If we've generated a new checkpoint snapshot, save to disk
if snap.Number%checkpointInterval == 0 && len(headers) > 0 {
if err = snap.store(c.db); err != nil {
if err = snap.store(a.db); err != nil {
return nil, err
}
log.Trace("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash)
@ -445,7 +432,7 @@ func (c *Aura) snapshot(chain consensus.ChainReader, number uint64, hash common.
// VerifyUncles implements consensus.Engine, always returning an error for any
// uncles as this consensus mechanism doesn't permit uncles.
func (c *Aura) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
func (a *Aura) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
if len(block.Uncles()) > 0 {
return errors.New("uncles not allowed")
}
@ -454,28 +441,28 @@ func (c *Aura) VerifyUncles(chain consensus.ChainReader, block *types.Block) err
// VerifySeal implements consensus.Engine, checking whether the signature contained
// in the header satisfies the consensus protocol requirements.
func (c *Aura) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
return c.verifySeal(chain, header, nil)
func (a *Aura) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
return a.verifySeal(chain, header, nil)
}
// verifySeal checks whether the signature contained in the header satisfies the
// consensus protocol requirements. The method accepts an optional list of parent
// headers that aren't yet part of the local blockchain to generate the snapshots
// from.
func (c *Aura) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
func (a *Aura) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header) error {
// Verifying the genesis block is not supported
number := header.Number.Uint64()
if number == 0 {
return errUnknownBlock
}
// Retrieve the snapshot needed to verify this header and cache it
snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
snap, err := a.snapshot(chain, number-1, header.ParentHash, parents)
if err != nil {
return err
}
// Resolve the authorization key and check against signers
signer, err := ecrecover(header, c.signatures)
signer, err := ecrecover(header, a.signatures)
if err != nil {
return err
}
@ -503,23 +490,23 @@ func (c *Aura) verifySeal(chain consensus.ChainReader, header *types.Header, par
// Prepare implements consensus.Engine, preparing all the consensus fields of the
// header for running the transactions on top.
func (c *Aura) Prepare(chain consensus.ChainReader, header *types.Header) error {
func (a *Aura) Prepare(chain consensus.ChainReader, header *types.Header) error {
// If the block isn't a checkpoint, cast a random vote (good enough for now)
header.Coinbase = common.Address{}
header.Nonce = types.BlockNonce{}
number := header.Number.Uint64()
// Assemble the voting snapshot to check which votes make sense
snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
snap, err := a.snapshot(chain, number-1, header.ParentHash, nil)
if err != nil {
return err
}
if number%c.config.Epoch != 0 {
c.lock.RLock()
if number%a.config.Epoch != 0 {
a.lock.RLock()
// Gather all the proposals that make sense voting on
addresses := make([]common.Address, 0, len(c.proposals))
for address, authorize := range c.proposals {
addresses := make([]common.Address, 0, len(a.proposals))
for address, authorize := range a.proposals {
if snap.validVote(address, authorize) {
addresses = append(addresses, address)
}
@ -527,16 +514,16 @@ func (c *Aura) Prepare(chain consensus.ChainReader, header *types.Header) error
// If there's pending proposals, cast a vote on them
if len(addresses) > 0 {
header.Coinbase = addresses[rand.Intn(len(addresses))]
if c.proposals[header.Coinbase] {
if a.proposals[header.Coinbase] {
copy(header.Nonce[:], nonceAuthVote)
} else {
copy(header.Nonce[:], nonceDropVote)
}
}
c.lock.RUnlock()
a.lock.RUnlock()
}
// Set the correct difficulty
header.Difficulty = CalcDifficulty(snap, c.signer)
header.Difficulty = CalcDifficulty(snap, a.signer)
// Ensure the extra data has all it's components
if len(header.Extra) < extraVanity {
@ -544,7 +531,7 @@ func (c *Aura) Prepare(chain consensus.ChainReader, header *types.Header) error
}
header.Extra = header.Extra[:extraVanity]
if number%c.config.Epoch == 0 {
if number%a.config.Epoch == 0 {
for _, signer := range snap.signers() {
header.Extra = append(header.Extra, signer[:]...)
}
@ -559,7 +546,7 @@ func (c *Aura) Prepare(chain consensus.ChainReader, header *types.Header) error
if parent == nil {
return consensus.ErrUnknownAncestor
}
header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(c.config.Period))
header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(a.config.Period))
if header.Time.Int64() < time.Now().Unix() {
header.Time = big.NewInt(time.Now().Unix())
}
@ -568,7 +555,7 @@ func (c *Aura) Prepare(chain consensus.ChainReader, header *types.Header) error
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block
// rewards given, and returns the final block.
func (c *Aura) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
func (a *Aura) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
// No block rewards in PoA, so the state remains as is and uncles are dropped
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
header.UncleHash = types.CalcUncleHash(nil)
@ -579,17 +566,17 @@ func (c *Aura) Finalize(chain consensus.ChainReader, header *types.Header, state
// Authorize injects a private key into the consensus engine to mint new blocks
// with.
func (c *Aura) Authorize(signer common.Address, signFn SignerFn) {
c.lock.Lock()
defer c.lock.Unlock()
func (a *Aura) Authorize(signer common.Address, signFn SignerFn) {
a.lock.Lock()
defer a.lock.Unlock()
c.signer = signer
c.signFn = signFn
a.signer = signer
a.signFn = signFn
}
// Seal implements consensus.Engine, attempting to create a sealed block using
// the local signing credentials.
func (c *Aura) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
func (a *Aura) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
header := block.Header()
// Sealing the genesis block is not supported
@ -598,16 +585,16 @@ func (c *Aura) Seal(chain consensus.ChainReader, block *types.Block, results cha
return errUnknownBlock
}
// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
if c.config.Period == 0 && len(block.Transactions()) == 0 {
if a.config.Period == 0 && len(block.Transactions()) == 0 {
return errWaitTransactions
}
// Don't hold the signer fields for the entire sealing procedure
c.lock.RLock()
signer, signFn := c.signer, c.signFn
c.lock.RUnlock()
a.lock.RLock()
signer, signFn := a.signer, a.signFn
a.lock.RUnlock()
// Bail out if we're unauthorized to sign a block
snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
snap, err := a.snapshot(chain, number-1, header.ParentHash, nil)
if err != nil {
return err
}
@ -651,51 +638,35 @@ func (c *Aura) Seal(chain consensus.ChainReader, block *types.Block, results cha
select {
case results <- block.WithSeal(header):
default:
log.Warn("Sealing result is not read by miner", "sealhash", c.SealHash(header))
log.Warn("Sealing result is not read by miner", "sealhash", a.SealHash(header))
}
}()
return nil
}
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
// that a new block should have based on the previous blocks in the chain and the
// current signer.
func (c *Aura) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
snap, err := c.snapshot(chain, parent.Number.Uint64(), parent.Hash(), nil)
if err != nil {
return nil
}
return CalcDifficulty(snap, c.signer)
}
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
// that a new block should have based on the previous blocks in the chain and the
// current signer.
func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
if snap.inturn(snap.Number+1, signer) {
return new(big.Int).Set(diffInTurn)
}
return new(big.Int).Set(diffNoTurn)
// Returns difficulty constant from config
func (a *Aura) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
return new(big.Int).SetUint64(chain.Config().Aura.Difficulty)
}
// SealHash returns the hash of a block prior to it being sealed.
func (c *Aura) SealHash(header *types.Header) common.Hash {
func (a *Aura) SealHash(header *types.Header) common.Hash {
return sigHash(header)
}
// Close implements consensus.Engine. It's a noop for clique as there is are no background threads.
func (c *Aura) Close() error {
func (a *Aura) Close() error {
return nil
}
// APIs implements consensus.Engine, returning the user facing RPC API to allow
// controlling the signer voting.
func (c *Aura) APIs(chain consensus.ChainReader) []rpc.API {
func (a *Aura) APIs(chain consensus.ChainReader) []rpc.API {
return []rpc.API{{
Namespace: "clique",
Version: "1.0",
Service: &API{chain: chain, clique: c},
Service: &API{chain: chain, aura: a},
Public: false,
}}
}

View file

@ -46,7 +46,7 @@ type Tally struct {
// Snapshot is the state of the authorization voting at a given point in time.
type Snapshot struct {
config *params.CliqueConfig // Consensus engine parameters to fine tune behavior
config *params.AuraConfig // Consensus engine parameters to fine tune behavior
sigcache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover
Number uint64 `json:"number"` // Block number where the snapshot was created
@ -67,7 +67,7 @@ func (s signers) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// newSnapshot creates a new snapshot with the specified startup parameters. This
// method does not initialize the set of recent signers, so only ever use if for
// the genesis block.
func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, signers []common.Address) *Snapshot {
func newSnapshot(config *params.AuraConfig, sigcache *lru.ARCCache, number uint64, hash common.Hash, signers []common.Address) *Snapshot {
snap := &Snapshot{
config: config,
sigcache: sigcache,
@ -84,7 +84,7 @@ func newSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, number uin
}
// loadSnapshot loads an existing snapshot from the database.
func loadSnapshot(config *params.CliqueConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
func loadSnapshot(config *params.AuraConfig, sigcache *lru.ARCCache, db ethdb.Database, hash common.Hash) (*Snapshot, error) {
blob, err := db.Get(append([]byte("clique-"), hash[:]...))
if err != nil {
return nil, err

View file

@ -49,6 +49,7 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/consensus/aura"
)
type LesServer interface {
@ -220,6 +221,8 @@ func CreateConsensusEngine(ctx *node.ServiceContext, chainConfig *params.ChainCo
// If proof-of-authority is requested, set it up
if chainConfig.Clique != nil {
return clique.New(chainConfig.Clique, db)
} else if chainConfig.Aura != nil {
return aura.New(chainConfig.Aura, db)
}
// Otherwise assume proof-of-work
switch config.PowMode {
@ -375,6 +378,15 @@ func (s *Ethereum) StartMining(threads int) error {
return fmt.Errorf("signer missing: %v", err)
}
clique.Authorize(eb, wallet.SignHash)
} else {
if aura, ok := s.engine.(*aura.Aura); ok {
wallet, e := s.accountManager.Find(accounts.Account{Address: eb})
if wallet == nil || e != nil {
log.Error("Etherbase account unavailable locally", "err", err)
return fmt.Errorf("signer missing: %v", err)
}
aura.Authorize(eb, wallet.SignHash)
}
}
// If mining is started, we can disable the transaction rejection mechanism
// introduced to speed sync times.

View file

@ -48,8 +48,11 @@ var RinkebyBootnodes = []string{
}
// Goerli testnet BootNodes
var GoerliBootnodes = []string {
"",
var GoerliBootnodes = []string{
"enode://ffc0d1bcc54dee616617be06edf2b3abdd200beb3765d4475ae9fb1750d98fb0d753b30e691912bb6775b7d442b71072c91becab2141191ce73de5b6d57ac723@40.114.122.81:30303",
"enode://5b360e4baabf9e89e42e9241d4d00e7ff7a804759049be7dde30980ccce445f1fb0f91a4b9a4a28ee371b18d679fcced3cac3d73654059dd69c4a7b772bd4abf@40.87.8.76:30303",
"enode://b95468b5fa80293c4f2fce2df7a02a52f0b259063d99a78a571afcb69f736ead79ca73412b37cb2336da75066f02439d2e50e22dedc1b78380a6ab36ebdda3fc@40.87.4.17:30303",
"enode://3969e0879235c0b2bcc8957fc6d62d53763fcff0e750788eae029d40f1b4fa69f4d5a952ea3d02f85eb558faaae6bd5fbd1f394867edc6728c9fe7b9959329b0@40.87.1.35:30303",
}
// DiscoveryV5Bootnodes are the enode URLs of the P2P bootstrap nodes for the

View file

@ -94,6 +94,10 @@ var (
Aura: &AuraConfig{
Period: 15,
Epoch: 30000,
Authorities: []string{
"0x540a9fe3d2381016dec8ffba7235c6fb00b0f942",
},
Difficulty: 131072,
},
}
@ -162,6 +166,8 @@ type CliqueConfig struct {
type AuraConfig struct {
Period uint64 `json:"period"` // Number of seconds between blocks to enforce
Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint
Authorities []string `json:"authorities"` // list of addresses of authorities
Difficulty uint64 `json:"difficulty"` // Constant block difficulty
}
// String implements the stringer interface, returning the consensus engine details.
@ -378,3 +384,8 @@ func (c *ChainConfig) Rules(num *big.Int) Rules {
}
return Rules{ChainID: new(big.Int).Set(chainID), IsHomestead: c.IsHomestead(num), IsEIP150: c.IsEIP150(num), IsEIP155: c.IsEIP155(num), IsEIP158: c.IsEIP158(num), IsByzantium: c.IsByzantium(num)}
}
// Return diffulty rate for Aura concensus
func (c *AuraConfig) GetDifficulty() (num *big.Int) {
return new(big.Int).SetUint64(c.Difficulty)
}