aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--cmd/faucet/faucet.go2
-rw-r--r--cmd/geth/accountcmd.go45
-rw-r--r--cmd/swarm/main.go8
-rw-r--r--internal/ethapi/api.go23
-rw-r--r--mobile/common.go43
-rw-r--r--mobile/ethereum.go22
-rw-r--r--p2p/discover/udp.go2
-rw-r--r--swarm/api/config.go19
-rw-r--r--swarm/api/config_test.go1
-rw-r--r--swarm/api/http/server.go1
-rw-r--r--swarm/api/manifest.go4
-rw-r--r--swarm/api/manifest_test.go33
-rw-r--r--swarm/swarm.go20
14 files changed, 186 insertions, 39 deletions
diff --git a/README.md b/README.md
index 0a6480685..7f7c54172 100644
--- a/README.md
+++ b/README.md
@@ -84,7 +84,7 @@ $ geth --testnet --fast --cache=512 console
```
The `--fast`, `--cache` flags and `console` subcommand have the exact same meaning as above and they
-are equially useful on the testnet too. Please see above for their explanations if you've skipped to
+are equally useful on the testnet too. Please see above for their explanations if you've skipped to
here.
Specifying the `--testnet` flag however will reconfigure your Geth instance a bit:
diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go
index f672433ee..c06c4365b 100644
--- a/cmd/faucet/faucet.go
+++ b/cmd/faucet/faucet.go
@@ -102,7 +102,7 @@ func main() {
if amount == 1 {
amounts[i] = strings.TrimSuffix(amounts[i], "s")
}
- // Calcualte the period for th enext tier and format it
+ // Calculate the period for the next tier and format it
period := *minutesFlag * int(math.Pow(3, float64(i)))
periods[i] = fmt.Sprintf("%d mins", period)
if period%60 == 0 {
diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go
index 1a3c63da9..5c756e66d 100644
--- a/cmd/geth/accountcmd.go
+++ b/cmd/geth/accountcmd.go
@@ -31,25 +31,40 @@ import (
var (
walletCommand = cli.Command{
- Name: "wallet",
- Usage: "Import Ethereum presale wallets",
- Action: utils.MigrateFlags(importWallet),
- Category: "ACCOUNT COMMANDS",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.KeyStoreDirFlag,
- utils.PasswordFileFlag,
- utils.LightKDFFlag,
- },
+ Name: "wallet",
+ Usage: "Manage Ethereum presale wallets",
+ ArgsUsage: "",
+ Category: "ACCOUNT COMMANDS",
Description: `
- geth wallet [options] /path/to/my/presale.wallet
+ geth wallet import /path/to/my/presale.wallet
+
+will prompt for your password and imports your ether presale account.
+It can be used non-interactively with the --password option taking a
+passwordfile as argument containing the wallet password in plaintext.`,
+ Subcommands: []cli.Command{
+ {
- will prompt for your password and imports your ether presale account.
- It can be used non-interactively with the --password option taking a
- passwordfile as argument containing the wallet password in plaintext.
+ Name: "import",
+ Usage: "Import Ethereum presale wallet",
+ ArgsUsage: "<keyFile>",
+ Action: utils.MigrateFlags(importWallet),
+ Category: "ACCOUNT COMMANDS",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.KeyStoreDirFlag,
+ utils.PasswordFileFlag,
+ utils.LightKDFFlag,
+ },
+ Description: `
+ geth wallet [options] /path/to/my/presale.wallet
- `,
+will prompt for your password and imports your ether presale account.
+It can be used non-interactively with the --password option taking a
+passwordfile as argument containing the wallet password in plaintext.`,
+ },
+ },
}
+
accountCommand = cli.Command{
Name: "account",
Usage: "Manage accounts",
diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go
index 26aa3e50f..71149c310 100644
--- a/cmd/swarm/main.go
+++ b/cmd/swarm/main.go
@@ -67,6 +67,10 @@ var (
Name: "bzzaccount",
Usage: "Swarm account key file",
}
+ SwarmListenAddrFlag = cli.StringFlag{
+ Name: "httpaddr",
+ Usage: "Swarm HTTP API listening interface",
+ }
SwarmPortFlag = cli.StringFlag{
Name: "bzzport",
Usage: "Swarm local http api port",
@@ -249,6 +253,7 @@ Cleans database of corrupted entries.
SwarmConfigPathFlag,
SwarmSwapEnabledFlag,
SwarmSyncEnabledFlag,
+ SwarmListenAddrFlag,
SwarmPortFlag,
SwarmAccountFlag,
SwarmNetworkIdFlag,
@@ -345,6 +350,9 @@ func registerBzzService(ctx *cli.Context, stack *node.Node) {
if len(bzzport) > 0 {
bzzconfig.Port = bzzport
}
+ if bzzaddr := ctx.GlobalString(SwarmListenAddrFlag.Name); bzzaddr != "" {
+ bzzconfig.ListenAddr = bzzaddr
+ }
swapEnabled := ctx.GlobalBool(SwarmSwapEnabledFlag.Name)
syncEnabled := ctx.GlobalBoolT(SwarmSyncEnabledFlag.Name)
diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go
index f9eed8797..62edc695c 100644
--- a/internal/ethapi/api.go
+++ b/internal/ethapi/api.go
@@ -24,6 +24,7 @@ import (
"fmt"
"math/big"
"strings"
+ "sync"
"time"
"github.com/ethereum/go-ethereum/accounts"
@@ -890,6 +891,12 @@ type PublicTransactionPoolAPI struct {
b Backend
}
+// nonceMutex is a global mutex for locking the nonce while a transaction
+// is being submitted. This should be used when a nonce has not been provided by the user,
+// and we get a nonce from the pools. The mutex prevents the (an identical nonce) from being
+// read again during the time that the first transaction is being signed.
+var nonceMutex sync.RWMutex
+
// NewPublicTransactionPoolAPI creates a new RPC service with methods specific for the transaction pool.
func NewPublicTransactionPoolAPI(b Backend) *PublicTransactionPoolAPI {
return &PublicTransactionPoolAPI{b}
@@ -1170,6 +1177,14 @@ func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c
// 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) {
+
+ if args.Nonce == nil {
+ // We'll need to set nonce from pool, and thus we need to lock here
+ nonceMutex.Lock()
+ defer nonceMutex.Unlock()
+
+ }
+
// Set some sanity defaults and terminate on failure
if err := args.setDefaults(ctx, s.b); err != nil {
return common.Hash{}, err
@@ -1257,6 +1272,14 @@ type SignTransactionResult struct {
// The node needs to have the private key of the account corresponding with
// the given from address and it needs to be unlocked.
func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) {
+
+ if args.Nonce == nil {
+ // We'll need to set nonce from pool, and thus we need to lock here
+ nonceMutex.Lock()
+ defer nonceMutex.Unlock()
+
+ }
+
if err := args.setDefaults(ctx, s.b); err != nil {
return nil, err
}
diff --git a/mobile/common.go b/mobile/common.go
index 779f22b4e..3090014c5 100644
--- a/mobile/common.go
+++ b/mobile/common.go
@@ -89,6 +89,18 @@ func (h *Hash) GetHex() string {
// Hashes represents a slice of hashes.
type Hashes struct{ hashes []common.Hash }
+// NewHashes creates a slice of uninitialized Hashes.
+func NewHashes(size int) *Hashes {
+ return &Hashes{
+ hashes: make([]common.Hash, size),
+ }
+}
+
+// NewHashesEmpty creates an empty slice of Hashes values.
+func NewHashesEmpty() *Hashes {
+ return NewHashes(0)
+}
+
// Size returns the number of hashes in the slice.
func (h *Hashes) Size() int {
return len(h.hashes)
@@ -102,6 +114,20 @@ func (h *Hashes) Get(index int) (hash *Hash, _ error) {
return &Hash{h.hashes[index]}, nil
}
+// Set sets the Hash at the given index in the slice.
+func (h *Hashes) Set(index int, hash *Hash) error {
+ if index < 0 || index >= len(h.hashes) {
+ return errors.New("index out of bounds")
+ }
+ h.hashes[index] = hash.hash
+ return nil
+}
+
+// Append adds a new Hash element to the end of the slice.
+func (h *Hashes) Append(hash *Hash) {
+ h.hashes = append(h.hashes, hash.hash)
+}
+
// Address represents the 20 byte address of an Ethereum account.
type Address struct {
address common.Address
@@ -164,6 +190,18 @@ func (a *Address) GetHex() string {
// Addresses represents a slice of addresses.
type Addresses struct{ addresses []common.Address }
+// NewAddresses creates a slice of uninitialized addresses.
+func NewAddresses(size int) *Addresses {
+ return &Addresses{
+ addresses: make([]common.Address, size),
+ }
+}
+
+// NewAddressesEmpty creates an empty slice of Addresses values.
+func NewAddressesEmpty() *Addresses {
+ return NewAddresses(0)
+}
+
// Size returns the number of addresses in the slice.
func (a *Addresses) Size() int {
return len(a.addresses)
@@ -185,3 +223,8 @@ func (a *Addresses) Set(index int, address *Address) error {
a.addresses[index] = address.address
return nil
}
+
+// Append adds a new address element to the end of the slice.
+func (a *Addresses) Append(address *Address) {
+ a.addresses = append(a.addresses, address.address)
+}
diff --git a/mobile/ethereum.go b/mobile/ethereum.go
index 94f707a87..30a94dc89 100644
--- a/mobile/ethereum.go
+++ b/mobile/ethereum.go
@@ -87,6 +87,18 @@ func (p *SyncProgress) GetKnownStates() int64 { return int64(p.progress.KnownS
// Topics is a set of topic lists to filter events with.
type Topics struct{ topics [][]common.Hash }
+// NewTopics creates a slice of uninitialized Topics.
+func NewTopics(size int) *Topics {
+ return &Topics{
+ topics: make([][]common.Hash, size),
+ }
+}
+
+// NewTopicsEmpty creates an empty slice of Topics values.
+func NewTopicsEmpty() *Topics {
+ return NewTopics(0)
+}
+
// Size returns the number of topic lists inside the set
func (t *Topics) Size() int {
return len(t.topics)
@@ -109,6 +121,11 @@ func (t *Topics) Set(index int, topics *Hashes) error {
return nil
}
+// Append adds a new topic list to the end of the slice.
+func (t *Topics) Append(topics *Hashes) {
+ t.topics = append(t.topics, topics.hashes)
+}
+
// FilterQuery contains options for contact log filtering.
type FilterQuery struct {
query ethereum.FilterQuery
@@ -123,3 +140,8 @@ func (fq *FilterQuery) GetFromBlock() *BigInt { return &BigInt{fq.query.FromB
func (fq *FilterQuery) GetToBlock() *BigInt { return &BigInt{fq.query.ToBlock} }
func (fq *FilterQuery) GetAddresses() *Addresses { return &Addresses{fq.query.Addresses} }
func (fq *FilterQuery) GetTopics() *Topics { return &Topics{fq.query.Topics} }
+
+func (fq *FilterQuery) SetFromBlock(fromBlock *BigInt) { fq.query.FromBlock = fromBlock.bigint }
+func (fq *FilterQuery) SetToBlock(toBlock *BigInt) { fq.query.ToBlock = toBlock.bigint }
+func (fq *FilterQuery) SetAddresses(addresses *Addresses) { fq.query.Addresses = addresses.addresses }
+func (fq *FilterQuery) SetTopics(topics *Topics) { fq.query.Topics = topics.topics }
diff --git a/p2p/discover/udp.go b/p2p/discover/udp.go
index 93545e7d5..f9eb99ee3 100644
--- a/p2p/discover/udp.go
+++ b/p2p/discover/udp.go
@@ -224,7 +224,7 @@ func ListenUDP(priv *ecdsa.PrivateKey, laddr string, natm nat.Interface, nodeDBP
if err != nil {
return nil, err
}
- log.Debug("UDP listener up", "self", tab.self)
+ log.Info("UDP listener up", "self", tab.self)
return tab, nil
}
diff --git a/swarm/api/config.go b/swarm/api/config.go
index 23a855500..647c153ed 100644
--- a/swarm/api/config.go
+++ b/swarm/api/config.go
@@ -32,7 +32,8 @@ import (
)
const (
- port = "8500"
+ DefaultHTTPListenAddr = "127.0.0.1"
+ DefaultHTTPPort = "8500"
)
var (
@@ -48,12 +49,13 @@ type Config struct {
*network.HiveParams
Swap *swap.SwapParams
*network.SyncParams
- Path string
- Port string
- PublicKey string
- BzzKey string
- EnsRoot common.Address
- NetworkId uint64
+ Path string
+ ListenAddr string
+ Port string
+ PublicKey string
+ BzzKey string
+ EnsRoot common.Address
+ NetworkId uint64
}
// config is agnostic to where private key is coming from
@@ -76,7 +78,8 @@ func NewConfig(path string, contract common.Address, prvKey *ecdsa.PrivateKey, n
HiveParams: network.NewHiveParams(dirpath),
ChunkerParams: storage.NewChunkerParams(),
StoreParams: storage.NewStoreParams(dirpath),
- Port: port,
+ ListenAddr: DefaultHTTPListenAddr,
+ Port: DefaultHTTPPort,
Path: dirpath,
Swap: swap.DefaultSwapParams(contract, prvKey),
PublicKey: pubkeyhex,
diff --git a/swarm/api/config_test.go b/swarm/api/config_test.go
index 2f40098a3..6b5cea915 100644
--- a/swarm/api/config_test.go
+++ b/swarm/api/config_test.go
@@ -80,6 +80,7 @@ var (
false
],
"Path": "TMPDIR",
+ "ListenAddr": "127.0.0.1",
"Port": "8500",
"PublicKey": "0x045f5cfd26692e48d0017d380349bcf50982488bc11b5145f3ddf88b24924299048450542d43527fbe29a5cb32f38d62755393ac002e6bfdd71b8d7ba725ecd7a3",
"BzzKey": "0xe861964402c0b78e2d44098329b8545726f215afa737d803714a4338552fcb81",
diff --git a/swarm/api/http/server.go b/swarm/api/http/server.go
index 849b9e10f..5f64f971b 100644
--- a/swarm/api/http/server.go
+++ b/swarm/api/http/server.go
@@ -69,7 +69,6 @@ func StartHttpServer(api *api.Api, config *ServerConfig) {
hdlr := c.Handler(NewServer(api))
go http.ListenAndServe(config.Addr, hdlr)
- log.Info(fmt.Sprintf("Swarm HTTP proxy started on localhost:%s", config.Addr))
}
func NewServer(api *api.Api) *Server {
diff --git a/swarm/api/manifest.go b/swarm/api/manifest.go
index dbaaf4bff..e251620a7 100644
--- a/swarm/api/manifest.go
+++ b/swarm/api/manifest.go
@@ -237,12 +237,12 @@ func (self *manifestTrie) addEntry(entry *manifestTrieEntry, quitC chan bool) {
}
b := byte(entry.Path[0])
- if (self.entries[b] == nil) || (self.entries[b].Path == entry.Path) {
+ oldentry := self.entries[b]
+ if (oldentry == nil) || (oldentry.Path == entry.Path && oldentry.ContentType != ManifestType) {
self.entries[b] = entry
return
}
- oldentry := self.entries[b]
cpl := 0
for (len(entry.Path) > cpl) && (len(oldentry.Path) > cpl) && (entry.Path[cpl] == oldentry.Path[cpl]) {
cpl++
diff --git a/swarm/api/manifest_test.go b/swarm/api/manifest_test.go
index 20b8117c6..0208848a3 100644
--- a/swarm/api/manifest_test.go
+++ b/swarm/api/manifest_test.go
@@ -18,6 +18,8 @@ package api
import (
// "encoding/json"
+ "bytes"
+ "encoding/json"
"fmt"
"io"
"strings"
@@ -78,3 +80,34 @@ func TestGetEntry(t *testing.T) {
func TestDeleteEntry(t *testing.T) {
}
+
+// TestAddFileWithManifestPath tests that adding an entry at a path which
+// already exists as a manifest just adds the entry to the manifest rather
+// than replacing the manifest with the entry
+func TestAddFileWithManifestPath(t *testing.T) {
+ // create a manifest containing "ab" and "ac"
+ manifest, _ := json.Marshal(&Manifest{
+ Entries: []ManifestEntry{
+ {Path: "ab", Hash: "ab"},
+ {Path: "ac", Hash: "ac"},
+ },
+ })
+ reader := &storage.LazyTestSectionReader{
+ SectionReader: io.NewSectionReader(bytes.NewReader(manifest), 0, int64(len(manifest))),
+ }
+ trie, err := readManifest(reader, nil, nil, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ checkEntry(t, "ab", "ab", trie)
+ checkEntry(t, "ac", "ac", trie)
+
+ // now add path "a" and check we can still get "ab" and "ac"
+ entry := &manifestTrieEntry{}
+ entry.Path = "a"
+ entry.Hash = "a"
+ trie.addEntry(entry, nil)
+ checkEntry(t, "ab", "ab", trie)
+ checkEntry(t, "ac", "ac", trie)
+ checkEntry(t, "a", "a", trie)
+}
diff --git a/swarm/swarm.go b/swarm/swarm.go
index 442e68d51..4f93a30b7 100644
--- a/swarm/swarm.go
+++ b/swarm/swarm.go
@@ -21,6 +21,7 @@ import (
"context"
"crypto/ecdsa"
"fmt"
+ "net"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
@@ -166,13 +167,13 @@ Start is called when the stack is started
* TODO: start subservices like sword, swear, swarmdns
*/
// implements the node.Service interface
-func (self *Swarm) Start(net *p2p.Server) error {
+func (self *Swarm) Start(srv *p2p.Server) error {
connectPeer := func(url string) error {
node, err := discover.ParseNode(url)
if err != nil {
return fmt.Errorf("invalid node URL: %v", err)
}
- net.AddPeer(node)
+ srv.AddPeer(node)
return nil
}
// set chequebook
@@ -189,8 +190,8 @@ func (self *Swarm) Start(net *p2p.Server) error {
log.Warn(fmt.Sprintf("Starting Swarm service"))
self.hive.Start(
- discover.PubkeyID(&net.PrivateKey.PublicKey),
- func() string { return net.ListenAddr },
+ discover.PubkeyID(&srv.PrivateKey.PublicKey),
+ func() string { return srv.ListenAddr },
connectPeer,
)
log.Info(fmt.Sprintf("Swarm network started on bzz address: %v", self.hive.Addr()))
@@ -200,17 +201,16 @@ func (self *Swarm) Start(net *p2p.Server) error {
// start swarm http proxy server
if self.config.Port != "" {
- addr := ":" + self.config.Port
+ addr := net.JoinHostPort(self.config.ListenAddr, self.config.Port)
go httpapi.StartHttpServer(self.api, &httpapi.ServerConfig{
Addr: addr,
CorsString: self.corsString,
})
- }
-
- log.Debug(fmt.Sprintf("Swarm http proxy started on port: %v", self.config.Port))
+ log.Info(fmt.Sprintf("Swarm http proxy started on %v", addr))
- if self.corsString != "" {
- log.Debug(fmt.Sprintf("Swarm http proxy started with corsdomain: %v", self.corsString))
+ if self.corsString != "" {
+ log.Debug(fmt.Sprintf("Swarm http proxy started with corsdomain: %v", self.corsString))
+ }
}
return nil