diff --git a/consensus/cheap/cheap.go b/consensus/cheap/cheap.go new file mode 100644 index 000000000000..f01a0db902fe --- /dev/null +++ b/consensus/cheap/cheap.go @@ -0,0 +1,138 @@ +package cheap + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/cheap/contracts" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/rpc" +) + +type Cheapconsensus struct { + config ethash.Config + ethash *ethash.Ethash + api *ethapi.PublicBlockChainAPI + api_init bool + contract *contract +} + +const ( + EnforcingCheckpointing = false + MIN_VERIFIERS = 10 + MINIMUM_BLOCK_LOOKBACK = 100 +) + +func New(config ethash.Config, notify []string, noverify bool, api *ethapi.PublicBlockChainAPI) *Cheapconsensus { + ethash := ethash.New(config, notify, noverify) + + return &Cheapconsensus{ + config: config, + ethash: ethash, + api: api, + api_init: false, + } +} + +func (c *Cheapconsensus) Author(header *types.Header) (common.Address, error) { + return c.ethash.Author(header) +} +func (c *Cheapconsensus) VerifyHeader(chain consensus.ChainHeaderReader, header *types.Header, seal bool) error { + + if c.api_init && c.contract != nil { + trusted, err := c.contract.GetTrusted() + // TODO: find an elegant way of passing errors if enforcing checkpointing or just log warns if not + if err != nil { + fmt.Println("error getting trusted", "err", err) + } + + if len(trusted) < MIN_VERIFIERS { + fmt.Println("too little trusted addresses to work properly") + } + + live_height := header.Number + last_possible := big.NewInt(0) + last_possible = last_possible.Sub(live_height, big.NewInt(MINIMUM_BLOCK_LOOKBACK)) + last_possible = last_possible.Mod(last_possible, big.NewInt(10)) + // Nice uint64 + last_possible_block := chain.GetHeaderByNumber(last_possible.Uint64()) + + var matched []common.Address + //TODO: distribute rewards + for _, v := range trusted { + cp, err := c.contract.GetBlockByNumber(*last_possible, v) + if err != nil { + fmt.Println("Error getting checkpoint", "err", err) + } + if cp.Hash == last_possible_block.Hash() && cp.SavedBlockNumber == last_possible_block.Number { + matched = append(matched, v) + } + } + + treshold := len(trusted) / 2 + 1 + if len(matched) < treshold { + fmt.Println("Not enough votes, should be treatead as invalid chain") + } + + } else { + fmt.Printf("Api not ready yet...\n") + } + return c.ethash.VerifyHeader(chain, header, seal) +} +func (c *Cheapconsensus) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { + return c.ethash.VerifyHeaders(chain, headers, seals) +} +func (c *Cheapconsensus) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { + return c.ethash.VerifyUncles(chain, block) +} +func (c *Cheapconsensus) VerifySeal(chain consensus.ChainHeaderReader, header *types.Header) error { + return c.ethash.VerifySeal(chain, header) +} +func (c *Cheapconsensus) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { + return c.ethash.Prepare(chain, header) +} +func (c *Cheapconsensus) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { + c.ethash.Finalize(chain, header, state, txs, uncles) +} +func (c *Cheapconsensus) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { + // FIXME: this is bad, we need a better way to track api ready state + if c.api != nil { + fmt.Printf("\n\nEthapi is %p\n", c.api) + fmt.Printf("Chain ID: %d\n\n\n", c.api.ChainId().ToInt()) + + //fmt.Printf("%s\n", string(state.Dump(false, false, false))) + code := state.GetCode(contracts.Contracts["Checkpointer"].Address) + if len(code) > 0 { + c.contract = InitCheckpointerContract(c.api) + } + c.api_init = true + } + return c.ethash.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts) +} +func (c *Cheapconsensus) Seal(chain consensus.ChainHeaderReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { + return c.ethash.Seal(chain, block, results, stop) +} +func (c *Cheapconsensus) SealHash(header *types.Header) common.Hash { + return c.ethash.SealHash(header) +} +func (c *Cheapconsensus) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { + return c.ethash.CalcDifficulty(chain, time, parent) +} +func (c *Cheapconsensus) APIs(chain consensus.ChainHeaderReader) []rpc.API { + return c.ethash.APIs(chain) +} +func (c *Cheapconsensus) Close() error { + return c.ethash.Close() +} +func (c *Cheapconsensus) SetThreads(threads int) { + c.ethash.SetThreads(threads) +} + +func (c *Cheapconsensus) Threads() int { + return c.ethash.Threads() +} diff --git a/consensus/cheap/contract_interaction.go b/consensus/cheap/contract_interaction.go new file mode 100644 index 000000000000..b696cb2635cc --- /dev/null +++ b/consensus/cheap/contract_interaction.go @@ -0,0 +1,145 @@ +package cheap + +import ( + "fmt" + "math" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/consensus/cheap/contracts" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/rpc" + "golang.org/x/net/context" +) + +func loadAbi(s string) (abi.ABI, error) { + return abi.JSON(strings.NewReader(s)) +} + +func makeData(Method abi.Method, args ...interface{}) hexutil.Bytes { + + if args == nil { + return (hexutil.Bytes)(Method.ID) + } + + d, err := Method.Inputs.Pack(args...) + if err != nil { + panic("pack error") + } + + return (hexutil.Bytes)(append(Method.ID, d...)) +} + +type contract struct { + api *ethapi.PublicBlockChainAPI + abi abi.ABI + addr common.Address +} + +func NewContract(api *ethapi.PublicBlockChainAPI, abi_json string, addr common.Address) (*contract, error) { + contract_abi, err := loadAbi(abi_json) + if err != nil { + fmt.Println(err) + return nil, err + } + + return &contract{ + api: api, + abi: contract_abi, + addr: addr, + }, nil +} + +func (c *contract) Call(method_name string, args ...interface{}) ([]byte, error) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + method := c.abi.Methods[method_name] + bData := makeData(method, args...) + to := c.addr + //TOOD: Use reasonble amoutn of gas, get rid of the warn + gas := (hexutil.Uint64)(math.MaxUint32) + callData := ethapi.CallArgs{ + Data: &bData, + To: &to, + Gas: &gas, + } + + res, err := c.api.Call( + ctx, + callData, + rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(c.api.BlockNumber())), + nil, + ) + + if err != nil { + return make([]byte, 0), err + } + + return res, nil +} +func (c *contract) UnpackResult(data []byte, method_name string) ([]interface{}, error) { + method := c.abi.Methods[method_name] + res, err := method.Outputs.Unpack(data) + if err != nil { + return nil, err + } + return res, nil +} + +type Checkpoint struct { + SavedBlockNumber *big.Int "json:\"savedBlockNumber\"" + Hash [32]uint8 "json:\"hash\"" +} + +func TrustedFromInterface(i []interface{}) []common.Address { + return *abi.ConvertType(i[0], new([]common.Address)).(*[]common.Address) +} + +func CheckpointFromInterface(i []interface{}) *Checkpoint { + return abi.ConvertType(i[0], new(Checkpoint)).(*Checkpoint) +} + +func (c *contract) GetTrusted() ([]common.Address, error) { + data, err := c.Call("getTrusted") + + if err != nil { + return nil, fmt.Errorf("call faliled with error: %s", err) + } + + unpack, err := c.UnpackResult(data, "getTrusted") + trusted := TrustedFromInterface(unpack) + if err != nil { + return nil, fmt.Errorf("failed to unpack data: %s", err) + } + + return trusted, nil +} + +func (c *contract) GetBlockByNumber(number big.Int, verifier common.Address) (*Checkpoint, error){ + data, err := c.Call("getBlockByNumber", number, verifier) + + if err != nil { + return nil, fmt.Errorf("call faliled with error: %s", err) + } + + unpack, err := c.UnpackResult(data, "getBlockByNumber") + point := CheckpointFromInterface(unpack) + if err != nil { + return nil, fmt.Errorf("failed to unpack data: %s", err) + } + + return point, nil + +} + +func InitCheckpointerContract(api *ethapi.PublicBlockChainAPI) (*contract) { + contract, err := NewContract(api, contracts.Contracts["Checkpointer"].Abi, contracts.Contracts["Checkpointer"].Address) + if err != nil { + panic(err) + } + return contract +} diff --git a/consensus/cheap/contracts/contract.go b/consensus/cheap/contracts/contract.go new file mode 100644 index 000000000000..6e02260629d2 --- /dev/null +++ b/consensus/cheap/contracts/contract.go @@ -0,0 +1,147 @@ +package contracts + +import ( + "encoding/hex" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" +) + +type Contract struct { + Address common.Address + Abi string + Code string +} +// TODO: make this read soidity files and populate abi and code +var Contracts map[string]Contract = map[string]Contract { + "Dummy" : { + Address: common.HexToAddress("0x1337000000000000000000000000000000000000"), + Abi: `[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "A", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "pure", + "type": "function" + } + ]`, + Code: + "6080604052348015600f57600080fd5b506004361060285760003560e01c8063f446c1d014602d575b600080fd5b60336047565b604051603e9190605e565b60405180910390f35b6000611337905090565b6058816077565b82525050565b6000602082019050607160008301846051565b92915050565b600067ffffffffffffffff8216905091905056fea26469706673582212208eb084396988ccea5e49eca052fd74fe9f102653d5e0ddebdcfb2138428db45b64736f6c63430007060033", + }, + "Checkpointer" : { + Address: common.HexToAddress("0x1111000000000000000000000000000000000000"), + Abi: `[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "number", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "blockHash", + "type": "bytes32" + } + ], + "name": "attest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "toTrust", + "type": "address" + } + ], + "name": "trust", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + }, + { + "internalType": "address", + "name": "verifier", + "type": "address" + } + ], + "name": "getBlockByNumber", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "hash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "savedBlockNumber", + "type": "uint256" + } + ], + "internalType": "struct Checkpointer.Checkpoint", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getTrusted", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ]`, + Code: "608060405234801561001057600080fd5b506004361061004c5760003560e01c806302165185146100515780630a28b1081461008157806317e859261461009f5780634637d827146100bb575b600080fd5b61006b6004803603810190610066919061088f565b6100d7565b6040516100789190610b07565b60405180910390f35b610089610155565b6040516100969190610a65565b60405180910390f35b6100b960048036038101906100b491906108cb565b610331565b005b6100d560048036038101906100d09190610866565b6104da565b005b6100df61080a565b60008084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180604001604052908160008201548152602001600182015481525050905092915050565b6060600060028054905067ffffffffffffffff81111561019e577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156101cc5781602001602082028036833780820191505090505b50905060005b60028054905081101561032957600160006002838154811061021d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168282815181106102dc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808061032190610be6565b9150506101d2565b508091505090565b606461ffff16431015610379576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161037090610a87565b60405180910390fd5b606461ffff164361038a9190610b6c565b8211156103cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c390610ae7565b60405180910390fd5b6000824090506000801b811415610418576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161040f90610ac7565b60405180910390fd5b81811461045a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045190610aa7565b60405180910390fd5b60405180604001604052808381526020018481525060008085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000820151816000015560208201518160010155905050505050565b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550606461ffff1660028054905010156105d2576002339080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610807565b6000806002600081548110610610577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163190506000600190505b6002805490508110156107805781600282815481106106a3577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1631101561076d5780925060028181548110610728577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163191505b808061077890610be6565b91505061065b565b5033600283815481106107bc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505b50565b604051806040016040528060008019168152602001600081525090565b60008135905061083681610d28565b92915050565b60008135905061084b81610d3f565b92915050565b60008135905061086081610d56565b92915050565b60006020828403121561087857600080fd5b600061088684828501610827565b91505092915050565b600080604083850312156108a257600080fd5b60006108b085828601610851565b92505060206108c185828601610827565b9150509250929050565b600080604083850312156108de57600080fd5b60006108ec85828601610851565b92505060206108fd8582860161083c565b9150509250929050565b6000610913838361091f565b60208301905092915050565b61092881610ba0565b82525050565b600061093982610b32565b6109438185610b4a565b935061094e83610b22565b8060005b8381101561097f5781516109668882610907565b975061097183610b3d565b925050600181019050610952565b5085935050505092915050565b61099581610bb2565b82525050565b60006109a8601083610b5b565b91506109b382610c5e565b602082019050919050565b60006109cb602383610b5b565b91506109d682610c87565b604082019050919050565b60006109ee601383610b5b565b91506109f982610cd6565b602082019050919050565b6000610a11601383610b5b565b9150610a1c82610cff565b602082019050919050565b604082016000820151610a3d600085018261098c565b506020820151610a506020850182610a56565b50505050565b610a5f81610bdc565b82525050565b60006020820190508181036000830152610a7f818461092e565b905092915050565b60006020820190508181036000830152610aa08161099b565b9050919050565b60006020820190508181036000830152610ac0816109be565b9050919050565b60006020820190508181036000830152610ae0816109e1565b9050919050565b60006020820190508181036000830152610b0081610a04565b9050919050565b6000604082019050610b1c6000830184610a27565b92915050565b6000819050602082019050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b6000610b7782610bdc565b9150610b8283610bdc565b925082821015610b9557610b94610c2f565b5b828203905092915050565b6000610bab82610bbc565b9050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000610bf182610bdc565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610c2457610c23610c2f565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f636861696e20697320746f6f206e657700000000000000000000000000000000600082015250565b7f626c6f636b6861736820646f65736e2774206d6174636820617474657374617460008201527f696f6e0000000000000000000000000000000000000000000000000000000000602082015250565b7f626c6f636b68617368206e6f7420666f756e6400000000000000000000000000600082015250565b7f626c6f636b20697320746f6f20726563656e7400000000000000000000000000600082015250565b610d3181610ba0565b8114610d3c57600080fd5b50565b610d4881610bb2565b8114610d5357600080fd5b50565b610d5f81610bdc565b8114610d6a57600080fd5b5056fea2646970667358221220a89d56318ed129150ca361d9dc64efb8547f5299e51a49fcef1656c571b8769e64736f6c63430008010033", + }, +} + + +func Deploy(state *state.StateDB) { + for n, c := range Contracts { + code, err := hex.DecodeString(c.Code) + if err != nil { + panic(fmt.Sprintf("Bad code for contract %s\n", n)) + } + + state.SetCode(c.Address, code) + // TODO: find a way to check if code was set correctly + } +} \ No newline at end of file diff --git a/core/chain_makers.go b/core/chain_makers.go index 2192b0a29b5d..ceeb0ed46fe0 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/cheap/contracts" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -207,6 +208,9 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 { misc.ApplyDAOHardFork(statedb) } + // Deploy system contracts + contracts.Deploy(statedb) + if config.CheapForkBlock != nil && config.CheapForkBlock.Cmp(b.header.Number) == 0 { misc.ApplyCheapHardFork(statedb) } diff --git a/core/state_processor.go b/core/state_processor.go index c94c8efebcd6..0adec2bd463b 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -21,6 +21,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/cheap/contracts" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -67,6 +68,8 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(statedb) } + contracts.Deploy(statedb) + if p.config.CheapForkBlock != nil && p.config.CheapForkBlock.Cmp(block.Number()) == 0 { misc.ApplyCheapHardFork(statedb) } diff --git a/eth/backend.go b/eth/backend.go index 03b0b319b76c..4389aeda025d 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -29,6 +29,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/cheap" "github.com/ethereum/go-ethereum/consensus/clique" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" @@ -123,13 +124,13 @@ func New(stack *node.Node, config *Config) (*Ethereum, error) { return nil, genesisErr } log.Info("Initialised chain configuration", "config", chainConfig) - + eth := &Ethereum{ config: config, chainDb: chainDb, eventMux: stack.EventMux(), accountManager: stack.AccountManager(), - engine: CreateConsensusEngine(stack, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb), + //engine: CreateConsensusEngine(stack, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb), closeBloomHandler: make(chan struct{}), networkID: config.NetworkId, gasPrice: config.Miner.GasPrice, @@ -139,6 +140,10 @@ func New(stack *node.Node, config *Config) (*Ethereum, error) { p2pServer: stack.Server(), } + eth.APIBackend = &EthAPIBackend{stack.Config().ExtRPCEnabled(), eth, nil} + pubApi := ethapi.NewPublicBlockChainAPI(eth.APIBackend) + eth.engine = CreateConsensusEngine(stack, chainConfig, &config.Ethash, config.Miner.Notify, config.Miner.Noverify, chainDb, pubApi) + bcVersion := rawdb.ReadDatabaseVersion(chainDb) var dbVer = "" if bcVersion != nil { @@ -241,7 +246,7 @@ func makeExtraData(extra []byte) []byte { } // CreateConsensusEngine creates the required type of consensus engine instance for an Ethereum service -func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine { +func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database, api *ethapi.PublicBlockChainAPI) consensus.Engine { // If proof-of-authority is requested, set it up if chainConfig.Clique != nil { return clique.New(chainConfig.Clique, db) @@ -258,7 +263,7 @@ func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, co log.Warn("Ethash used in shared mode") return ethash.NewShared() default: - engine := ethash.New(ethash.Config{ + engine := cheap.New(ethash.Config{ CacheDir: stack.ResolvePath(config.CacheDir), CachesInMem: config.CachesInMem, CachesOnDisk: config.CachesOnDisk, @@ -267,7 +272,7 @@ func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, co DatasetsInMem: config.DatasetsInMem, DatasetsOnDisk: config.DatasetsOnDisk, DatasetsLockMmap: config.DatasetsLockMmap, - }, notify, noverify) + }, notify, noverify, api) engine.SetThreads(-1) // Disable CPU mining return engine } diff --git a/go.mod b/go.mod index 0f47809ef6bd..d7f466bfcd24 100644 --- a/go.mod +++ b/go.mod @@ -62,7 +62,7 @@ require ( github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/mobile v0.0.0-20200801112145-973feb4309de // indirect - golang.org/x/net v0.0.0-20200822124328-c89045814202 // indirect + golang.org/x/net v0.0.0-20200822124328-c89045814202 golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8 golang.org/x/text v0.3.3 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 diff --git a/les/client.go b/les/client.go index 37250d076fde..b8e62f1393ca 100644 --- a/les/client.go +++ b/les/client.go @@ -104,7 +104,8 @@ func New(stack *node.Node, config *eth.Config) (*LightEthereum, error) { eventMux: stack.EventMux(), reqDist: newRequestDistributor(peers, &mclock.System{}), accountManager: stack.AccountManager(), - engine: eth.CreateConsensusEngine(stack, chainConfig, &config.Ethash, nil, false, chainDb), + // TODO? make cheapconsensus work with LesApiBackend + engine: eth.CreateConsensusEngine(stack, chainConfig, &config.Ethash, nil, false, chainDb, nil), bloomRequests: make(chan chan *bloombits.Retrieval), bloomIndexer: eth.NewBloomIndexer(chainDb, params.BloomBitsBlocksClient, params.HelperTrieConfirmations), valueTracker: lpc.NewValueTracker(lespayDb, &mclock.System{}, requestList, time.Minute, 1/float64(time.Hour), 1/float64(time.Hour*100), 1/float64(time.Hour*1000)), diff --git a/miner/worker.go b/miner/worker.go index abdeed2c48cd..364da813da48 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -27,6 +27,7 @@ import ( mapset "github.com/deckarep/golang-set" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/cheap/contracts" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" @@ -908,6 +909,9 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64) if w.chainConfig.DAOForkSupport && w.chainConfig.DAOForkBlock != nil && w.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(env.state) } + + contracts.Deploy(env.state) + if w.chainConfig.CheapForkBlock != nil && w.chainConfig.CheapForkBlock.Cmp(header.Number) == 0 { misc.ApplyCheapHardFork(env.state) }