diff --git a/contracts/utils.go b/contracts/utils.go index 42643b4571..dd05e2d4b5 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -42,6 +42,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -374,6 +375,17 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]* } // Get candidate owner by address. +func GetCandidatesOwnerBySigner2(vmenv *vm.EVM, signerAddr common.Address) common.Address { + owner := signerAddr + owner, err := core.GetCandidateOwner(signerAddr, vmenv) + if err != nil { + log.Error("Fail get candidate owner", "error", err) + return owner + } + + return owner +} + func GetCandidatesOwnerBySigner(validator *contractValidator.TomoValidator, signerAddr common.Address) common.Address { owner := signerAddr opts := new(bind.CallOpts) @@ -386,6 +398,81 @@ func GetCandidatesOwnerBySigner(validator *contractValidator.TomoValidator, sign return owner } +// Calculate reward for holders. +func CalculateRewardForHolders2(foudationWalletAddr common.Address, vmenv *vm.EVM, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) { + rewards, err := GetRewardBalancesRate2(foudationWalletAddr, signer, calcReward, vmenv) + if err != nil { + return err, nil + } + if len(rewards) > 0 { + for holder, reward := range rewards { + state.AddBalance(holder, reward) + } + } + return nil, rewards +} + +// Get reward balance rates for master node, founder and holders. +func GetRewardBalancesRate2(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, vmenv *vm.EVM) (map[common.Address]*big.Int, error) { + owner := GetCandidatesOwnerBySigner2(vmenv, masterAddr) + balances := make(map[common.Address]*big.Int) + rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent)) + rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100)) + balances[owner] = rewardMaster + // Get voters for masternode. + voters, err := core.GetVoters(masterAddr, vmenv) + if err != nil { + log.Error("Fail to get voters", "error", err) + return nil, err + } + + if len(voters) > 0 { + totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent)) + totalVoterReward = new(big.Int).Div(totalVoterReward, new(big.Int).SetUint64(100)) + totalCap := new(big.Int) + // Get voters capacities. + voterCaps := make(map[common.Address]*big.Int) + for _, voteAddr := range voters { + voterCap, err := core.GetVoterCap(masterAddr, voteAddr, vmenv) + if err != nil { + log.Error("Fail to get vote capacity", "error", err) + return nil, err + } + + totalCap.Add(totalCap, voterCap) + voterCaps[voteAddr] = voterCap + } + if totalCap.Cmp(new(big.Int).SetInt64(0)) > 0 { + for addr, voteCap := range voterCaps { + // Only valid voter has cap > 0. + if voteCap.Cmp(new(big.Int).SetInt64(0)) > 0 { + rcap := new(big.Int).Mul(totalVoterReward, voteCap) + rcap = new(big.Int).Div(rcap, totalCap) + if balances[addr] != nil { + balances[addr].Add(balances[addr], rcap) + } else { + balances[addr] = rcap + } + } + } + } + } + + foudationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent)) + foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100)) + balances[foudationWalletAddr] = foudationReward + + jsonHolders, err := json.Marshal(balances) + if err != nil { + log.Error("Fail to parse json holders", "error", err) + return nil, err + } + log.Info("Holders reward", "holders", string(jsonHolders), "master node", masterAddr.String()) + fmt.Println("Holders reward", "holders", string(jsonHolders), "master node", masterAddr.String()) + + return balances, nil +} + // Calculate reward for holders. func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *contractValidator.TomoValidator, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) { rewards, err := GetRewardBalancesRate(foudationWalletAddr, signer, calcReward, validator) diff --git a/core/vm/validator/env.go b/core/env_validator.go similarity index 80% rename from core/vm/validator/env.go rename to core/env_validator.go index 9e24c696e3..aa62c3a913 100644 --- a/core/vm/validator/env.go +++ b/core/env_validator.go @@ -1,15 +1,14 @@ -package validator +package core import ( "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/vm" ) func NewEnv(cfg *Config) *vm.EVM { context := vm.Context{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, + CanTransfer: CanTransfer, + Transfer: Transfer, GetHash: func(uint64) common.Hash { return common.Hash{} }, Origin: cfg.Origin, diff --git a/core/runtime_validator.go b/core/runtime_validator.go new file mode 100644 index 0000000000..f1f98dff63 --- /dev/null +++ b/core/runtime_validator.go @@ -0,0 +1,205 @@ +package core + +import ( + "math" + "math/big" + "strings" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/params" +) + +// Config is a basic type specifying certain configuration flags for running +// the EVM. +type Config struct { + ChainConfig *params.ChainConfig + Difficulty *big.Int + Origin common.Address + Coinbase common.Address + BlockNumber *big.Int + Time *big.Int + GasLimit uint64 + GasPrice *big.Int + Value *big.Int + Debug bool + EVMConfig vm.Config + + State *state.StateDB + GetHashFn func(n uint64) common.Hash +} + +var abiValidator = `[{"constant":false,"inputs":[{"name":"_candidate","type":"address"}],"name":"propose","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_candidate","type":"address"},{"name":"_cap","type":"uint256"}],"name":"unvote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getCandidates","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_blockNumber","type":"uint256"}],"name":"getWithdrawCap","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_candidate","type":"address"}],"name":"getVoters","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getWithdrawBlockNumbers","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_candidate","type":"address"},{"name":"_voter","type":"address"}],"name":"getVoterCap","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"candidates","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_blockNumber","type":"uint256"},{"name":"_index","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_candidate","type":"address"}],"name":"getCandidateCap","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_candidate","type":"address"}],"name":"vote","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"candidateCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"voterWithdrawDelay","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_candidate","type":"address"}],"name":"resign","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_candidate","type":"address"}],"name":"getCandidateOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxValidatorNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"candidateWithdrawDelay","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_candidate","type":"address"}],"name":"isCandidate","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minCandidateCap","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minVoterCap","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_candidates","type":"address[]"},{"name":"_caps","type":"uint256[]"},{"name":"_firstOwner","type":"address"},{"name":"_minCandidateCap","type":"uint256"},{"name":"_minVoterCap","type":"uint256"},{"name":"_maxValidatorNumber","type":"uint256"},{"name":"_candidateWithdrawDelay","type":"uint256"},{"name":"_voterWithdrawDelay","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_voter","type":"address"},{"indexed":false,"name":"_candidate","type":"address"},{"indexed":false,"name":"_cap","type":"uint256"}],"name":"Vote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_voter","type":"address"},{"indexed":false,"name":"_candidate","type":"address"},{"indexed":false,"name":"_cap","type":"uint256"}],"name":"Unvote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_owner","type":"address"},{"indexed":false,"name":"_candidate","type":"address"},{"indexed":false,"name":"_cap","type":"uint256"}],"name":"Propose","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_owner","type":"address"},{"indexed":false,"name":"_candidate","type":"address"}],"name":"Resign","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_owner","type":"address"},{"indexed":false,"name":"_blockNumber","type":"uint256"},{"indexed":false,"name":"_cap","type":"uint256"}],"name":"Withdraw","type":"event"}]` + +// sets defaults on the config +func setDefaults(cfg *Config) { + if cfg.ChainConfig == nil { + cfg.ChainConfig = ¶ms.ChainConfig{ + ChainId: big.NewInt(1), + HomesteadBlock: new(big.Int), + DAOForkBlock: new(big.Int), + DAOForkSupport: false, + EIP150Block: new(big.Int), + EIP155Block: new(big.Int), + EIP158Block: new(big.Int), + } + } + + if cfg.Difficulty == nil { + cfg.Difficulty = new(big.Int) + } + if cfg.Time == nil { + cfg.Time = big.NewInt(time.Now().Unix()) + } + if cfg.GasLimit == 0 { + cfg.GasLimit = math.MaxUint64 + } + if cfg.GasPrice == nil { + cfg.GasPrice = new(big.Int) + } + if cfg.Value == nil { + cfg.Value = new(big.Int) + } + if cfg.BlockNumber == nil { + cfg.BlockNumber = new(big.Int) + } + if cfg.GetHashFn == nil { + cfg.GetHashFn = func(n uint64) common.Hash { + return common.BytesToHash(crypto.Keccak256([]byte(new(big.Int).SetUint64(n).String()))) + } + } +} + +// Execute executes the code using the input as call data during the execution. +// It returns the EVM's return value, the new state and an error if it failed. +// +// Executes sets up a in memory, temporarily, environment for the execution of +// the given code. It makes sure that it's restored to it's original state afterwards. +/* +func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { + if cfg == nil { + cfg = new(Config) + } + setDefaults(cfg) + + if cfg.State == nil { + db, _ := ethdb.NewMemDatabase() + cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(db)) + } + var ( + address = common.StringToAddress("contract") + vmenv = NewEnv(cfg) + sender = vm.AccountRef(cfg.Origin) + ) + cfg.State.CreateAccount(address) + // set the receiver's (the executing contract) code for execution. + cfg.State.SetCode(address, code) + // Call the code with the given configuration. + ret, _, err := vmenv.Call( + sender, + common.StringToAddress("contract"), + input, + cfg.GasLimit, + cfg.Value, + ) + + return ret, cfg.State, err +} +*/ +func NewRuntimeEVM(chainState *state.StateDB) *vm.EVM { + cfg := new(Config) + setDefaults(cfg) + db, _ := ethdb.NewMemDatabase() + cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(db)) + + var ( + address = common.HexToAddress(common.MasternodeVotingSMC) + vmenv = NewEnv(cfg) + ) + cfg.State.CreateAccount(address) + code := chainState.GetCode(common.HexToAddress(common.MasternodeVotingSMC)) + cfg.State.SetCode(address, code) + + f := func(key, val common.Hash) bool { + cfg.State.SetState(address, key, val) + return true + } + chainState.ForEachStorage(common.HexToAddress(common.MasternodeVotingSMC), f) + + return vmenv +} + +func GetVoters(candidate common.Address, vmenv *vm.EVM) ([]common.Address, error) { + + abi, err := abi.JSON(strings.NewReader(abiValidator)) + getVoters, err := abi.Pack("getVoters", candidate) + + // Call the code with the given configuration. + voters, _, err := vmenv.Call( + vm.AccountRef(common.HexToAddress(common.MasternodeVotingSMC)), + common.HexToAddress(common.MasternodeVotingSMC), + getVoters, + math.MaxUint64, + new(big.Int), + ) + + ret := common.ExtractAddressFromBytes(voters) + + return ret, err +} + +func GetCandidateOwner(candidate common.Address, vmenv *vm.EVM) (common.Address, error) { + + abi, err := abi.JSON(strings.NewReader(abiValidator)) + getCandidateOwner, err := abi.Pack("getCandidateOwner", candidate) + + // Call the code with the given configuration. + ret, _, err := vmenv.Call( + vm.AccountRef(common.HexToAddress(common.MasternodeVotingSMC)), + common.HexToAddress(common.MasternodeVotingSMC), + getCandidateOwner, + math.MaxUint64, + new(big.Int), + ) + + return common.BytesToAddress(ret), err +} + +func GetCandidateCap(candidate common.Address, vmenv *vm.EVM) (*big.Int, error) { + + abi, err := abi.JSON(strings.NewReader(abiValidator)) + getCandidateCap, err := abi.Pack("getCandidateCap", candidate) + + // Call the code with the given configuration. + ret, _, err := vmenv.Call( + vm.AccountRef(common.HexToAddress(common.MasternodeVotingSMC)), + common.HexToAddress(common.MasternodeVotingSMC), + getCandidateCap, + math.MaxUint64, + new(big.Int), + ) + + return new(big.Int).SetBytes(ret), err +} + +func GetVoterCap(candidate common.Address, voter common.Address, vmenv *vm.EVM) (*big.Int, error) { + + abi, err := abi.JSON(strings.NewReader(abiValidator)) + getVoterCap, err := abi.Pack("getVoterCap", candidate, voter) + + // Call the code with the given configuration. + ret, _, err := vmenv.Call( + vm.AccountRef(common.HexToAddress(common.MasternodeVotingSMC)), + common.HexToAddress(common.MasternodeVotingSMC), + getVoterCap, + math.MaxUint64, + new(big.Int), + ) + + return new(big.Int).SetBytes(ret), err +} diff --git a/core/vm/validator/runtime.go b/core/vm/validator/runtime.go deleted file mode 100644 index 2db1621ce6..0000000000 --- a/core/vm/validator/runtime.go +++ /dev/null @@ -1,156 +0,0 @@ -package validator - -import ( - "math" - "math/big" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/params" -) - -// Config is a basic type specifying certain configuration flags for running -// the EVM. -type Config struct { - ChainConfig *params.ChainConfig - Difficulty *big.Int - Origin common.Address - Coinbase common.Address - BlockNumber *big.Int - Time *big.Int - GasLimit uint64 - GasPrice *big.Int - Value *big.Int - Debug bool - EVMConfig vm.Config - - State *state.StateDB - GetHashFn func(n uint64) common.Hash -} - -// sets defaults on the config -func setDefaults(cfg *Config) { - if cfg.ChainConfig == nil { - cfg.ChainConfig = ¶ms.ChainConfig{ - ChainId: big.NewInt(1), - HomesteadBlock: new(big.Int), - DAOForkBlock: new(big.Int), - DAOForkSupport: false, - EIP150Block: new(big.Int), - EIP155Block: new(big.Int), - EIP158Block: new(big.Int), - } - } - - if cfg.Difficulty == nil { - cfg.Difficulty = new(big.Int) - } - if cfg.Time == nil { - cfg.Time = big.NewInt(time.Now().Unix()) - } - if cfg.GasLimit == 0 { - cfg.GasLimit = math.MaxUint64 - } - if cfg.GasPrice == nil { - cfg.GasPrice = new(big.Int) - } - if cfg.Value == nil { - cfg.Value = new(big.Int) - } - if cfg.BlockNumber == nil { - cfg.BlockNumber = new(big.Int) - } - if cfg.GetHashFn == nil { - cfg.GetHashFn = func(n uint64) common.Hash { - return common.BytesToHash(crypto.Keccak256([]byte(new(big.Int).SetUint64(n).String()))) - } - } -} - -// Execute executes the code using the input as call data during the execution. -// It returns the EVM's return value, the new state and an error if it failed. -// -// Executes sets up a in memory, temporarily, environment for the execution of -// the given code. It makes sure that it's restored to it's original state afterwards. -func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { - if cfg == nil { - cfg = new(Config) - } - setDefaults(cfg) - - if cfg.State == nil { - db, _ := ethdb.NewMemDatabase() - cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(db)) - } - var ( - address = common.StringToAddress("contract") - vmenv = NewEnv(cfg) - sender = vm.AccountRef(cfg.Origin) - ) - cfg.State.CreateAccount(address) - // set the receiver's (the executing contract) code for execution. - cfg.State.SetCode(address, code) - // Call the code with the given configuration. - ret, _, err := vmenv.Call( - sender, - common.StringToAddress("contract"), - input, - cfg.GasLimit, - cfg.Value, - ) - - return ret, cfg.State, err -} - -// Create executes the code using the EVM create method -func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { - if cfg == nil { - cfg = new(Config) - } - setDefaults(cfg) - - if cfg.State == nil { - db, _ := ethdb.NewMemDatabase() - cfg.State, _ = state.New(common.Hash{}, state.NewDatabase(db)) - } - var ( - vmenv = NewEnv(cfg) - sender = vm.AccountRef(cfg.Origin) - ) - - // Call the code with the given configuration. - code, address, leftOverGas, err := vmenv.Create( - sender, - input, - cfg.GasLimit, - cfg.Value, - ) - return code, address, leftOverGas, err -} - -// Call executes the code given by the contract's address. It will return the -// EVM's return value or an error if it failed. -// -// Call, unlike Execute, requires a config and also requires the State field to -// be set. -func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, error) { - setDefaults(cfg) - - vmenv := NewEnv(cfg) - - sender := cfg.State.GetOrNewStateObject(cfg.Origin) - // Call the code with the given configuration. - ret, leftOverGas, err := vmenv.Call( - sender, - address, - input, - cfg.GasLimit, - cfg.Value, - ) - - return ret, leftOverGas, err -} diff --git a/core/vm/validator/runtime_test.go b/core/vm/validator/runtime_test.go deleted file mode 100644 index c431842371..0000000000 --- a/core/vm/validator/runtime_test.go +++ /dev/null @@ -1,135 +0,0 @@ -package validator - -import ( - "math/big" - "strings" - "testing" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/ethdb" -) - -func TestDefaults(t *testing.T) { - cfg := new(Config) - setDefaults(cfg) - - if cfg.Difficulty == nil { - t.Error("expected difficulty to be non nil") - } - - if cfg.Time == nil { - t.Error("expected time to be non nil") - } - if cfg.GasLimit == 0 { - t.Error("didn't expect gaslimit to be zero") - } - if cfg.GasPrice == nil { - t.Error("expected time to be non nil") - } - if cfg.Value == nil { - t.Error("expected time to be non nil") - } - if cfg.GetHashFn == nil { - t.Error("expected time to be non nil") - } - if cfg.BlockNumber == nil { - t.Error("expected block number to be non nil") - } -} - -func TestEVM(t *testing.T) { - defer func() { - if r := recover(); r != nil { - t.Fatalf("crashed with: %v", r) - } - }() - - Execute([]byte{ - byte(vm.DIFFICULTY), - byte(vm.TIMESTAMP), - byte(vm.GASLIMIT), - byte(vm.PUSH1), - byte(vm.ORIGIN), - byte(vm.BLOCKHASH), - byte(vm.COINBASE), - }, nil, nil) -} - -func TestExecute(t *testing.T) { - ret, _, err := Execute([]byte{ - byte(vm.PUSH1), 10, - byte(vm.PUSH1), 0, - byte(vm.MSTORE), - byte(vm.PUSH1), 32, - byte(vm.PUSH1), 0, - byte(vm.RETURN), - }, nil, nil) - if err != nil { - t.Fatal("didn't expect error", err) - } - - num := new(big.Int).SetBytes(ret) - if num.Cmp(big.NewInt(10)) != 0 { - t.Error("Expected 10, got", num) - } -} - -func TestCall(t *testing.T) { - db, _ := ethdb.NewMemDatabase() - state, _ := state.New(common.Hash{}, state.NewDatabase(db)) - address := common.HexToAddress("0x0a") - state.SetCode(address, []byte{ - byte(vm.PUSH1), 10, - byte(vm.PUSH1), 0, - byte(vm.MSTORE), - byte(vm.PUSH1), 32, - byte(vm.PUSH1), 0, - byte(vm.RETURN), - }) - - ret, _, err := Call(address, nil, &Config{State: state}) - if err != nil { - t.Fatal("didn't expect error", err) - } - - num := new(big.Int).SetBytes(ret) - if num.Cmp(big.NewInt(10)) != 0 { - t.Error("Expected 10, got", num) - } -} - -func BenchmarkCall(b *testing.B) { - var definition = `[{"constant":true,"inputs":[],"name":"seller","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[],"name":"abort","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"value","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[],"name":"refund","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"buyer","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[],"name":"confirmReceived","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"state","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":false,"inputs":[],"name":"confirmPurchase","outputs":[],"type":"function"},{"inputs":[],"type":"constructor"},{"anonymous":false,"inputs":[],"name":"Aborted","type":"event"},{"anonymous":false,"inputs":[],"name":"PurchaseConfirmed","type":"event"},{"anonymous":false,"inputs":[],"name":"ItemReceived","type":"event"},{"anonymous":false,"inputs":[],"name":"Refunded","type":"event"}]` - - var code = common.Hex2Bytes("6060604052361561006c5760e060020a600035046308551a53811461007457806335a063b4146100865780633fa4f245146100a6578063590e1ae3146100af5780637150d8ae146100cf57806373fac6f0146100e1578063c19d93fb146100fe578063d696069714610112575b610131610002565b610133600154600160a060020a031681565b610131600154600160a060020a0390811633919091161461015057610002565b61014660005481565b610131600154600160a060020a039081163391909116146102d557610002565b610133600254600160a060020a031681565b610131600254600160a060020a0333811691161461023757610002565b61014660025460ff60a060020a9091041681565b61013160025460009060ff60a060020a9091041681146101cc57610002565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60025460009060a060020a900460ff16811461016b57610002565b600154600160a060020a03908116908290301631606082818181858883f150506002805460a060020a60ff02191660a160020a179055506040517f72c874aeff0b183a56e2b79c71b46e1aed4dee5e09862134b8821ba2fddbf8bf9250a150565b80546002023414806101dd57610002565b6002805460a060020a60ff021973ffffffffffffffffffffffffffffffffffffffff1990911633171660a060020a1790557fd5d55c8a68912e9a110618df8d5e2e83b8d83211c57a8ddd1203df92885dc881826060a15050565b60025460019060a060020a900460ff16811461025257610002565b60025460008054600160a060020a0390921691606082818181858883f150508354604051600160a060020a0391821694503090911631915082818181858883f150506002805460a060020a60ff02191660a160020a179055506040517fe89152acd703c9d8c7d28829d443260b411454d45394e7995815140c8cbcbcf79250a150565b60025460019060a060020a900460ff1681146102f057610002565b6002805460008054600160a060020a0390921692909102606082818181858883f150508354604051600160a060020a0391821694503090911631915082818181858883f150506002805460a060020a60ff02191660a160020a179055506040517f8616bbbbad963e4e65b1366f1d75dfb63f9e9704bbbf91fb01bec70849906cf79250a15056") - - abi, err := abi.JSON(strings.NewReader(definition)) - if err != nil { - b.Fatal(err) - } - - cpurchase, err := abi.Pack("confirmPurchase") - if err != nil { - b.Fatal(err) - } - creceived, err := abi.Pack("confirmReceived") - if err != nil { - b.Fatal(err) - } - refund, err := abi.Pack("refund") - if err != nil { - b.Fatal(err) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - for j := 0; j < 400; j++ { - Execute(code, cpurchase, nil) - Execute(code, creceived, nil) - Execute(code, refund, nil) - } - } -} diff --git a/eth/backend.go b/eth/backend.go index c05909bfd6..dc15a048e2 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -37,7 +37,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/consensus/posv" "github.com/ethereum/go-ethereum/contracts" - "github.com/ethereum/go-ethereum/contracts/validator/contract" + // "github.com/ethereum/go-ethereum/contracts/validator/contract" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/bloombits" "github.com/ethereum/go-ethereum/core/state" @@ -323,7 +323,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { return err, nil } // Get validator. - validator, err := contract.NewTomoValidator(common.HexToAddress(common.MasternodeVotingSMC), client) + // validator, err := contract.NewTomoValidator(common.HexToAddress(common.MasternodeVotingSMC), client) if err != nil { log.Error("Fail get instance of Tomo Validator", "error", err) return err, nil @@ -331,8 +331,10 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { // Add reward for coin holders. voterResults := make(map[common.Address]interface{}) if len(signers) > 0 { + vmenv := core.NewRuntimeEVM(state) for signer, calcReward := range rewardSigners { - err, rewards := contracts.CalculateRewardForHolders(foudationWalletAddr, validator, state, signer, calcReward) + // err, rewards := contracts.CalculateRewardForHolders(foudationWalletAddr, validator, state, signer, calcReward) + err, rewards := contracts.CalculateRewardForHolders2(foudationWalletAddr, vmenv, state, signer, calcReward) if err != nil { log.Error("Fail to calculate reward for holders.", "error", err) return err, nil @@ -341,7 +343,8 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { } } rewards["rewards"] = voterResults - log.Debug("Time Calculated HookReward ", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start))) + // log.Debug("Time Calculated HookReward ", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start))) + fmt.Println("Time Calculated HookReward ", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start))) } return nil, rewards }