[project] Endless tech debt (#2777)

* [internal] Remove dead RPC/wallet

* [rpc] Reduce API surface area for dead RPC

* [node] Remove dead flags, unused setters

* [project] Unused logger, too many loggers

* [core] staticcheck fixes, remove unused db keys

* [project] More dead code through, now in param and genesis

* [internal] Useless test
pull/2776/head
Edgar Aroutiounian 5 years ago committed by GitHub
parent e484b556ae
commit a1c8156afc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 214
      accounts/manager.go
  2. 1
      api/service/manager.go
  3. 110
      cmd/harmony/main.go
  4. 10
      consensus/consensus.go
  5. 25
      core/genesis.go
  6. 4
      core/rawdb/accessors_indexes.go
  7. 61
      core/rawdb/schema.go
  8. 1
      go.mod
  9. 6
      hmy/api_backend.go
  10. 42
      hmy/backend.go
  11. 11
      internal/hmyapi/apiv1/backend.go
  12. 70
      internal/hmyapi/apiv1/private_account.go
  13. 28
      internal/hmyapi/apiv1/public_account.go
  14. 37
      internal/hmyapi/apiv1/transactionpool.go
  15. 31
      internal/hmyapi/apiv2/backend.go
  16. 70
      internal/hmyapi/apiv2/private_account.go
  17. 28
      internal/hmyapi/apiv2/public_account.go
  18. 47
      internal/hmyapi/apiv2/transactionpool.go
  19. 14
      internal/hmyapi/backend.go
  20. 79
      internal/params/config.go
  21. 44
      internal/params/config_test.go
  22. 24
      node/node.go
  23. 1
      node/service_setup.go
  24. 3
      p2p/host/hostv2/hostv2.go
  25. 4
      staking/types/delegation.go
  26. 2
      staking/types/transaction.go
  27. 14
      staking/types/transaction_test.go
  28. 30
      test/chain/main.go

@ -1,214 +0,0 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package accounts
import (
"reflect"
"sort"
"sync"
"github.com/ethereum/go-ethereum/event"
)
// Config contains the settings of the global account manager.
//
// TODO(rjl493456442, karalabe, holiman): Get rid of this when account management
// is removed in favor of Clef.
type Config struct {
InsecureUnlockAllowed bool // Whether account unlocking in insecure environment is allowed
}
// Manager is an overarching account manager that can communicate with various
// backends for signing transactions.
type Manager struct {
config *Config // Global account manager configurations
backends map[reflect.Type][]Backend // Index of backends currently registered
updaters []event.Subscription // Wallet update subscriptions for all backends
updates chan WalletEvent // Subscription sink for backend wallet changes
wallets []Wallet // Cache of all wallets from all registered backends
feed event.Feed // Wallet feed notifying of arrivals/departures
quit chan chan error
lock sync.RWMutex
}
// NewManager creates a generic account manager to sign transaction via various
// supported backends.
func NewManager(config *Config, backends ...Backend) *Manager {
// Retrieve the initial list of wallets from the backends and sort by URL
var wallets []Wallet
for _, backend := range backends {
wallets = merge(wallets, backend.Wallets()...)
}
// Subscribe to wallet notifications from all backends
updates := make(chan WalletEvent, 4*len(backends))
subs := make([]event.Subscription, len(backends))
for i, backend := range backends {
subs[i] = backend.Subscribe(updates)
}
// Assemble the account manager and return
am := &Manager{
config: config,
backends: make(map[reflect.Type][]Backend),
updaters: subs,
updates: updates,
wallets: wallets,
quit: make(chan chan error),
}
for _, backend := range backends {
kind := reflect.TypeOf(backend)
am.backends[kind] = append(am.backends[kind], backend)
}
go am.update()
return am
}
// Close terminates the account manager's internal notification processes.
func (am *Manager) Close() error {
errc := make(chan error)
am.quit <- errc
return <-errc
}
// Config returns the configuration of account manager.
func (am *Manager) Config() *Config {
return am.config
}
// update is the wallet event loop listening for notifications from the backends
// and updating the cache of wallets.
func (am *Manager) update() {
// Close all subscriptions when the manager terminates
defer func() {
am.lock.Lock()
for _, sub := range am.updaters {
sub.Unsubscribe()
}
am.updaters = nil
am.lock.Unlock()
}()
// Loop until termination
for {
select {
case event := <-am.updates:
// Wallet event arrived, update local cache
am.lock.Lock()
switch event.Kind {
case WalletArrived:
am.wallets = merge(am.wallets, event.Wallet)
case WalletDropped:
am.wallets = drop(am.wallets, event.Wallet)
}
am.lock.Unlock()
// Notify any listeners of the event
am.feed.Send(event)
case errc := <-am.quit:
// Manager terminating, return
errc <- nil
return
}
}
}
// Backends retrieves the backend(s) with the given type from the account manager.
func (am *Manager) Backends(kind reflect.Type) []Backend {
return am.backends[kind]
}
// Wallets returns all signer accounts registered under this account manager.
func (am *Manager) Wallets() []Wallet {
am.lock.RLock()
defer am.lock.RUnlock()
cpy := make([]Wallet, len(am.wallets))
copy(cpy, am.wallets)
return cpy
}
// Wallet retrieves the wallet associated with a particular URL.
func (am *Manager) Wallet(url string) (Wallet, error) {
am.lock.RLock()
defer am.lock.RUnlock()
parsed, err := parseURL(url)
if err != nil {
return nil, err
}
for _, wallet := range am.Wallets() {
if wallet.URL() == parsed {
return wallet, nil
}
}
return nil, ErrUnknownWallet
}
// Find attempts to locate the wallet corresponding to a specific account. Since
// accounts can be dynamically added to and removed from wallets, this method has
// a linear runtime in the number of wallets.
func (am *Manager) Find(account Account) (Wallet, error) {
am.lock.RLock()
defer am.lock.RUnlock()
for _, wallet := range am.wallets {
if wallet.Contains(account) {
return wallet, nil
}
}
return nil, ErrUnknownAccount
}
// Subscribe creates an async subscription to receive notifications when the
// manager detects the arrival or departure of a wallet from any of its backends.
func (am *Manager) Subscribe(sink chan<- WalletEvent) event.Subscription {
return am.feed.Subscribe(sink)
}
// merge is a sorted analogue of append for wallets, where the ordering of the
// origin list is preserved by inserting new wallets at the correct position.
//
// The original slice is assumed to be already sorted by URL.
func merge(slice []Wallet, wallets ...Wallet) []Wallet {
for _, wallet := range wallets {
n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 })
if n == len(slice) {
slice = append(slice, wallet)
continue
}
slice = append(slice[:n], append([]Wallet{wallet}, slice[n:]...)...)
}
return slice
}
// drop is the couterpart of merge, which looks up wallets from within the sorted
// cache and removes the ones specified.
func drop(slice []Wallet, wallets ...Wallet) []Wallet {
for _, wallet := range wallets {
n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 })
if n == len(slice) {
// Wallet not found, may happen during startup
continue
}
slice = append(slice[:n], slice[n+1:]...)
}
return slice
}

