Esempio n. 1
0
func TestPeerFromReq(t *testing.T) {
	defer os.RemoveAll(testutil.InitDir(t))
	ocCred := cred.NewOcCred()
	btcConf, err := util.LoadBitcoindConf("")
	if err != nil {
		t.Fatal(err)
	}
	// TODO(ortutay): this test is flakey, as we may not have any BTC at all
	btcCreds, err := cred.GetBtcCredInRange(0, util.B2S(1000), btcConf)
	if err != nil {
		t.Fatal(err)
	}
	req := calc.NewCalcReq([]string{"1 2 +"})
	err = ocCred.SignOcReq(req)
	if err != nil {
		t.Fatal(err)
	}
	for _, bc := range *btcCreds {
		err = bc.SignOcReq(req, btcConf)
		if err != nil {
			t.Fatal(err)
		}
	}
	p, err := NewPeerFromReq(req, btcConf)
	if err != nil {
		t.Fatal(err)
	}
	if p.ID != req.ID {
		t.FailNow()
	}
}
Esempio n. 2
0
func TestBtcCredSign(t *testing.T) {
	printBitcoindExpected()
	conf, err := util.LoadBitcoindConf("")
	if err != nil {
		t.Errorf("%v", err)
	}

	ocReq := newReq()

	addr, err := getAnyBtcAddr(conf)
	if err != nil {
		t.Errorf("%v", err)
	}

	if err != nil {
		t.Errorf("%v", err)
	}
	btcCred := BtcCred{
		Addr: addr,
	}

	err = btcCred.SignOcReq(ocReq, conf)
	if err != nil {
		t.Errorf("%v", err)
	}

	ok, err := VerifyOcReqSig(ocReq, conf)
	if err != nil {
		t.Errorf("%v", err)
	}
	if !ok {
		t.Errorf("sig did not verify")
	}
}
Esempio n. 3
0
func TestGetAddr(t *testing.T) {
	defer os.RemoveAll(testutil.InitDir(t))
	btcConf, err := util.LoadBitcoindConf("")
	if err != nil {
		t.Errorf("%v", err)
	}
	req := NewPaymentAddrReq(msg.BTC)
	ps := PaymentService{BitcoindConf: btcConf}
	_, err = ps.getPaymentAddr(req)
	if err != nil {
		log.Fatal(err)
	}
}
Esempio n. 4
0
func TestAmountPaid(t *testing.T) {
	defer os.RemoveAll(testutil.InitDir(t))
	btcConf, err := util.LoadBitcoindConf("")
	if err != nil {
		t.Fatal(err)
	}
	peer := Peer{ID: msg.OcID("123id")}
	otherPeer := Peer{ID: msg.OcID("456otherid")}

	addr, err := peer.PaymentAddr(1, btcConf)
	if err != nil {
		t.Fatal(err)
	}
	otherAddr, err := otherPeer.PaymentAddr(1, btcConf)
	if err != nil {
		t.Fatal(err)
	}
	fmt.Printf("addr %v other addr %v\n", addr, otherAddr)

	// Send some BTC to ourselves.
	amt := int64(1e6)
	cmd, err := btcjson.NewSendToAddressCmd("", addr, amt)
	if err != nil {
		log.Fatal(err)
	}
	sendBtcResp, err := util.SendBtcRpc(cmd, btcConf)
	_, ok := sendBtcResp.Result.(string)
	if !ok {
		log.Fatal(sendBtcResp)
	}

	// Send some BTC to another address.
	cmd, err = btcjson.NewSendToAddressCmd("", otherAddr, 1e6)
	if err != nil {
		log.Fatal(err)
	}
	sendBtcResp, err = util.SendBtcRpc(cmd, btcConf)
	_, ok = sendBtcResp.Result.(string)
	if !ok {
		log.Fatal(sendBtcResp)
	}

	// Verify balance
	pv, err := peer.AmountPaid(0, btcConf)
	if err != nil {
		log.Fatal(err)
	}
	if pv.Amount != amt {
		t.Fatalf("%v != %v", paid, amt)
	}
}
Esempio n. 5
0
func TestBtcSignRequest(t *testing.T) {
	printBitcoindExpected()
	btcConf, err := util.LoadBitcoindConf("")
	if err != nil {
		t.Errorf(err.Error())
	}
	c, err := newClient(btcConf)
	if err != nil {
		log.Fatal(err)
	}
	err = c.BtcSignRequest(util.B2S(.08), util.B2S(.08), nil)
	if err != nil {
		log.Fatal(err)
	}
}
Esempio n. 6
0
func TestInvalidBtcSignatureFails(t *testing.T) {
	printBitcoindExpected()
	conf, err := util.LoadBitcoindConf("")
	if err != nil {
		t.Errorf("%v", err)
	}

	ocReq := newReq()

	addr, err := getAnyBtcAddr(conf)
	if err != nil {
		t.Errorf("%v", err)
	}

	if err != nil {
		t.Errorf("%v", err)
	}
	btcCred := BtcCred{
		Addr: addr,
	}

	err = btcCred.SignOcReq(ocReq, conf)
	if err != nil {
		t.Errorf("%v", err)
	}

	originalSig := ocReq.CoinSigs[0]
	ocReq.CoinSigs[0] = originalSig[0:len(originalSig)-2] + "1"
	ok, err := VerifyOcReqSig(ocReq, conf)
	if ok {
		t.Errorf("invalid sig %v verified", ocReq.CoinSigs[0])
	}
	if err == nil || err.Error() != "-5: Malformed base64 encoding" {
		t.Errorf("expected malformed base64 encoding error, but got  %v", err)
	}

	originalID := ocReq.Coins[0]
	ocReq.Coins[0] = originalID[0:len(originalID)-2] + "1"
	ok, err = VerifyOcReqSig(ocReq, conf)
	if ok {
		t.Errorf("invalid node id %v verified", ocReq.Coins[0])
	}
	if err == nil || err.Error() != "-3: Invalid address" {
		t.Errorf("expected invalid address error, but got  %v", err)
	}
}
Esempio n. 7
0
func TestPeerFromReqCoinReuse(t *testing.T) {
	defer os.RemoveAll(testutil.InitDir(t))
	ocCred1 := cred.NewOcCred()
	ocCred2 := cred.NewOcCred()
	btcConf, err := util.LoadBitcoindConf("")
	if err != nil {
		t.Fatal(err)
	}
	// TODO(ortutay): this test is flakey, as we may not have any BTC at all
	btcCreds, err := cred.GetBtcCredInRange(0, util.B2S(1000), btcConf)
	if err != nil {
		t.Fatal(err)
	}
	req1 := calc.NewCalcReq([]string{"1 2 +"})
	err = ocCred1.SignOcReq(req1)
	if err != nil {
		t.Fatal(err)
	}
	req2 := calc.NewCalcReq([]string{"1 2 +"})
	err = ocCred2.SignOcReq(req2)
	if err != nil {
		t.Fatal(err)
	}
	for _, bc := range *btcCreds {
		err = bc.SignOcReq(req1, btcConf)
		err = bc.SignOcReq(req2, btcConf)
		if err != nil {
			t.Fatal(err)
		}
	}
	p1, err := NewPeerFromReq(req1, btcConf)
	if err != nil {
		t.Fatal(err)
	}
	if p1.ID != req1.ID {
		t.FailNow()
	}
	p2, err := NewPeerFromReq(req2, btcConf)
	if err == nil || err != COIN_REUSE {
		t.Fatal("Expected COIN_REUSE error")
	}
	if p2 != nil {
		t.FailNow()
	}
}
Esempio n. 8
0
func TestGetAddr(t *testing.T) {
	defer os.RemoveAll(testutil.InitDir(t))
	btcConf, err := util.LoadBitcoindConf("")
	if err != nil {
		t.Errorf("%v", err)
	}
	p := Peer{ID: msg.OcID("123id")}
	addr1, err := p.PaymentAddr(1, btcConf)
	if err != nil {
		log.Fatal(err)
	}
	addr2, err := p.PaymentAddr(1, btcConf)
	if err != nil {
		log.Fatal(err)
	}
	if addr1 != addr2 {
		t.Fatalf("%v != %v\n", addr1, addr2)
	}
}
Esempio n. 9
0
func TestPaymentRoundTrip(t *testing.T) {
	printBitcoindExpected()
	btcConf, err := util.LoadBitcoindConf("")
	if err != nil {
		t.Errorf(err.Error())
	}

	addr := ":9443"
	services := make(map[string]Handler)
	services[calc.SERVICE_NAME] = calc.CalcService{
		Conf: &conf.Conf{
			Policies: []conf.Policy{
				conf.Policy{
					Selector: conf.PolicySelector{
						Service: calc.SERVICE_NAME,
						Method:  calc.CALCULATE_METHOD,
					},
					Cmd:  conf.MIN_FEE,
					Args: []interface{}{msg.PaymentValue{2e6, msg.BTC}},
				},
			},
		},
	}
	services[payment.SERVICE_NAME] = &payment.PaymentService{BitcoindConf: btcConf}
	mux := ServiceMux{
		Services: services,
	}
	s := Server{
		Cred:    &cred.Cred{},
		Addr:    addr,
		Handler: &mux,
	}
	listener, err := net.Listen("tcp", s.Addr)
	defer listener.Close()
	if err != nil {
		log.Fatal(err)
	}

	c, err := newClient(btcConf)
	if err != nil {
		log.Fatal(err)
	}

	// Quote
	go s.Serve(listener)
	fmt.Printf("quote\n")
	calcReq := calc.NewCalcReq([]string{"1 2 +"})
	work, err := calc.Measure(calcReq)
	if err != nil {
		log.Fatal(err)
	}
	quoteReq := calc.NewQuoteReq(work)
	fmt.Printf("quote req: %v\n", quoteReq)
	resp, err := c.SignAndSend(addr, quoteReq)
	if err != nil {
		log.Fatal(err)
	}
	pv, err := msg.NewPaymentValue(string(resp.Body))
	fmt.Printf("resp: %v\nbody: %v\n", resp, string(resp.Body))
	if err != nil {
		log.Fatal(err)
	}

	// Get payment address
	go s.Serve(listener)
	fmt.Printf("get payment addr\n")
	payAddrReq := payment.NewPaymentAddrReq(msg.BTC)
	fmt.Printf("req: %v\n", payAddrReq)
	resp, err = c.SignAndSend(addr, payAddrReq)
	if err != nil {
		log.Fatal(err)
	}
	pa, err := msg.NewPaymentAddr(string(resp.Body))
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("resp: %v\npa: %v\n", resp, pa)

	// Send low payment
	// TODO(ortutay): separate test for this
	go s.Serve(listener)
	fmt.Printf("send req with deferred payment")
	lowPv := msg.PaymentValue(*pv)
	lowPv.Amount -= 1
	calcReqLowPv := msg.OcReq(*calcReq)
	calcReqLowPv.AttachDeferredPayment(&lowPv)
	resp, err = c.SignAndSend(addr, &calcReqLowPv)
	if resp.Status != msg.TOO_LOW {
		log.Fatalf("expected status %v, got %v", msg.TOO_LOW, resp.Status)
	}

	// Send requested payment as deferred
	go s.Serve(listener)
	fmt.Printf("send req with deferred payment")
	calcReq.AttachDeferredPayment(pv)
	resp, err = c.SignAndSend(addr, calcReq)
	if resp.Status != msg.OK {
		log.Fatalf("expected status %v, got %v", msg.OK, resp.Status)
	}
	fmt.Printf("resp: %v\n", resp)

	// We got the response, now send the actual payment
	// (normally, we would want to verify the results)
	go s.Serve(listener)
	txid, err := c.SendBtcPayment(pv, pa)
	if err != nil {
		log.Fatal(err)
	}
	txidReq := payment.NewBtcTxidReq(txid)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("txid req: %v\n", txidReq)
	resp, err = c.SignAndSend(addr, txidReq)
	if resp.Status != msg.OK {
		log.Fatalf("expected status %v, got %v", msg.OK, resp.Status)
	}
	fmt.Printf("resp: %v\n", resp)
}
Esempio n. 10
0
func main() {
	goopt.Parse(nil)
	cmdArgs := make([]string, 0)
	for _, arg := range os.Args[1:] {
		if arg[0] != '-' {
			cmdArgs = append(cmdArgs, arg)
		}
	}
	fmt.Printf("cmd args: %v\n", cmdArgs)
	config, err := makeConf(*fMinFee, *fMinCoins, *fMaxWork)
	if err != nil {
		log.Fatal(err.Error())
	}

	config.AddPolicy(&conf.Policy{
		Selector: conf.PolicySelector{},
		Cmd:      conf.MAX_BALANCE,
		Args:     []interface{}{getPaymentValue("", *fMaxBalance)},
	})

	// TODO(ortutay): s/"store"/store.SERVICE_NAME/
	config.AddPolicy(&conf.Policy{
		Selector: conf.PolicySelector{Service: "store"},
		Cmd:      conf.STORE_DIR,
		Args:     []interface{}{*fStoreDir},
	})
	config.AddPolicy(&conf.Policy{
		Selector: conf.PolicySelector{Service: "store"},
		Cmd:      conf.STORE_MAX_SPACE,
		Args:     []interface{}{getSpace("", *fStoreMaxSpace)},
	})
	config.AddPolicy(&conf.Policy{
		Selector: conf.PolicySelector{Service: "store"},
		Cmd:      conf.STORE_GB_PRICE_PER_MO,
		Args:     []interface{}{getPaymentValue("", *fStoreGbPricePerMo)},
	})
	fmt.Printf("running with conf: %v\n", config)

	util.SetAppDir(*fAppDir)
	ocCred, err := cred.NewOcCredLoadOrCreate("")
	if err != nil {
		log.Fatal(err.Error())
	}

	// TODO(ortutay): really, this should be flags to the binary so that we don't
	// spend people's coins without explicit intent
	bConf, err := util.LoadBitcoindConf("")
	if err != nil {
		log.Fatal(err.Error())
	}

	addr := fmt.Sprintf(":%v", *fPort)

	// TODO(ortutay): configure which services to run from command line args
	calcService := calc.CalcService{Conf: config}
	paymentService := payment.PaymentService{Conf: config, BitcoindConf: bConf}
	storeService := store.StoreService{Conf: config}

	services := make(map[string]node.Handler)
	services[calc.SERVICE_NAME] = &calcService
	services[payment.SERVICE_NAME] = &paymentService
	services[store.SERVICE_NAME] = &storeService
	mux := node.ServiceMux{
		Services: services,
	}

	wakers := []node.PeriodicWaker{&storeService}

	s := node.Server{
		Cred: &cred.Cred{
			OcCred:  *ocCred,
			BtcConf: bConf,
			Coins:   []cred.BtcCred{},
		},
		BtcConf:        bConf,
		Conf:           config,
		Addr:           addr,
		Handler:        &mux,
		PeriodicWakers: wakers,
	}
	err = s.ListenAndServe()
	if err != nil {
		log.Fatal(err.Error())
	}
}
Esempio n. 11
0
func main() {
	goopt.Parse(nil)
	util.SetAppDir(*fAppDir)

	ocCred, err := cred.NewOcCredLoadOrCreate("")
	if err != nil {
		log.Fatal(err.Error())
	}

	bConf, err := util.LoadBitcoindConf("")
	if err != nil {
		log.Fatal(err.Error())
	}

	pvLower, err := msg.NewPaymentValueParseString(*fCoinsLower)
	if err != nil {
		log.Fatal(err)
	}
	pvUpper, err := msg.NewPaymentValueParseString(*fCoinsUpper)
	if err != nil {
		log.Fatal(err)
	}
	coins, err := cred.GetBtcCredInRange(pvLower.Amount, pvUpper.Amount, bConf)
	if err != nil {
		log.Fatal(err.Error())
	}

	c := node.Client{
		BtcConf: bConf,
		Cred: cred.Cred{
			OcCred:  *ocCred,
			BtcConf: bConf,
			Coins:   *coins,
		},
	}

	var body []byte
	if !termutil.Isatty(os.Stdin.Fd()) {
		var err error
		body, err = ioutil.ReadAll(os.Stdin)
		util.Ferr(err)
	}

	cmdArgs := make([]string, 0)
	for _, arg := range os.Args[1:] {
		if arg[0] != '-' {
			cmdArgs = append(cmdArgs, arg)
		}
	}
	if len(cmdArgs) == 0 {
		// TODO(ortutay): print usage info
		return
	}

	var req *msg.OcReq
	switch cmdArgs[0] {
	case "quote":
		qReq, err := makeQuoteReq(cmdArgs[1:])
		if err != nil {
			log.Fatal(err.Error())
		}
		resp := sendRequest(&c, qReq)
		if resp.Status == msg.OK {
			var pv msg.PaymentValue
			err := json.Unmarshal(resp.Body, &pv)
			if err != nil {
				panic(err)
			}
			fmt.Printf("\n%v%v\n", util.S2B(pv.Amount), pv.Currency)
		}
	case "call":
		req, err = makeReq(cmdArgs[1:], body)
		if err != nil {
			log.Fatal(err.Error())
		}
		resp := sendRequest(&c, req)
		switch fmt.Sprintf("%v.%v", req.Service, req.Method) {
		case "payment.balance":
			{
				var br payment.BalanceResponse
				err := json.Unmarshal(resp.Body, &br)
				if err != nil {
					log.Fatalf("malformed response")
				}
				fmt.Printf("\nServer reports balance of %v%v (max allowed is %v%v)\n",
					util.S2B(br.Balance.Amount), br.Balance.Currency,
					util.S2B(br.MaxBalance.Amount), br.MaxBalance.Currency)
			}
		}
	case "pay":
		payBtc(&c, cmdArgs)
	case "listrep":
		sel := rep.Record{}
		if len(cmdArgs) > 1 {
			selJson := cmdArgs[1]
			err := json.Unmarshal([]byte(selJson), &sel)
			if err != nil {
				log.Fatal(err.Error())
			}
			fmt.Printf("sel json: %v %v\n", selJson, sel)
		}
		err := rep.PrettyPrint(&sel)
		if err != nil {
			log.Fatal(err.Error())
		}
	default:
		fmt.Printf("unrecognized command: %v", cmdArgs)
	}
}