github.com/rayrapetyan/go-ethereum@v1.8.21/cmd/swarm/feeds_test.go (about)

     1  // Copyright 2017 The go-ethereum Authors
     2  // This file is part of go-ethereum.
     3  //
     4  // go-ethereum is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // go-ethereum is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU General Public License
    15  // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package main
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/json"
    22  	"io/ioutil"
    23  	"os"
    24  	"testing"
    25  
    26  	"github.com/ethereum/go-ethereum/common/hexutil"
    27  	"github.com/ethereum/go-ethereum/crypto"
    28  	"github.com/ethereum/go-ethereum/log"
    29  	"github.com/ethereum/go-ethereum/swarm/api"
    30  	swarm "github.com/ethereum/go-ethereum/swarm/api/client"
    31  	swarmhttp "github.com/ethereum/go-ethereum/swarm/api/http"
    32  	"github.com/ethereum/go-ethereum/swarm/storage/feed"
    33  	"github.com/ethereum/go-ethereum/swarm/storage/feed/lookup"
    34  	"github.com/ethereum/go-ethereum/swarm/testutil"
    35  )
    36  
    37  func TestCLIFeedUpdate(t *testing.T) {
    38  	srv := swarmhttp.NewTestSwarmServer(t, func(api *api.API) swarmhttp.TestServer {
    39  		return swarmhttp.NewServer(api, "")
    40  	}, nil)
    41  	log.Info("starting a test swarm server")
    42  	defer srv.Close()
    43  
    44  	// create a private key file for signing
    45  	privkeyHex := "0000000000000000000000000000000000000000000000000000000000001979"
    46  	privKey, _ := crypto.HexToECDSA(privkeyHex)
    47  	address := crypto.PubkeyToAddress(privKey.PublicKey)
    48  
    49  	pkFileName := testutil.TempFileWithContent(t, privkeyHex)
    50  	defer os.Remove(pkFileName)
    51  
    52  	// compose a topic. We'll be doing quotes about Miguel de Cervantes
    53  	var topic feed.Topic
    54  	subject := []byte("Miguel de Cervantes")
    55  	copy(topic[:], subject[:])
    56  	name := "quotes"
    57  
    58  	// prepare some data for the update
    59  	data := []byte("En boca cerrada no entran moscas")
    60  	hexData := hexutil.Encode(data)
    61  
    62  	flags := []string{
    63  		"--bzzapi", srv.URL,
    64  		"--bzzaccount", pkFileName,
    65  		"feed", "update",
    66  		"--topic", topic.Hex(),
    67  		"--name", name,
    68  		hexData}
    69  
    70  	// create an update and expect an exit without errors
    71  	log.Info("updating a feed with 'swarm feed update'")
    72  	cmd := runSwarm(t, flags...)
    73  	cmd.ExpectExit()
    74  
    75  	// now try to get the update using the client
    76  	client := swarm.NewClient(srv.URL)
    77  
    78  	// build the same topic as before, this time
    79  	// we use NewTopic to create a topic automatically.
    80  	topic, err := feed.NewTopic(name, subject)
    81  	if err != nil {
    82  		t.Fatal(err)
    83  	}
    84  
    85  	// Feed configures whose updates we will be looking up.
    86  	fd := feed.Feed{
    87  		Topic: topic,
    88  		User:  address,
    89  	}
    90  
    91  	// Build a query to get the latest update
    92  	query := feed.NewQueryLatest(&fd, lookup.NoClue)
    93  
    94  	// retrieve content!
    95  	reader, err := client.QueryFeed(query, "")
    96  	if err != nil {
    97  		t.Fatal(err)
    98  	}
    99  
   100  	retrieved, err := ioutil.ReadAll(reader)
   101  	if err != nil {
   102  		t.Fatal(err)
   103  	}
   104  
   105  	// check we retrieved the sent information
   106  	if !bytes.Equal(data, retrieved) {
   107  		t.Fatalf("Received %s, expected %s", retrieved, data)
   108  	}
   109  
   110  	// Now retrieve info for the next update
   111  	flags = []string{
   112  		"--bzzapi", srv.URL,
   113  		"feed", "info",
   114  		"--topic", topic.Hex(),
   115  		"--user", address.Hex(),
   116  	}
   117  
   118  	log.Info("getting feed info with 'swarm feed info'")
   119  	cmd = runSwarm(t, flags...)
   120  	_, matches := cmd.ExpectRegexp(`.*`) // regex hack to extract stdout
   121  	cmd.ExpectExit()
   122  
   123  	// verify we can deserialize the result as a valid JSON
   124  	var request feed.Request
   125  	err = json.Unmarshal([]byte(matches[0]), &request)
   126  	if err != nil {
   127  		t.Fatal(err)
   128  	}
   129  
   130  	// make sure the retrieved feed is the same
   131  	if request.Feed != fd {
   132  		t.Fatalf("Expected feed to be: %s, got %s", fd, request.Feed)
   133  	}
   134  
   135  	// test publishing a manifest
   136  	flags = []string{
   137  		"--bzzapi", srv.URL,
   138  		"--bzzaccount", pkFileName,
   139  		"feed", "create",
   140  		"--topic", topic.Hex(),
   141  	}
   142  
   143  	log.Info("Publishing manifest with 'swarm feed create'")
   144  	cmd = runSwarm(t, flags...)
   145  	_, matches = cmd.ExpectRegexp(`[a-f\d]{64}`)
   146  	cmd.ExpectExit()
   147  
   148  	manifestAddress := matches[0] // read the received feed manifest
   149  
   150  	// now attempt to lookup the latest update using a manifest instead
   151  	reader, err = client.QueryFeed(nil, manifestAddress)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  
   156  	retrieved, err = ioutil.ReadAll(reader)
   157  	if err != nil {
   158  		t.Fatal(err)
   159  	}
   160  
   161  	if !bytes.Equal(data, retrieved) {
   162  		t.Fatalf("Received %s, expected %s", retrieved, data)
   163  	}
   164  
   165  	// test publishing a manifest for a different user
   166  	flags = []string{
   167  		"--bzzapi", srv.URL,
   168  		"feed", "create",
   169  		"--topic", topic.Hex(),
   170  		"--user", "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", // different user
   171  	}
   172  
   173  	log.Info("Publishing manifest with 'swarm feed create' for a different user")
   174  	cmd = runSwarm(t, flags...)
   175  	_, matches = cmd.ExpectRegexp(`[a-f\d]{64}`)
   176  	cmd.ExpectExit()
   177  
   178  	manifestAddress = matches[0] // read the received feed manifest
   179  
   180  	// now let's try to update that user's manifest which we don't have the private key for
   181  	flags = []string{
   182  		"--bzzapi", srv.URL,
   183  		"--bzzaccount", pkFileName,
   184  		"feed", "update",
   185  		"--manifest", manifestAddress,
   186  		hexData}
   187  
   188  	// create an update and expect an error given there is a user mismatch
   189  	log.Info("updating a feed with 'swarm feed update'")
   190  	cmd = runSwarm(t, flags...)
   191  	cmd.ExpectRegexp("Fatal:.*") // best way so far to detect a failure.
   192  	cmd.ExpectExit()
   193  	if cmd.ExitStatus() == 0 {
   194  		t.Fatal("Expected nonzero exit code when updating a manifest with the wrong user. Got 0.")
   195  	}
   196  }