@ -169,7 +169,6 @@ func (m *Manager) SetupServiceMessageChan(
mapServiceTypeChan map[Type]chan *msg_pb.Message,
) {
for serviceType, service := range m.services {
// TODO(minhdoan): for performance, consider buffered channel.
mapServiceTypeChan[serviceType] = make(chan *msg_pb.Message)
service.SetMessageChan(mapServiceTypeChan[serviceType])
}

@ -43,7 +43,6 @@ import (
"github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/webhooks"
"github.com/pkg/errors"
gologging "github.com/whyrusleeping/go-logging"
)
// Version string variables
@ -56,33 +55,30 @@ var (
// Host
var (
myHost p2p.Host
myHost p2p.Host
initialAccounts = []*genesis.DeployAccount{}
)
func printVersion() {
_, _ = fmt.Fprintln(os.Stderr, nodeconfig.GetVersion())
fmt.Fprintln(os.Stderr, nodeconfig.GetVersion())
os.Exit(0)
}
var (
ip = flag.String("ip", "127.0.0.1", "ip of the node")
port = flag.String("port", "9000", "port of the node.")
logFolder = flag.String("log_folder", "latest", "the folder collecting the logs of this execution")
logMaxSize = flag.Int("log_max_size", 100, "the max size in megabytes of the log file before it gets rotated")
freshDB = flag.Bool("fresh_db", false, "true means the existing disk based db will be removed")
profile = flag.Bool("profile", false, "Turn on profiling (CPU, Memory).")
metricsReportURL = flag.String("metrics_report_url", "", "If set, reports metrics to this URL.")
pprof = flag.String("pprof", "", "what address and port the pprof profiling server should listen on")
versionFlag = flag.Bool("version", false, "Output version info")
onlyLogTps = flag.Bool("only_log_tps", false, "Only log TPS if true")
dnsZone = flag.String("dns_zone", "", "if given and not empty, use peers from the zone (default: use libp2p peer discovery instead)")
dnsFlag = flag.Bool("dns", true, "[deprecated] equivalent to -dns_zone t.hmny.io")
ip = flag.String("ip", "127.0.0.1", "ip of the node")
port = flag.String("port", "9000", "port of the node.")
logFolder = flag.String("log_folder", "latest", "the folder collecting the logs of this execution")
logMaxSize = flag.Int("log_max_size", 100, "the max size in megabytes of the log file before it gets rotated")
freshDB = flag.Bool("fresh_db", false, "true means the existing disk based db will be removed")
pprof = flag.String("pprof", "", "what address and port the pprof profiling server should listen on")
versionFlag = flag.Bool("version", false, "Output version info")
onlyLogTps = flag.Bool("only_log_tps", false, "Only log TPS if true")
dnsZone = flag.String("dns_zone", "", "if given and not empty, use peers from the zone (default: use libp2p peer discovery instead)")
dnsFlag = flag.Bool("dns", true, "[deprecated] equivalent to -dns_zone t.hmny.io")
//Leader needs to have a minimal number of peers to start consensus
minPeers = flag.Int("min_peers", 32, "Minimal number of Peers in shard")
// Key file to store the private key
keyFile = flag.String("key", "./.hmykey", "the p2p key file of the harmony node")
// isGenesis indicates this node is a genesis node
isGenesis = flag.Bool("is_genesis", true, "true means this node is a genesis node")
// isArchival indicates this node is an archival node that will save and archive current blockchain
isArchival = flag.Bool("is_archival", false, "false will enable cached state pruning")
// delayCommit is the commit-delay timer, used by Harmony nodes
@ -91,13 +87,8 @@ var (
nodeType = flag.String("node_type", "validator", "node type: validator, explorer")
// networkType indicates the type of the network
networkType = flag.String("network_type", "mainnet", "type of the network: mainnet, testnet, pangaea, partner, stressnet, devnet, localnet")
// syncFreq indicates sync frequency
syncFreq = flag.Int("sync_freq", 60, "unit in seconds")
// beaconSyncFreq indicates beaconchain sync frequency
beaconSyncFreq = flag.Int("beacon_sync_freq", 60, "unit in seconds")
// blockPeriod indicates the how long the leader waits to propose a new block.
blockPeriod = flag.Int("block_period", 8, "how long in second the leader waits to propose a new block.")
leaderOverride = flag.Bool("leader_override", false, "true means override the default leader role and acts as validator")
blockPeriod = flag.Int("block_period", 8, "how long in second the leader waits to propose a new block.")
// staking indicates whether the node is operating in staking mode.
stakingFlag = flag.Bool("staking", false, "whether the node should operate in staking mode")
// shardID indicates the shard ID of this node
@ -115,18 +106,11 @@ var (
// logConn logs incoming/outgoing connections
logConn = flag.Bool("log_conn", false, "log incoming/outgoing connections")
keystoreDir = flag.String("keystore", hmykey.DefaultKeyStoreDir, "The default keystore directory")
// Use a separate log file to log libp2p traces
logP2P = flag.Bool("log_p2p", false, "log libp2p debug info")
initialAccounts = []*genesis.DeployAccount{}
// logging verbosity
verbosity = flag.Int("verbosity", 5, "Logging verbosity: 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=detail (default: 5)")
// dbDir is the database directory.
dbDir = flag.String("db_dir", "", "blockchain database directory")
// Disable view change.
disableViewChange = flag.Bool("disable_view_change", false, "Do not propose view change (testing only)")
publicRPC = flag.Bool("public_rpc", false, "Enable Public RPC Access (default: false)")
dbDir = flag.String("db_dir", "", "blockchain database directory")
publicRPC = flag.Bool("public_rpc", false, "Enable Public RPC Access (default: false)")
// Bad block revert
doRevertBefore = flag.Int("do_revert_before", 0, "If the current block is less than do_revert_before, revert all blocks until (including) revert_to block")
revertTo = flag.Int("revert_to", 0, "The revert will rollback all blocks until and including block number revert_to")
@ -227,9 +211,8 @@ func findAccountsByPubKeys(config shardingconfig.Instance, pubKeys []*bls.Public
func setupLegacyNodeAccount() error {
genesisShardingConfig := shard.Schedule.InstanceForEpoch(big.NewInt(core.GenesisEpoch))
multiBLSPubKey := setupConsensusKey(nodeconfig.GetDefaultConfig())
reshardingEpoch := genesisShardingConfig.ReshardingEpoch()
if reshardingEpoch != nil && len(reshardingEpoch) > 0 {
if len(reshardingEpoch) > 0 {
for _, epoch := range reshardingEpoch {
config := shard.Schedule.InstanceForEpoch(epoch)
findAccountsByPubKeys(config, multiBLSPubKey.PublicKey)
@ -242,7 +225,11 @@ func setupLegacyNodeAccount() error {
}
if len(initialAccounts) == 0 {
fmt.Fprintf(os.Stderr, "ERROR cannot find your BLS key in the genesis/FN tables: %s\n", multiBLSPubKey.SerializeToHexStr())
fmt.Fprintf(
os.Stderr,
"ERROR cannot find your BLS key in the genesis/FN tables: %s\n",
multiBLSPubKey.SerializeToHexStr(),
)
os.Exit(100)
}
@ -258,7 +245,9 @@ func setupStakingNodeAccount() error {
if err != nil {
return errors.Wrap(err, "cannot determine shard to join")
}
if err := nodeconfig.GetDefaultConfig().ValidateConsensusKeysForSameShard(pubKey.PublicKey, shardID); err != nil {
if err := nodeconfig.GetDefaultConfig().ValidateConsensusKeysForSameShard(
pubKey.PublicKey, shardID,
); err != nil {
return err
}
for _, blsKey := range pubKey.PublicKey {
@ -480,10 +469,6 @@ func setupConsensusAndNode(nodeConfig *nodeconfig.ConfigType) *node.Node {
currentConsensus.SetCommitDelay(commitDelay)
currentConsensus.MinPeers = *minPeers
if *disableViewChange {
currentConsensus.DisableViewChangeForTestingOnly()
}
blacklist, err := setupBlacklist()
if err != nil {
utils.Logger().Warn().Msgf("Blacklist setup error: %s", err.Error())
@ -607,8 +592,6 @@ func setupViperConfig() {
viperconfig.ResetConfString(logFolder, envViper, configFileViper, "", "log_folder")
viperconfig.ResetConfInt(logMaxSize, envViper, configFileViper, "", "log_max_size")
viperconfig.ResetConfBool(freshDB, envViper, configFileViper, "", "fresh_db")
viperconfig.ResetConfBool(profile, envViper, configFileViper, "", "profile")
viperconfig.ResetConfString(metricsReportURL, envViper, configFileViper, "", "metrics_report_url")
viperconfig.ResetConfString(pprof, envViper, configFileViper, "", "pprof")
viperconfig.ResetConfBool(versionFlag, envViper, configFileViper, "", "version")
viperconfig.ResetConfBool(onlyLogTps, envViper, configFileViper, "", "only_log_tps")
@ -616,15 +599,11 @@ func setupViperConfig() {
viperconfig.ResetConfBool(dnsFlag, envViper, configFileViper, "", "dns")
viperconfig.ResetConfInt(minPeers, envViper, configFileViper, "", "min_peers")
viperconfig.ResetConfString(keyFile, envViper, configFileViper, "", "key")
viperconfig.ResetConfBool(isGenesis, envViper, configFileViper, "", "is_genesis")
viperconfig.ResetConfBool(isArchival, envViper, configFileViper, "", "is_archival")
viperconfig.ResetConfString(delayCommit, envViper, configFileViper, "", "delay_commit")
viperconfig.ResetConfString(nodeType, envViper, configFileViper, "", "node_type")
viperconfig.ResetConfString(networkType, envViper, configFileViper, "", "network_type")
viperconfig.ResetConfInt(syncFreq, envViper, configFileViper, "", "sync_freq")
viperconfig.ResetConfInt(beaconSyncFreq, envViper, configFileViper, "", "beacon_sync_freq")
viperconfig.ResetConfInt(blockPeriod, envViper, configFileViper, "", "block_period")
viperconfig.ResetConfBool(leaderOverride, envViper, configFileViper, "", "leader_override")
viperconfig.ResetConfBool(stakingFlag, envViper, configFileViper, "", "staking")
viperconfig.ResetConfInt(shardID, envViper, configFileViper, "", "shard_id")
viperconfig.ResetConfString(blsKeyFile, envViper, configFileViper, "", "blskey_file")
@ -635,10 +614,8 @@ func setupViperConfig() {
viperconfig.ResetConfInt(devnetHarmonySize, envViper, configFileViper, "", "dn_hmy_size")
viperconfig.ResetConfBool(logConn, envViper, configFileViper, "", "log_conn")
viperconfig.ResetConfString(keystoreDir, envViper, configFileViper, "", "keystore")
viperconfig.ResetConfBool(logP2P, envViper, configFileViper, "", "log_p2p")
viperconfig.ResetConfInt(verbosity, envViper, configFileViper, "", "verbosity")
viperconfig.ResetConfString(dbDir, envViper, configFileViper, "", "db_dir")
viperconfig.ResetConfBool(disableViewChange, envViper, configFileViper, "", "disable_view_change")
viperconfig.ResetConfBool(publicRPC, envViper, configFileViper, "", "public_rpc")
viperconfig.ResetConfInt(doRevertBefore, envViper, configFileViper, "", "do_revert_before")
viperconfig.ResetConfInt(revertTo, envViper, configFileViper, "", "revert_to")
@ -717,7 +694,7 @@ func main() {
err = setupLegacyNodeAccount()
}
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "cannot set up node account: %s\n", err)
fmt.Fprintf(os.Stderr, "cannot set up node account: %s\n", err)
os.Exit(1)
}
}
@ -739,7 +716,7 @@ func main() {
nodeConfig, err := createGlobalConfig()
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "ERROR cannot configure node: %s\n", err)
fmt.Fprintf(os.Stderr, "ERROR cannot configure node: %s\n", err)
os.Exit(1)
}
currentNode := setupConsensusAndNode(nodeConfig)
@ -749,23 +726,16 @@ func main() {
osSignal := make(chan os.Signal)
signal.Notify(osSignal, os.Interrupt, syscall.SIGTERM)
go func() {
for {
select {
case sig := <-osSignal:
if sig == syscall.SIGTERM || sig == os.Interrupt {
msg := "Got %s signal. Gracefully shutting down...\n"
utils.Logger().Printf(msg, sig)
fmt.Printf(msg, sig)
currentNode.ShutDown()
}
for sig := range osSignal {
if sig == syscall.SIGTERM || sig == os.Interrupt {
const msg = "Got %s signal. Gracefully shutting down...\n"
utils.Logger().Printf(msg, sig)
fmt.Printf(msg, sig)
currentNode.ShutDown()
}
}
}()
//setup state syncing and beacon syncing frequency
currentNode.SetSyncFreq(*syncFreq)
currentNode.SetBeaconSyncFreq(*beaconSyncFreq)
if nodeConfig.ShardID != shard.BeaconChainShardID &&
currentNode.NodeConfig.Role() != nodeconfig.ExplorerNode {
utils.Logger().Info().
@ -810,20 +780,6 @@ func main() {
).
Msg(startMsg)
if *logP2P {
f, err := os.OpenFile(
path.Join(*logFolder, "libp2p.log"),
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644,
)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to open libp2p.log. %v\n", err)
} else {
defer f.Close()
backend1 := gologging.NewLogBackend(f, "", 0)
gologging.SetBackend(backend1)
}
}
go currentNode.SupportSyncing()
currentNode.ServiceManagerSetup()
currentNode.RunServices()

@ -140,16 +140,6 @@ func (consensus *Consensus) SetCommitDelay(delay time.Duration) {
consensus.delayCommit = delay
}
// DisableViewChangeForTestingOnly makes the receiver not propose view
// changes when it should, e.g. leader timeout.
//
// As the name implies, this is intended for testing only,
// and should not be used on production network.
// This is also not part of the long-term consensus API and may go away later.
func (consensus *Consensus) DisableViewChangeForTestingOnly() {
consensus.disableViewChange = true
}
// BlocksSynchronized lets the main loop know that block synchronization finished
// thus the blockchain is likely to be up to date.
func (consensus *Consensus) BlocksSynchronized() {

@ -158,11 +158,11 @@ func (e *GenesisMismatchError) Error() string {
// db has genesis | from DB | genesis (if compatible)
//
// The stored chain configuration will be updated if it is compatible (i.e. does not
// specify a fork block below the local head block). In case of a conflict, the
// error is a *params.ConfigCompatError and the new, unwritten config is returned.
//
// specify a fork block below the local head block)
// The returned chain configuration is never nil.
func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
func SetupGenesisBlock(
db ethdb.Database, genesis *Genesis,
) (*params.ChainConfig, common.Hash, error) {
if genesis != nil && genesis.Config == nil {
return params.AllProtocolChanges, common.Hash{}, errGenesisNoConfig
}
@ -196,24 +196,12 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
rawdb.WriteChainConfig(db, stored, newcfg)
return newcfg, stored, nil
}
// Special case: don't change the existing config of a non-mainnet chain if no new
// config is supplied. These chains would get AllProtocolChanges (and a compat error)
// if we just continued here.
// TODO: take use of genesis hash
//if genesis == nil && stored != params.MainnetGenesisHash {
// return storedcfg, stored, nil
//}
// Check config compatibility and write the config. Compatibility errors
// are returned to the caller unless we're already at block zero.
height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
if height == nil {
return newcfg, stored, fmt.Errorf("missing block number for head header hash")
}
compatErr := storedcfg.CheckCompatible(newcfg, *height)
if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
return newcfg, stored, compatErr
}
rawdb.WriteChainConfig(db, stored, newcfg)
return newcfg, stored, nil
}
@ -222,11 +210,6 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
switch {
case g != nil:
return g.Config
// TODO: take use of genesis hash
//case ghash == params.MainnetGenesisHash:
// return params.MainnetChainConfig
//case ghash == params.TestnetGenesisHash:
// return params.TestnetChainConfig
default:
return params.AllProtocolChanges
}

@ -98,7 +98,7 @@ func ReadTransaction(db DatabaseReader, hash common.Hash) (*types.Transaction, c
return nil, common.Hash{}, 0, 0
}
tx := body.TransactionAt(int(txIndex))
if tx == nil || bytes.Compare(hash.Bytes(), tx.Hash().Bytes()) != 0 {
if tx == nil || !bytes.Equal(hash.Bytes(), tx.Hash().Bytes()) {
utils.Logger().Error().
Uint64("number", blockNumber).
Str("hash", blockHash.Hex()).
@ -128,7 +128,7 @@ func ReadStakingTransaction(db DatabaseReader, hash common.Hash) (*staking.Staki
return nil, common.Hash{}, 0, 0
}
tx := body.StakingTransactionAt(int(txIndex))
if tx == nil || bytes.Compare(hash.Bytes(), tx.Hash().Bytes()) != 0 {
if tx == nil || !bytes.Equal(hash.Bytes(), tx.Hash().Bytes()) {
utils.Logger().Error().
Uint64("number", blockNumber).
Str("hash", blockHash.Hex()).

@ -29,67 +29,46 @@ import (
var (
// databaseVerisionKey tracks the current database version.
databaseVerisionKey = []byte("DatabaseVersion")
// headHeaderKey tracks the latest know header's hash.
headHeaderKey = []byte("LastHeader")
// headBlockKey tracks the latest know full block's hash.
headBlockKey = []byte("LastBlock")
// headFastBlockKey tracks the latest known incomplete block's hash duirng fast sync.
headFastBlockKey = []byte("LastFast")
// Data item prefixes (use single byte to avoid mixing data types, avoid `i`, used for indexes).
headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header
headerTDSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + headerTDSuffix -> td
headerHashSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash
headerNumberPrefix = []byte("H") // headerNumberPrefix + hash -> num (uint64 big endian)
blockBodyPrefix = []byte("b") // blockBodyPrefix + num (uint64 big endian) + hash -> block body
blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts
txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata
cxLookupPrefix = []byte("cx") // cxLookupPrefix + hash -> cxReceipt lookup metadata
bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits
shardStatePrefix = []byte("ss") // shardStatePrefix + num (uint64 big endian) + hash -> shardState
lastCommitsKey = []byte("LastCommits")
pendingCrosslinkKey = []byte("pendingCL") // prefix for shard last pending crosslink
pendingSlashingKey = []byte("pendingSC") // prefix for shard last pending slashing record
preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage
configPrefix = []byte("ethereum-config-") // config prefix for the db
shardLastCrosslinkPrefix = []byte("lcl") // prefix for shard last crosslink
crosslinkPrefix = []byte("cl") // prefix for crosslink
delegatorValidatorListPrefix = []byte("dvl") // prefix for delegator's validator list
headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header
headerTDSuffix = []byte("t") // headerPrefix + num (uint64 big endian) + hash + headerTDSuffix -> td
headerHashSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash
headerNumberPrefix = []byte("H") // headerNumberPrefix + hash -> num (uint64 big endian)
blockBodyPrefix = []byte("b") // blockBodyPrefix + num (uint64 big endian) + hash -> block body
blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts
txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata
cxLookupPrefix = []byte("cx") // cxLookupPrefix + hash -> cxReceipt lookup metadata
bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits
shardStatePrefix = []byte("ss") // shardStatePrefix + num (uint64 big endian) + hash -> shardState
lastCommitsKey = []byte("LastCommits")
pendingCrosslinkKey = []byte("pendingCL") // prefix for shard last pending crosslink
pendingSlashingKey = []byte("pendingSC") // prefix for shard last pending slashing record
preimagePrefix = []byte("secure-key-") // preimagePrefix + hash -> preimage
configPrefix = []byte("ethereum-config-") // config prefix for the db
crosslinkPrefix = []byte("cl") // prefix for crosslink
delegatorValidatorListPrefix = []byte("dvl") // prefix for delegator's validator list
// TODO: shorten the key prefix so we don't waste db space
cxReceiptPrefix = []byte("cxReceipt") // prefix for cross shard transaction receipt
cxReceiptHashPrefix = []byte("cxReceiptHash") // prefix for cross shard transaction receipt hash
cxReceiptSpentPrefix = []byte("cxReceiptSpent") // prefix for indicator of unspent of cxReceiptsProof
cxReceiptUnspentCheckpointPrefix = []byte("cxReceiptUnspentCheckpoint") // prefix for cxReceiptsProof unspent checkpoint
validatorPrefix = []byte("validator") // prefix for staking validator information
cxReceiptPrefix = []byte("cxReceipt") // prefix for cross shard transaction receipt
cxReceiptSpentPrefix = []byte("cxReceiptSpent") // prefix for indicator of unspent of cxReceiptsProof
validatorSnapshotPrefix = []byte("validator-snapshot") // prefix for staking validator's snapshot information
validatorStatsPrefix = []byte("validator-stats") // prefix for staking validator's stats information
validatorListKey = []byte("validator-list") // key for all validators list
electedValidatorListKey = []byte("elected-validator-list") // key for elected validators list
// epochBlockNumberPrefix + epoch (big.Int.Bytes())
// -> epoch block number (big.Int.Bytes())
epochBlockNumberPrefix = []byte("harmony-epoch-block-number")
// epochVrfBlockNumbersPrefix + epoch (big.Int.Bytes())
epochVrfBlockNumbersPrefix = []byte("epoch-vrf-block-numbers")
// epochVdfBlockNumberPrefix + epoch (big.Int.Bytes())
epochVdfBlockNumberPrefix = []byte("epoch-vdf-block-number")
// Chain index prefixes (use `i` + single byte to avoid mixing data types).
BloomBitsIndexPrefix = []byte("iB") // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress
BloomBitsIndexPrefix = []byte("iB") // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress
preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil)
preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil)
currentRewardGivenOutPrefix = []byte("blk-rwd-")

@ -65,7 +65,6 @@ require (
github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965
github.com/uber/jaeger-client-go v2.20.1+incompatible // indirect
github.com/uber/jaeger-lib v2.2.0+incompatible // indirect
github.com/whyrusleeping/go-logging v0.0.1
go.uber.org/zap v1.14.1 // indirect
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59
golang.org/x/lint v0.0.0-20200302205851-738671d3881b

@ -12,7 +12,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
"github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/api/proto"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus/quorum"
@ -119,11 +118,6 @@ func (b *APIBackend) CurrentBlock() *types.Block {
return types.NewBlockWithHeader(b.hmy.blockchain.CurrentHeader())
}
// AccountManager ...
func (b *APIBackend) AccountManager() *accounts.Manager {
return b.hmy.accountManager
}
// GetReceipts ...
func (b *APIBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
return b.hmy.blockchain.GetReceiptsByHash(hash), nil

@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/core/bloombits"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/params"
@ -18,14 +17,13 @@ import (
// Harmony implements the Harmony full node service.
type Harmony struct {
// Channel for shutting down the service
shutdownChan chan bool // Channel for shutting down the Harmony
bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
blockchain *core.BlockChain
beaconchain *core.BlockChain
txPool *core.TxPool
cxPool *core.CxPool
accountManager *accounts.Manager
eventMux *event.TypeMux
shutdownChan chan bool // Channel for shutting down the Harmony
bloomRequests chan chan *bloombits.Retrieval // Channel receiving bloom data retrieval requests
blockchain *core.BlockChain
beaconchain *core.BlockChain
txPool *core.TxPool
cxPool *core.CxPool
eventMux *event.TypeMux
// DB interfaces
chainDb ethdb.Database // Block chain database
bloomIndexer *core.ChainIndexer // Bloom indexer operating during block imports
@ -44,7 +42,6 @@ type NodeAPI interface {
AddPendingTransaction(newTx *types.Transaction) error
Blockchain() *core.BlockChain
Beaconchain() *core.BlockChain
AccountManager() *accounts.Manager
GetBalanceOfAddress(address common.Address) (*big.Int, error)
GetNonceOfAddress(address common.Address) uint64
GetTransactionsHistory(address, txType, order string) ([]common.Hash, error)
@ -63,19 +60,18 @@ func New(
) (*Harmony, error) {
chainDb := nodeAPI.Blockchain().ChainDB()
hmy := &Harmony{
shutdownChan: make(chan bool),
bloomRequests: make(chan chan *bloombits.Retrieval),
blockchain: nodeAPI.Blockchain(),
beaconchain: nodeAPI.Beaconchain(),
txPool: txPool,
cxPool: cxPool,
accountManager: nodeAPI.AccountManager(),
eventMux: eventMux,
chainDb: chainDb,
bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
nodeAPI: nodeAPI,
networkID: 1, // TODO(ricl): this should be from config
shardID: shardID,
shutdownChan: make(chan bool),
bloomRequests: make(chan chan *bloombits.Retrieval),
blockchain: nodeAPI.Blockchain(),
beaconchain: nodeAPI.Beaconchain(),
txPool: txPool,
cxPool: cxPool,
eventMux: eventMux,
chainDb: chainDb,
bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms),
nodeAPI: nodeAPI,
networkID: 1, // TODO(ricl): this should be from config
shardID: shardID,
}
hmy.APIBackend = &APIBackend{hmy: hmy,
TotalStakingCache: struct {

@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
"github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/core"
@ -28,19 +27,15 @@ import (
// * hmy/api_backend.go
type Backend interface {
NetVersion() uint64
// Downloader() *downloader.Downloader
ProtocolVersion() int
// SuggestPrice(ctx context.Context) (*big.Int, error)
ChainDb() ethdb.Database
EventMux() *event.TypeMux
AccountManager() *accounts.Manager
// ExtRPCEnabled() bool
RPCGasCap() *big.Int // global gas cap for hmy_call over rpc: DoS protection
HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*block.Header, error)
BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error)
StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.DB, *block.Header, error)
StateAndHeaderByNumber(
ctx context.Context, blockNr rpc.BlockNumber,
) (*state.DB, *block.Header, error)
GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)

@ -1,70 +0,0 @@
package apiv1
import (
"context"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/hmy"
"github.com/harmony-one/harmony/internal/utils"
)
// PrivateAccountAPI provides an API to access accounts managed by this node.
// It offers methods to create, (un)lock en list accounts. Some methods accept
// passwords and are therefore considered private by default.
type PrivateAccountAPI struct {
am *accounts.Manager
nonceLock *AddrLocker
b *hmy.APIBackend
}
// NewAccount will create a new account and returns the address for the new account.
func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) {
// TODO: port
return common.Address{}, nil
}
// SendTransaction will create a transaction from the given arguments and
// tries to sign it with the key associated with args.To. If the given passwd isn't
// able to decrypt the key it fails.
func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) {
if args.Nonce == nil {
// Hold the addresse's mutex around signing to prevent concurrent assignment of
// the same nonce to multiple accounts.
s.nonceLock.LockAddr(args.From)
defer s.nonceLock.UnlockAddr(args.From)
}
signed, err := s.signTransaction(ctx, &args, passwd)
if err != nil {
utils.Logger().Warn().
Str("from", args.From.Hex()).
Str("to", args.To.Hex()).
Uint64("value", args.Value.ToInt().Uint64()).
AnErr("err", err).
Msg("Failed transaction send attempt")
return common.Hash{}, err
}
return SubmitTransaction(ctx, s.b, signed)
}
// signTransaction sets defaults and signs the given transaction
// NOTE: the caller needs to ensure that the nonceLock is held, if applicable,
// and release it after the transaction has been submitted to the tx pool
func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *SendTxArgs, passwd string) (*types.Transaction, error) {
// Look up the wallet containing the requested signer
account := accounts.Account{Address: args.From}
wallet, err := s.am.Find(account)
if err != nil {
return nil, err
}
// Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, s.b); err != nil {
return nil, err
}
// Assemble the transaction and sign with the wallet
tx := args.toTransaction()
return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID)
}

@ -1,28 +0,0 @@
package apiv1
import (
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/accounts"
)
// PublicAccountAPI provides an API to access accounts managed by this node.
// It offers only methods that can retrieve accounts.
type PublicAccountAPI struct {
am *accounts.Manager
}
// NewPublicAccountAPI creates a new PublicAccountAPI.
func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI {
return &PublicAccountAPI{am: am}
}
// Accounts returns the collection of accounts this node manages
func (s *PublicAccountAPI) Accounts() []common.Address {
addresses := make([]common.Address, 0) // return [] instead of nil if empty
for _, wallet := range s.am.Wallets() {
for _, account := range wallet.Accounts() {
addresses = append(addresses, account.Address)
}
}
return addresses
}

@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/rawdb"
"github.com/harmony-one/harmony/core/types"
@ -173,38 +172,6 @@ func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, addr
return (*hexutil.Uint64)(&nonce), state.Error()
}
// SendTransaction creates a transaction for the given argument, sign it and submit it to the
// transaction pool.
func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) {
// Look up the wallet containing the requested signer
account := accounts.Account{Address: args.From}
wallet, err := s.b.AccountManager().Find(account)
if err != nil {
return common.Hash{}, err
}
if args.Nonce == nil {
// Hold the addresse's mutex around signing to prevent concurrent assignment of
// the same nonce to multiple accounts.
s.nonceLock.LockAddr(args.From)
defer s.nonceLock.UnlockAddr(args.From)
}
// Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, s.b); err != nil {
return common.Hash{}, err
}
// Assemble the transaction and sign with the wallet
tx := args.toTransaction()
signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID)
if err != nil {
return common.Hash{}, err
}
return SubmitTransaction(ctx, s.b, signed)
}
// SendRawStakingTransaction will add the signed transaction to the transaction pool.
// The sender is responsible for signing the transaction and using the correct nonce.
func (s *PublicTransactionPoolAPI) SendRawStakingTransaction(
@ -229,7 +196,9 @@ func (s *PublicTransactionPoolAPI) SendRawStakingTransaction(
// SendRawTransaction will add the signed transaction to the transaction pool.
// The sender is responsible for signing the transaction and using the correct nonce.
func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) {
func (s *PublicTransactionPoolAPI) SendRawTransaction(
ctx context.Context, encodedTx hexutil.Bytes,
) (common.Hash, error) {
if len(encodedTx) >= types.MaxEncodedPoolTransactionSize {
err := errors.Wrapf(core.ErrOversizedData, "encoded tx size: %d", len(encodedTx))
return common.Hash{}, err

@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
"github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/core"
@ -27,50 +26,38 @@ import (
// implementations:
// * hmy/api_backend.go
type Backend interface {
// NOTE(ricl): this is not in ETH Backend inteface. They put it directly in eth object.
NetVersion() uint64
// General Ethereum API
// Downloader() *downloader.Downloader
ProtocolVersion() int
// SuggestPrice(ctx context.Context) (*big.Int, error)
ChainDb() ethdb.Database
EventMux() *event.TypeMux
AccountManager() *accounts.Manager
// ExtRPCEnabled() bool
RPCGasCap() *big.Int // global gas cap for hmy_call over rpc: DoS protection
// BlockChain API
// SetHead(number uint64)
HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*block.Header, error)
BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error)
StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.DB, *block.Header, error)
StateAndHeaderByNumber(
ctx context.Context, blockNr rpc.BlockNumber,
) (*state.DB, *block.Header, error)
GetBlock(ctx context.Context, blockHash common.Hash) (*types.Block, error)
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
// GetTd(blockHash common.Hash) *big.Int
GetEVM(ctx context.Context, msg core.Message, state *state.DB, header *block.Header) (*vm.EVM, func() error, error)
GetEVM(
ctx context.Context, msg core.Message,
state *state.DB, header *block.Header,
) (*vm.EVM, func() error, error)
SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription
// TxPool API
SendTx(ctx context.Context, signedTx *types.Transaction) error
// GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
GetPoolTransactions() (types.PoolTransactions, error)
GetPoolTransaction(txHash common.Hash) types.PoolTransaction
GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error)
// Stats() (pending int, queued int)
// TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions)
SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
ChainConfig() *params.ChainConfig
CurrentBlock() *types.Block
// Get balance
GetBalance(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*big.Int, error)
// Get validators for a particular epoch
GetBalance(
ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*big.Int, error)
GetValidators(epoch *big.Int) (*shard.Committee, error)
GetShardID() uint32
// Get transactions history for an address
GetTransactionsHistory(address, txType, order string) ([]common.Hash, error)
// Get staking transactions history for an address
GetStakingTransactionsHistory(address, txType, order string) ([]common.Hash, error)
// retrieve the blockHash using txID and add blockHash to CxPool for resending
ResendCx(ctx context.Context, txID common.Hash) (uint64, bool)
IsLeader() bool
SendStakingTx(ctx context.Context, newStakingTx *staking.StakingTransaction) error

@ -1,70 +0,0 @@
package apiv2
import (
"context"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/hmy"
"github.com/harmony-one/harmony/internal/utils"
)
// PrivateAccountAPI provides an API to access accounts managed by this node.
// It offers methods to create, (un)lock en list accounts. Some methods accept
// passwords and are therefore considered private by default.
type PrivateAccountAPI struct {
am *accounts.Manager
nonceLock *AddrLocker
b *hmy.APIBackend
}
// NewAccount will create a new account and returns the address for the new account.
func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) {
// TODO: port
return common.Address{}, nil
}
// SendTransaction will create a transaction from the given arguments and
// tries to sign it with the key associated with args.To. If the given passwd isn't
// able to decrypt the key it fails.
func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) {
if args.Nonce == nil {
// Hold the addresse's mutex around signing to prevent concurrent assignment of
// the same nonce to multiple accounts.
s.nonceLock.LockAddr(args.From)
defer s.nonceLock.UnlockAddr(args.From)
}
signed, err := s.signTransaction(ctx, &args, passwd)
if err != nil {
utils.Logger().Warn().
Str("from", args.From.Hex()).
Str("to", args.To.Hex()).
Uint64("value", args.Value.ToInt().Uint64()).
AnErr("err", err).
Msg("Failed transaction send attempt")
return common.Hash{}, err
}
return SubmitTransaction(ctx, s.b, signed)
}
// signTransaction sets defaults and signs the given transaction
// NOTE: the caller needs to ensure that the nonceLock is held, if applicable,
// and release it after the transaction has been submitted to the tx pool
func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args *SendTxArgs, passwd string) (*types.Transaction, error) {
// Look up the wallet containing the requested signer
account := accounts.Account{Address: args.From}
wallet, err := s.am.Find(account)
if err != nil {
return nil, err
}
// Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, s.b); err != nil {
return nil, err
}
// Assemble the transaction and sign with the wallet
tx := args.toTransaction()
return wallet.SignTxWithPassphrase(account, passwd, tx, s.b.ChainConfig().ChainID)
}

@ -1,28 +0,0 @@
package apiv2
import (
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/accounts"
)
// PublicAccountAPI provides an API to access accounts managed by this node.
// It offers only methods that can retrieve accounts.
type PublicAccountAPI struct {
am *accounts.Manager
}
// NewPublicAccountAPI creates a new PublicAccountAPI.
func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI {
return &PublicAccountAPI{am: am}
}
// Accounts returns the collection of accounts this node manages
func (s *PublicAccountAPI) Accounts() []common.Address {
addresses := make([]common.Address, 0) // return [] instead of nil if empty
for _, wallet := range s.am.Wallets() {
for _, account := range wallet.Accounts() {
addresses = append(addresses, account.Address)
}
}
return addresses
}

@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/rawdb"
"github.com/harmony-one/harmony/core/types"
@ -204,7 +203,9 @@ func (s *PublicTransactionPoolAPI) GetStakingTransactionByHash(ctx context.Conte
// GetTransactionCount returns the number of transactions the given address has sent from genesis to the input block number
// NOTE: unlike other txn apis where staking vs. regular txns are separate,
// the transaction count here includes the count of both regular and staking txns
func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, addr string, blockNr uint64) (uint64, error) {
func (s *PublicTransactionPoolAPI) GetTransactionCount(
ctx context.Context, addr string, blockNr uint64,
) (uint64, error) {
address := internal_common.ParseAddr(addr)
// Ask transaction pool for the nonce which includes pending transactions
if rpc.BlockNumber(blockNr) == rpc.PendingBlockNumber {
@ -223,38 +224,6 @@ func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, addr
return nonce, state.Error()
}
// SendTransaction creates a transaction for the given argument, sign it and submit it to the
// transaction pool.
func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) {
// Look up the wallet containing the requested signer
account := accounts.Account{Address: args.From}
wallet, err := s.b.AccountManager().Find(account)
if err != nil {
return common.Hash{}, err
}
if args.Nonce == nil {
// Hold the addresse's mutex around signing to prevent concurrent assignment of
// the same nonce to multiple accounts.
s.nonceLock.LockAddr(args.From)
defer s.nonceLock.UnlockAddr(args.From)
}
// Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, s.b); err != nil {
return common.Hash{}, err
}
// Assemble the transaction and sign with the wallet
tx := args.toTransaction()
signed, err := wallet.SignTx(account, tx, s.b.ChainConfig().ChainID)
if err != nil {
return common.Hash{}, err
}
return SubmitTransaction(ctx, s.b, signed)
}
// SendRawStakingTransaction will add the signed transaction to the transaction pool.
// The sender is responsible for signing the transaction and using the correct nonce.
func (s *PublicTransactionPoolAPI) SendRawStakingTransaction(
@ -398,11 +367,6 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, err
return nil, err
}
managedAccounts := make(map[common.Address]struct{})
for _, wallet := range s.b.AccountManager().Wallets() {
for _, account := range wallet.Accounts() {
managedAccounts[account.Address] = struct{}{}
}
}
transactions := make([]*RPCTransaction, 0, len(pending))
for _, tx := range pending {
var signer types.Signer = types.HomesteadSigner{}
@ -431,11 +395,6 @@ func (s *PublicTransactionPoolAPI) PendingStakingTransactions() ([]*RPCStakingTr
return nil, err
}
managedAccounts := make(map[common.Address]struct{})
for _, wallet := range s.b.AccountManager().Wallets() {
for _, account := range wallet.Accounts() {
managedAccounts[account.Address] = struct{}{}
}
}
transactions := make([]*RPCStakingTransaction, 0, len(pending))
for _, tx := range pending {
var signer types.Signer = types.HomesteadSigner{}

@ -8,7 +8,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/rpc"
"github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/core"
@ -34,7 +33,6 @@ type Backend interface {
ProtocolVersion() int
ChainDb() ethdb.Database
EventMux() *event.TypeMux
AccountManager() *accounts.Manager
RPCGasCap() *big.Int // global gas cap for hmy_call over rpc: DoS protection
HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*block.Header, error)
BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error)
@ -112,12 +110,6 @@ func GetAPIs(b Backend) []rpc.API {
Service: apiv1.NewPublicTransactionPoolAPI(b, nonceLock),
Public: true,
},
{
Namespace: "hmy",
Version: "1.0",
Service: apiv1.NewPublicAccountAPI(b.AccountManager()),
Public: true,
},
{
Namespace: "hmy",
Version: "1.0",
@ -142,12 +134,6 @@ func GetAPIs(b Backend) []rpc.API {
Service: apiv2.NewPublicTransactionPoolAPI(b, nonceLockV2),
Public: true,
},
{
Namespace: "hmyv2",
Version: "1.0",
Service: apiv2.NewPublicAccountAPI(b.AccountManager()),
Public: true,
},
{
Namespace: "hmyv2",
Version: "1.0",

@ -252,44 +252,6 @@ func (c *ChainConfig) GasTable(epoch *big.Int) GasTable {
}
}
// CheckCompatible checks whether scheduled fork transitions have been imported
// with a mismatching chain configuration.
func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
bhead := new(big.Int).SetUint64(height)
// Iterate checkCompatible to find the lowest conflict.
var lasterr *ConfigCompatError
for {
err := c.checkCompatible(newcfg, bhead)
if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
break
}
lasterr = err
bhead.SetUint64(err.RewindTo)
}
return lasterr
}
func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
// TODO: check compatibility and reversion based on epochs.
//if isForkIncompatible(c.EIP155Epoch, newcfg.EIP155Epoch, head) {
// return newCompatError("EIP155 fork block", c.EIP155Epoch, newcfg.EIP155Epoch)
//}
//if isForkIncompatible(c.CrossLinkEpoch, newcfg.CrossLinkEpoch, head) {
// return newCompatError("CrossLink fork block", c.CrossLinkEpoch, newcfg.CrossLinkEpoch)
//}
//if isForkIncompatible(c.S3Epoch, newcfg.S3Epoch, head) {
// return newCompatError("S3 fork block", c.S3Epoch, newcfg.S3Epoch)
//}
return nil
}
// isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
// epoch s2 because head is already past the fork.
func isForkIncompatible(s1, s2, epoch *big.Int) bool {
return (isForked(s1, epoch) || isForked(s2, epoch)) && !configNumEqual(s1, s2)
}
// isForked returns whether a fork scheduled at epoch s is active at the given head epoch.
func isForked(s, epoch *big.Int) bool {
if s == nil || epoch == nil {
@ -298,47 +260,6 @@ func isForked(s, epoch *big.Int) bool {
return s.Cmp(epoch) <= 0
}
func configNumEqual(x, y *big.Int) bool {
if x == nil {
return y == nil
}
if y == nil {
return x == nil
}
return x.Cmp(y) == 0
}
// ConfigCompatError is raised if the locally-stored blockchain is initialised with a
// ChainConfig that would alter the past.
type ConfigCompatError struct {
What string
// block numbers of the stored and new configurations
StoredConfig, NewConfig *big.Int
// the block number to which the local chain must be rewound to correct the error
RewindTo uint64
}
func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
var rew *big.Int
switch {
case storedblock == nil:
rew = newblock
case newblock == nil || storedblock.Cmp(newblock) < 0:
rew = storedblock
default:
rew = newblock
}
err := &ConfigCompatError{what, storedblock, newblock, 0}
if rew != nil && rew.Sign() > 0 {
err.RewindTo = rew.Uint64() - 1
}
return err
}
func (err *ConfigCompatError) Error() string {
return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
}
// Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
// that do not have or require information about the block.
//

@ -1,44 +0,0 @@
package params
import (
"math/big"
"reflect"
"testing"
)
func TestCheckCompatible(t *testing.T) {
type test struct {
stored, new *ChainConfig
head uint64
wantErr *ConfigCompatError
}
tests := []test{
{stored: AllProtocolChanges, new: AllProtocolChanges, head: 0, wantErr: nil},
{stored: AllProtocolChanges, new: AllProtocolChanges, head: 100, wantErr: nil},
{
stored: &ChainConfig{EIP155Epoch: big.NewInt(10)},
new: &ChainConfig{EIP155Epoch: big.NewInt(20)},
head: 9,
wantErr: nil,
},
{
stored: &ChainConfig{S3Epoch: big.NewInt(30), EIP155Epoch: big.NewInt(10)},
new: &ChainConfig{S3Epoch: big.NewInt(25), EIP155Epoch: big.NewInt(20)},
head: 25,
wantErr: &ConfigCompatError{
What: "EIP155 fork block",
StoredConfig: big.NewInt(10),
NewConfig: big.NewInt(20),
RewindTo: 9,
},
},
}
for _, test := range tests {
err := test.stored.CheckCompatible(test.new, test.head)
if !reflect.DeepEqual(err, test.wantErr) {
// TODO: re-enable this once CheckCompatible is updated.
//t.Errorf("error mismatch:\nstored: %v\nnew: %v\nhead: %v\nerr: %v\nwant: %v", test.stored, test.new, test.head, err, test.wantErr)
}
}
}

@ -9,7 +9,6 @@ import (
"sync"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/accounts"
"github.com/harmony-one/harmony/api/client"
msg_pb "github.com/harmony-one/harmony/api/proto/message"
proto_node "github.com/harmony-one/harmony/api/proto/node"
@ -161,29 +160,21 @@ type Node struct {
// Shard group Message Receiver
shardGroupReceiver p2p.GroupReceiver
// Global group Message Receiver, communicate with beacon chain, or cross-shard TX
globalGroupReceiver p2p.GroupReceiver
// Client Message Receiver to handle light client messages
// Beacon leader needs to use this receiver to talk to new node
clientReceiver p2p.GroupReceiver
// Duplicated Ping Message Received
duplicatedPing sync.Map
// Channel to notify consensus service to really start consensus
startConsensus chan struct{}
// node configuration, including group ID, shard ID, etc
NodeConfig *nodeconfig.ConfigType
// Chain configuration.
chainConfig params.ChainConfig
// map of service type to its message channel.
serviceMessageChan map[service.Type]chan *msg_pb.Message
accountManager *accounts.Manager
isFirstTime bool // the node was started with a fresh database
// Last 1024 staking transaction error, only in memory
@ -700,26 +691,11 @@ func (node *Node) initNodeConfiguration() (service.NodeConfig, chan p2p.Peer) {
return nodeConfig, chanPeer
}
// AccountManager ...
func (node *Node) AccountManager() *accounts.Manager {
return node.accountManager
}
// ServiceManager ...
func (node *Node) ServiceManager() *service.Manager {
return node.serviceManager
}
// SetSyncFreq sets the syncing frequency in the loop
func (node *Node) SetSyncFreq(syncFreq int) {
node.syncFreq = syncFreq
}
// SetBeaconSyncFreq sets the syncing frequency in the loop
func (node *Node) SetBeaconSyncFreq(syncFreq int) {
node.beaconSyncFreq = syncFreq
}
// ShutDown gracefully shut down the node server and dump the in-memory blockchain state into DB.
func (node *Node) ShutDown() {
node.Blockchain().Stop()

@ -17,7 +17,6 @@ import (
func (node *Node) setupForValidator() {
nodeConfig, chanPeer := node.initNodeConfiguration()
// Register peer discovery service
node.serviceManager.RegisterService(
service.PeerDiscovery,

@ -154,7 +154,8 @@ func (r *GroupReceiverImpl) Receive(ctx context.Context) (
func (host *HostV2) GroupReceiver(group nodeconfig.GroupID) (
receiver p2p.GroupReceiver, err error,
) {
t, err := host.getTopic(string(group))
top := string(group)
t, err := host.getTopic(top)
if err != nil {
return nil, err
}

@ -12,8 +12,8 @@ import (
)
var (
errInsufficientBalance = errors.New("Insufficient balance to undelegate")
errInvalidAmount = errors.New("Invalid amount, must be positive")
errInsufficientBalance = errors.New("insufficient balance to undelegate")
errInvalidAmount = errors.New("invalid amount, must be positive")
)
const (

@ -15,7 +15,7 @@ import (
)
var (
errStakingTransactionTypeCastErr = errors.New("Cannot type cast to matching staking type")
errStakingTransactionTypeCastErr = errors.New("cannot type cast to matching staking type")
)
type txdata struct {

@ -150,18 +150,6 @@ func TestGasCost(t *testing.T) {
if err != nil || cost.Int64() != 21100 {
t.Errorf("staking transaction cost is incorrect %v\n", err)
}
dAddr, _ := common2.Bech32ToAddress(testAccount)
vAddr, _ := common2.Bech32ToAddress(testAccount)
delegateTx1, err := NewStakingTransaction(0, 21000, big.NewInt(1), func() (Directive, interface{}) {
return DirectiveCreateValidator, Delegate{
DelegatorAddress: dAddr,
ValidatorAddress: vAddr,
Amount: big.NewInt(100),
}
})
if _, err = delegateTx1.Cost(); err == nil {
t.Error("expected", errStakingTransactionTypeCastErr, "got", nil)
}
}
func TestNonce(t *testing.T) {
@ -183,7 +171,7 @@ func TestData(t *testing.T) {
if err != nil {
t.Errorf("could not rlp encode staking tx %v\n", err)
}
if bytes.Compare(stakingTx.Data(), encoded) != 0 {
if !bytes.Equal(stakingTx.Data(), encoded) {
t.Error("RLPEncode and Data does not match \n")
}
if _, err = RLPDecodeStakeMsg(encoded, DirectiveCreateValidator); err != nil {

@ -21,9 +21,7 @@ import (
)
const (
//StakingContractBinary is binary for staking contract.
StakingContractBinary = "0x608060405234801561001057600080fd5b506103f7806100206000396000f3fe608060405260043610610067576000357c01000000000000000000000000000000000000000000000000000000009004806317437a2c1461006c5780632e1a7d4d146100975780638da5cb5b146100e6578063b69ef8a81461013d578063d0e30db014610168575b600080fd5b34801561007857600080fd5b50610081610186565b6040518082815260200191505060405180910390f35b3480156100a357600080fd5b506100d0600480360360208110156100ba57600080fd5b81019080803590602001909291905050506101a5565b6040518082815260200191505060405180910390f35b3480156100f257600080fd5b506100fb6102cd565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561014957600080fd5b506101526102f3565b6040518082815260200191505060405180910390f35b610170610339565b6040518082815260200191505060405180910390f35b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115156102c757816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015610280573d6000803e3d6000fd5b506000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506102c8565b5b919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905090565b6000346000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055506000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490509056fea165627a7a723058204acf95662eb95006df1e0b8ba32316211039c7872bc6eb99d12689c1624143d80029"
//FaucetContractBinary is binary for faucet contract.
// FaucetContractBinary is binary for faucet contract.
FaucetContractBinary = "0x60806040526706f05b59d3b2000060015560028054600160a060020a031916331790556101aa806100316000396000f3fe608060405260043610610045577c0100000000000000000000000000000000000000000000000000000000600035046327c78c42811461004a578063b69ef8a81461008c575b600080fd5b34801561005657600080fd5b5061008a6004803603602081101561006d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166100b3565b005b34801561009857600080fd5b506100a1610179565b60408051918252519081900360200190f35b60025473ffffffffffffffffffffffffffffffffffffffff1633146100d757600080fd5b600154303110156100e757600080fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526020819052604090205460ff161561011a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260208190526040808220805460ff1916600190811790915554905181156108fc0292818181858888f19350505050158015610175573d6000803e3d6000fd5b5050565b30319056fea165627a7a723058206b894c1f3badf3b26a7a2768ab8141b1e6fa1c1ddc4622f4f44a7d5041edc9350029"
)
@ -34,19 +32,14 @@ var (
FaucetAddress = crypto.PubkeyToAddress(FaucetPriKey.PublicKey)
//FaucetInitFunds initial funds in facuet contract
FaucetInitFunds = big.NewInt(8000000000000000000)
testUserKey, _ = crypto.GenerateKey()
testUserAddress = crypto.PubkeyToAddress(testUserKey.PublicKey)
chainConfig = params.TestChainConfig
blockFactory = blockfactory.ForTest
chainConfig = params.TestChainConfig
blockFactory = blockfactory.ForTest
// Test transactions
pendingTxs []*types.Transaction
newTxs []*types.Transaction
database = ethdb.NewMemDatabase()
gspec = core.Genesis{
database = ethdb.NewMemDatabase()
gspec = core.Genesis{
Config: chainConfig,
Factory: blockFactory,
Alloc: core.GenesisAlloc{FaucetAddress: {Balance: FaucetInitFunds}},
@ -59,12 +52,9 @@ var (
allRandomUserAddress []common.Address
allRandomUserKey []*ecdsa.PrivateKey
faucetContractAddress common.Address
stakeContractAddress common.Address
chain *core.BlockChain
err error
block *types.Block
state *core_state.DB
stakingtxns []*types.Transaction
)
func init() {
@ -104,11 +94,15 @@ func fundFaucetContract(chain *core.BlockChain) {
contractworker = pkgworker.New(params.TestChainConfig, chain, chain.Engine())
nonce = contractworker.GetCurrentState().GetNonce(crypto.PubkeyToAddress(FaucetPriKey.PublicKey))
dataEnc = common.FromHex(FaucetContractBinary)
ftx, _ := types.SignTx(types.NewContractCreation(nonce, 0, big.NewInt(7000000000000000000), params.TxGasContractCreation*10, nil, dataEnc), types.HomesteadSigner{}, FaucetPriKey)
ftx, _ := types.SignTx(
types.NewContractCreation(
nonce, 0, big.NewInt(7000000000000000000),
params.TxGasContractCreation*10, nil, dataEnc),
types.HomesteadSigner{}, FaucetPriKey,
)
faucetContractAddress = crypto.CreateAddress(FaucetAddress, nonce)
state := contractworker.GetCurrentState()
txs = append(txs, ftx)
//Funding the user addressed
// Funding the user addressed
for i := 1; i <= 3; i++ {
randomUserKey, _ := crypto.GenerateKey()
randomUserAddress := crypto.PubkeyToAddress(randomUserKey.PublicKey)

Loading…
Cancel
Save