tapir/applications/tokenboard/tokenboard_integration_test.go

157 lines
5.2 KiB
Go
Raw Normal View History

2019-09-15 21:20:05 +00:00
package tokenboard
import (
"errors"
"git.openprivacy.ca/cwtch.im/tapir/applications"
"git.openprivacy.ca/cwtch.im/tapir/networks/tor"
"git.openprivacy.ca/cwtch.im/tapir/primitives"
"git.openprivacy.ca/cwtch.im/tapir/primitives/auditable"
"git.openprivacy.ca/cwtch.im/tapir/primitives/privacypass"
"git.openprivacy.ca/openprivacy/connectivity"
torProvider "git.openprivacy.ca/openprivacy/connectivity/tor"
"git.openprivacy.ca/openprivacy/log"
2020-06-29 21:32:38 +00:00
"os"
2019-09-15 21:20:05 +00:00
"runtime"
"sync"
"testing"
"time"
)
type Handler struct {
Store *auditable.Store
}
func (h Handler) HandleNewMessages(previousLastCommit []byte) {
log.Debugf("Handling Messages After %x", previousLastCommit)
messages := h.Store.GetMessagesAfter(previousLastCommit)
for _, message := range messages {
log.Debugf("Message %s", message)
}
}
type FreePaymentHandler struct {
tokens []*privacypass.Token
TokenService *privacypass.TokenServer
ACN connectivity.ACN
ServerHostname string
}
func (fph *FreePaymentHandler) MakePayment() {
id, sk := primitives.InitializeEphemeralIdentity()
2021-06-09 17:36:34 +00:00
client := new(tor.BaseOnionService)
2019-09-15 21:20:05 +00:00
client.Init(fph.ACN, sk, &id)
tokenApplication := new(applications.TokenApplication)
tokenApplication.TokenService = fph.TokenService
powTokenApp := new(applications.ApplicationChain).
ChainApplication(new(applications.ProofOfWorkApplication), applications.SuccessfulProofOfWorkCapability).
ChainApplication(tokenApplication, applications.HasTokensCapability)
client.Connect(fph.ServerHostname, powTokenApp)
2019-11-26 21:10:09 +00:00
conn, err := client.WaitForCapabilityOrClose(fph.ServerHostname, applications.HasTokensCapability)
2019-09-15 21:20:05 +00:00
if err == nil {
powtapp, _ := conn.App().(*applications.TokenApplication)
fph.tokens = append(fph.tokens, powtapp.Tokens...)
log.Debugf("Transcript: %v", powtapp.Transcript().OutputTranscriptToAudit())
conn.Close()
2019-11-26 21:10:09 +00:00
return
2019-09-15 21:20:05 +00:00
}
log.Debugf("Error making payment: %v", err)
}
2019-11-26 21:10:09 +00:00
func (fph *FreePaymentHandler) NextToken(data []byte, hostname string) (privacypass.SpentToken, error) {
2019-09-15 21:20:05 +00:00
if len(fph.tokens) == 0 {
return privacypass.SpentToken{}, errors.New("No more tokens")
}
token := fph.tokens[0]
fph.tokens = fph.tokens[1:]
2019-11-26 21:10:09 +00:00
return token.SpendToken(append(data, hostname...)), nil
2019-09-15 21:20:05 +00:00
}
func TestTokenBoardApp(t *testing.T) {
// numRoutinesStart := runtime.NumGoroutine()
log.SetLevel(log.LevelDebug)
log.Infof("Number of goroutines open at start: %d", runtime.NumGoroutine())
2020-06-29 21:32:38 +00:00
os.MkdirAll("./tor/", 0700)
2021-04-09 00:14:41 +00:00
builder := new(torProvider.TorrcBuilder)
builder.WithHashedPassword("tapir-integration-test").Build("./tor/torrc")
2020-06-29 21:32:38 +00:00
2019-09-15 21:20:05 +00:00
// Connect to Tor
2020-06-29 21:32:38 +00:00
acn, err := torProvider.NewTorACNWithAuth("./", "", 9051, torProvider.HashedPasswordAuthenticator{Password: "tapir-integration-test"})
if err != nil {
t.Fatalf("could not launch ACN %v", err)
}
2019-09-15 21:20:05 +00:00
acn.WaitTillBootstrapped()
// Generate Server Key
sid, sk := primitives.InitializeEphemeralIdentity()
tokenService := privacypass.NewTokenServer()
serverAuditableStore := new(auditable.Store)
serverAuditableStore.Init(sid)
clientAuditableStore := new(auditable.Store)
// Only initialize with public parameters
sidpubk := sid.PublicKey()
publicsid := primitives.InitializeIdentity("server", nil, &sidpubk)
clientAuditableStore.Init(publicsid)
// Init the Server running the Simple App.
2021-06-09 17:36:34 +00:00
service := new(tor.BaseOnionService)
2019-09-15 21:20:05 +00:00
service.Init(acn, sk, &sid)
// Goroutine Management
sg := new(sync.WaitGroup)
sg.Add(1)
go func() {
2019-11-26 21:10:09 +00:00
service.Listen(NewTokenBoardServer(tokenService, serverAuditableStore))
2019-09-15 21:20:05 +00:00
sg.Done()
}()
// Init the Server running the PoW Token App.
2021-06-09 17:36:34 +00:00
powTokenService := new(tor.BaseOnionService)
2019-09-15 21:20:05 +00:00
spowid, spowk := primitives.InitializeEphemeralIdentity()
powTokenService.Init(acn, spowk, &spowid)
sg.Add(1)
go func() {
tokenApplication := new(applications.TokenApplication)
2019-11-26 21:10:09 +00:00
tokenApplication.TokenService = tokenService
2019-09-15 21:20:05 +00:00
powTokenApp := new(applications.ApplicationChain).
ChainApplication(new(applications.ProofOfWorkApplication), applications.SuccessfulProofOfWorkCapability).
ChainApplication(tokenApplication, applications.HasTokensCapability)
powTokenService.Listen(powTokenApp)
sg.Done()
}()
time.Sleep(time.Second * 60) // wait for server to initialize
id, sk := primitives.InitializeEphemeralIdentity()
2021-06-09 17:36:34 +00:00
client := new(tor.BaseOnionService)
2019-09-15 21:20:05 +00:00
client.Init(acn, sk, &id)
2019-11-26 21:10:09 +00:00
client.Connect(sid.Hostname(), NewTokenBoardClient(clientAuditableStore, Handler{Store: clientAuditableStore}, &FreePaymentHandler{ACN: acn, TokenService: tokenService, ServerHostname: spowid.Hostname()}))
2019-09-15 21:20:05 +00:00
client.WaitForCapabilityOrClose(sid.Hostname(), applications.AuthCapability)
conn, _ := client.GetConnection(sid.Hostname())
tba, _ := conn.App().(*Client)
tba.PurchaseTokens()
tba.Post([]byte("HELLO 1"))
tba.Post([]byte("HELLO 2"))
tba.Post([]byte("HELLO 3"))
tba.Post([]byte("HELLO 4"))
tba.Post([]byte("HELLO 5"))
tba.Replay()
time.Sleep(time.Second * 10) // We have to wait for the async replay request!
tba.Post([]byte("HELLO 6"))
tba.Post([]byte("HELLO 7"))
tba.Post([]byte("HELLO 8"))
tba.Post([]byte("HELLO 9"))
tba.Post([]byte("HELLO 10"))
tba.Replay()
time.Sleep(time.Second * 10) // We have to wait for the async replay request!
if tba.Post([]byte("HELLO 11")) {
t.Errorf("Post should have failed.")
}
time.Sleep(time.Second * 10)
acn.Close()
sg.Wait()
}