diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index eaaa5bb6a2..e5c1e9f28e 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -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", } diff --git a/consensus/aura/api.go b/consensus/aura/api.go index fa40a80cf0..3a65a9e536 100644 --- a/consensus/aura/api.go +++ b/consensus/aura/api.go @@ -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) } diff --git a/consensus/aura/aura.go b/consensus/aura/aura.go index 33f5a00b56..cbd03abb56 100644 --- a/consensus/aura/aura.go +++ b/consensus/aura/aura.go @@ -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, }} } \ No newline at end of file diff --git a/consensus/aura/snapshot.go b/consensus/aura/snapshot.go index df2d46f22d..14ff8a2eb6 100644 --- a/consensus/aura/snapshot.go +++ b/consensus/aura/snapshot.go @@ -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 diff --git a/eth/backend.go b/eth/backend.go index 9926225f24..019fceb611 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -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. diff --git a/params/bootnodes.go b/params/bootnodes.go index b36ff2f83c..fbe978da0f 100644 --- a/params/bootnodes.go +++ b/params/bootnodes.go @@ -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 @@ -59,4 +62,4 @@ var DiscoveryV5Bootnodes = []string{ "enode://0cc5f5ffb5d9098c8b8c62325f3797f56509bff942704687b6530992ac706e2cb946b90a34f1f19548cd3c7baccbcaea354531e5983c7d1bc0dee16ce4b6440b@40.118.3.223:30304", "enode://1c7a64d76c0334b0418c004af2f67c50e36a3be60b5e4790bdac0439d21603469a85fad36f2473c9a80eb043ae60936df905fa28f1ff614c3e5dc34f15dcd2dc@40.118.3.223:30306", "enode://85c85d7143ae8bb96924f2b54f1b3e70d8c4d367af305325d30a61385a432f247d2c75c45c6b4a60335060d072d7f5b35dd1d4c45f76941f62a4f83b6e75daaf@40.118.3.223:30307", -} +} \ No newline at end of file diff --git a/params/config.go b/params/config.go index ee586ae22e..f482c672f8 100644 --- a/params/config.go +++ b/params/config.go @@ -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) +}