Skip to content

Commit

Permalink
Allow miners to specify a verification rewards recipient (ethereum#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
asaj authored Oct 12, 2018
1 parent 3114540 commit bbd1057
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 46 deletions.
11 changes: 6 additions & 5 deletions abe/abe.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ func decryptPhoneNumber(request types.VerificationRequest, account accounts.Acco
return string(phoneNumber), nil
}

func createVerificationMessage(request types.VerificationRequest, account accounts.Account, wallet accounts.Wallet) (string, error) {
signature, err := wallet.SignHash(account, request.UnsignedMessageHash.Bytes())
func createVerificationMessage(request types.VerificationRequest, verificationRewardsAddress common.Address, account accounts.Account, wallet accounts.Wallet) (string, error) {
unsignedMessage := crypto.Keccak256(append(request.CodeHash.Bytes(), verificationRewardsAddress.Bytes()...))
signature, err := wallet.SignHash(account, unsignedMessage)
if err != nil {
return "", err
}
return fmt.Sprintf("Celo verification code: %s:%d", base64.URLEncoding.EncodeToString(signature), request.VerificationIndex), nil
return fmt.Sprintf("Celo verification code: %s:%d:%s", base64.URLEncoding.EncodeToString(signature), request.VerificationIndex, base64.URLEncoding.EncodeToString(verificationRewardsAddress.Bytes())), nil
}

func sendSms(phoneNumber string, message string) error {
Expand All @@ -75,7 +76,7 @@ func sendSms(phoneNumber string, message string) error {
return err
}

func SendVerificationMessages(receipts []*types.Receipt, block *types.Block, coinbase common.Address, accountManager *accounts.Manager) {
func SendVerificationMessages(receipts []*types.Receipt, block *types.Block, coinbase common.Address, accountManager *accounts.Manager, verificationRewardsAddress common.Address) {
account := accounts.Account{Address: coinbase}
wallet, err := accountManager.Find(account)
if err != nil {
Expand All @@ -95,7 +96,7 @@ func SendVerificationMessages(receipts []*types.Receipt, block *types.Block, coi
}
log.Debug(fmt.Sprintf("[Celo] Phone number %s requesting verification", phoneNumber))

message, err := createVerificationMessage(request, account, wallet)
message, err := createVerificationMessage(request, verificationRewardsAddress, account, wallet)
if err != nil {
log.Error("[Celo] Failed to create verification message", "err", err)
continue
Expand Down
1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ var (
utils.MinerLegacyExtraDataFlag,
utils.MinerRecommitIntervalFlag,
utils.MinerNoVerfiyFlag,
utils.MinerVerificationRewardsFlag,
utils.NATFlag,
utils.NoDiscoverFlag,
utils.DiscoveryV5Flag,
Expand Down
1 change: 1 addition & 0 deletions cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ var AppHelpFlagGroups = []flagGroup{
utils.MinerExtraDataFlag,
utils.MinerRecommitIntervalFlag,
utils.MinerNoVerfiyFlag,
utils.MinerVerificationRewardsFlag,
},
},
{
Expand Down
26 changes: 26 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,13 @@ var (
Name: "miner.noverify",
Usage: "Disable remote sealing verification",
}
MinerVerificationRewardsFlag = cli.StringFlag{
Name: "miner.verificationrewards",
Usage: "Account address to which to send the verification rewards.",
// TODO(sklanje): Update this to Celo verification pool address.
Value: "0xfeE1a22F43BeeCB912B5a4912ba87527682ef0fC",
}

// Account settings
UnlockedAccountFlag = cli.StringFlag{
Name: "unlock",
Expand Down Expand Up @@ -865,6 +872,24 @@ func setEtherbase(ctx *cli.Context, ks *keystore.KeyStore, cfg *eth.Config) {
}
}

// setVerificationRewards retrieves the verificationrewards either from the directly specified
// command line flags or from the keystore if CLI indexed.
func setVerificationRewards(ctx *cli.Context, ks *keystore.KeyStore, cfg *eth.Config) {
// Extract the current verificationrewards
var verificationrewards string
if ctx.GlobalIsSet(MinerVerificationRewardsFlag.Name) {
verificationrewards = ctx.GlobalString(MinerVerificationRewardsFlag.Name)
}
// Convert the verificationrewards into an address and configure it
if verificationrewards != "" {
account, err := MakeAddress(ks, verificationrewards)
if err != nil {
Fatalf("Invalid miner verificationrewards: %v", err)
}
cfg.MinerVerificationRewards = account.Address
}
}

// MakePasswordList reads password lines from the file specified by the global --password flag.
func MakePasswordList(ctx *cli.Context) []string {
path := ctx.GlobalString(PasswordFileFlag.Name)
Expand Down Expand Up @@ -1109,6 +1134,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {

ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
setEtherbase(ctx, ks, cfg)
setVerificationRewards(ctx, ks, cfg)
setGPO(ctx, &cfg.GPO)
setTxPool(ctx, &cfg.TxPool)
setEthash(ctx, cfg)
Expand Down
14 changes: 7 additions & 7 deletions core/types/receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ const (

// VerificationRequest represents a request for verification in the Celo ABE protocol.
type VerificationRequest struct {
PhoneHash common.Hash
UnsignedMessageHash common.Hash
VerificationIndex *big.Int
Verifier common.Address
EncryptedPhone hexutil.Bytes
PhoneHash common.Hash
CodeHash common.Hash
VerificationIndex *big.Int
Verifier common.Address
EncryptedPhone hexutil.Bytes
}

// Receipt represents the results of a transaction.
Expand Down Expand Up @@ -110,14 +110,14 @@ func NewReceipt(root []byte, failed bool, cumulativeGasUsed uint64) *Receipt {
// Decode a VerificationRequest from raw input bytes.
// Input is expected to be encoded in the following manner:
// input[0:32]: bytes32 phoneHash
// input[32:64]: bytes32 unsignedMessageHash
// input[32:64]: bytes32 codeHash
// input[64:96]: bytes32 verificationIndex
// input[96:128]: address verifier
// input[96:] bytes encryptedPhone
func DecodeVerificationRequest(input []byte) (VerificationRequest, error) {
var v VerificationRequest
v.PhoneHash = common.BytesToHash(input[0:32])
v.UnsignedMessageHash = common.BytesToHash(input[32:64])
v.CodeHash = common.BytesToHash(input[32:64])
var parsed bool
v.VerificationIndex, parsed = math.ParseBig256(hexutil.Encode(input[64:96]))
if !parsed {
Expand Down
2 changes: 1 addition & 1 deletion eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
return nil, err
}

eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine, config.MinerRecommit, config.MinerGasFloor, config.MinerGasCeil)
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine, config.MinerRecommit, config.MinerGasFloor, config.MinerGasCeil, config.MinerVerificationRewards)
eth.miner.SetExtra(makeExtraData(config.MinerExtraData))

eth.APIBackend = &EthAPIBackend{eth, nil}
Expand Down
17 changes: 9 additions & 8 deletions eth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,15 @@ type Config struct {
TrieTimeout time.Duration

// Mining-related options
Etherbase common.Address `toml:",omitempty"`
MinerNotify []string `toml:",omitempty"`
MinerExtraData []byte `toml:",omitempty"`
MinerGasFloor uint64
MinerGasCeil uint64
MinerGasPrice *big.Int
MinerRecommit time.Duration
MinerNoverify bool
Etherbase common.Address `toml:",omitempty"`
MinerNotify []string `toml:",omitempty"`
MinerExtraData []byte `toml:",omitempty"`
MinerGasFloor uint64
MinerGasCeil uint64
MinerGasPrice *big.Int
MinerRecommit time.Duration
MinerNoverify bool
MinerVerificationRewards common.Address

// Ethash options
Ethash ethash.Config
Expand Down
4 changes: 2 additions & 2 deletions miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ type Miner struct {
shouldStart int32 // should start indicates whether we should start after sync
}

func New(eth Backend, config *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, recommit time.Duration, gasFloor, gasCeil uint64) *Miner {
func New(eth Backend, config *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine, recommit time.Duration, gasFloor, gasCeil uint64, verificationRewards common.Address) *Miner {
miner := &Miner{
eth: eth,
mux: mux,
engine: engine,
exitCh: make(chan struct{}),
worker: newWorker(config, engine, eth, mux, recommit, gasFloor, gasCeil),
worker: newWorker(config, engine, eth, mux, recommit, gasFloor, gasCeil, verificationRewards),
canStart: 1,
}
go miner.update()
Expand Down
48 changes: 26 additions & 22 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,30 +175,34 @@ type worker struct {
skipSealHook func(*task) bool // Method to decide whether skipping the sealing.
fullTaskHook func() // Method to call before pushing the full sealing task.
resubmitHook func(time.Duration, time.Duration) // Method to call upon updating resubmitting interval.

// Verification Service
verificationRewards common.Address
}

func newWorker(config *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, recommit time.Duration, gasFloor, gasCeil uint64) *worker {
func newWorker(config *params.ChainConfig, engine consensus.Engine, eth Backend, mux *event.TypeMux, recommit time.Duration, gasFloor, gasCeil uint64, verificationRewards common.Address) *worker {
worker := &worker{
config: config,
engine: engine,
eth: eth,
mux: mux,
chain: eth.BlockChain(),
gasFloor: gasFloor,
gasCeil: gasCeil,
possibleUncles: make(map[common.Hash]*types.Block),
unconfirmed: newUnconfirmedBlocks(eth.BlockChain(), miningLogAtDepth),
pendingTasks: make(map[common.Hash]*task),
txsCh: make(chan core.NewTxsEvent, txChanSize),
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
chainSideCh: make(chan core.ChainSideEvent, chainSideChanSize),
newWorkCh: make(chan *newWorkReq),
taskCh: make(chan *task),
resultCh: make(chan *types.Block, resultQueueSize),
exitCh: make(chan struct{}),
startCh: make(chan struct{}, 1),
resubmitIntervalCh: make(chan time.Duration),
resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize),
config: config,
engine: engine,
eth: eth,
mux: mux,
chain: eth.BlockChain(),
gasFloor: gasFloor,
gasCeil: gasCeil,
verificationRewards: verificationRewards,
possibleUncles: make(map[common.Hash]*types.Block),
unconfirmed: newUnconfirmedBlocks(eth.BlockChain(), miningLogAtDepth),
pendingTasks: make(map[common.Hash]*task),
txsCh: make(chan core.NewTxsEvent, txChanSize),
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
chainSideCh: make(chan core.ChainSideEvent, chainSideChanSize),
newWorkCh: make(chan *newWorkReq),
taskCh: make(chan *task),
resultCh: make(chan *types.Block, resultQueueSize),
exitCh: make(chan struct{}),
startCh: make(chan struct{}, 1),
resubmitIntervalCh: make(chan time.Duration),
resubmitAdjustCh: make(chan *intervalAdjust, resubmitAdjustChanSize),
}
// Subscribe NewTxsEvent for tx pool
worker.txsSub = eth.TxPool().SubscribeNewTxsEvent(worker.txsCh)
Expand Down Expand Up @@ -962,7 +966,7 @@ func (w *worker) commit(uncles []*types.Header, interval func(), update bool, st

log.Info("Commit new mining work", "number", block.Number(), "sealhash", w.engine.SealHash(block.Header()),
"uncles", len(uncles), "txs", w.current.tcount, "gas", block.GasUsed(), "fees", feesEth, "elapsed", common.PrettyDuration(time.Since(start)))
abe.SendVerificationMessages(w.current.receipts, block, w.coinbase, w.eth.AccountManager())
abe.SendVerificationMessages(w.current.receipts, block, w.coinbase, w.eth.AccountManager(), w.verificationRewards)

case <-w.exitCh:
log.Info("Worker has exited")
Expand Down
5 changes: 4 additions & 1 deletion miner/worker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ var (
testUserKey, _ = crypto.GenerateKey()
testUserAddress = crypto.PubkeyToAddress(testUserKey.PublicKey)

testVerificationRewardsKey, _ = crypto.GenerateKey()
testVerificationRewardsAddress = crypto.PubkeyToAddress(testVerificationRewardsKey.PublicKey)

// Test transactions
pendingTxs []*types.Transaction
newTxs []*types.Transaction
Expand Down Expand Up @@ -140,7 +143,7 @@ func (b *testWorkerBackend) PostChainEvents(events []interface{}) {
func newTestWorker(t *testing.T, chainConfig *params.ChainConfig, engine consensus.Engine, blocks int) (*worker, *testWorkerBackend) {
backend := newTestWorkerBackend(t, chainConfig, engine, blocks)
backend.txPool.AddLocals(pendingTxs)
w := newWorker(chainConfig, engine, backend, new(event.TypeMux), time.Second, params.GenesisGasLimit, params.GenesisGasLimit)
w := newWorker(chainConfig, engine, backend, new(event.TypeMux), time.Second, params.GenesisGasLimit, params.GenesisGasLimit, testVerificationRewardsAddress)
w.setEtherbase(testBankAddress)
return w, backend
}
Expand Down

0 comments on commit bbd1057

Please sign in to comment.