Relaxed nonce-checking for demo
This commit is contained in:
parent
7dccf61484
commit
538f3110b1
5
Makefile
5
Makefile
|
@ -1,9 +1,6 @@
|
|||
.PHONY: all test get_deps
|
||||
|
||||
all: protoc test install
|
||||
|
||||
protoc:
|
||||
protoc --go_out=. types/*.proto
|
||||
all: test install
|
||||
|
||||
install: get_deps
|
||||
go install github.com/tendermint/blackstar/cmd/...
|
||||
|
|
21
app/app.go
21
app/app.go
|
@ -1,6 +1,7 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/tendermint/blackstar/types"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire"
|
||||
|
@ -62,7 +63,7 @@ func (app *Blackstar) AppendTx(txBytes []byte) (code tmsp.CodeType, result []byt
|
|||
// Load accounts
|
||||
accMap := loadAccounts(app.eyesCli, allPubKeys(tx))
|
||||
// Execute tx
|
||||
accs, code, errStr := execTx(tx, accMap)
|
||||
accs, code, errStr := execTx(tx, accMap, false)
|
||||
if errStr != "" {
|
||||
return code, nil, "Error executing tx: " + errStr
|
||||
}
|
||||
|
@ -89,7 +90,7 @@ func (app *Blackstar) CheckTx(txBytes []byte) (code tmsp.CodeType, result []byte
|
|||
// Load accounts
|
||||
accMap := loadAccounts(app.eyesCli, allPubKeys(tx))
|
||||
// Execute tx
|
||||
_, code, errStr = execTx(tx, accMap)
|
||||
_, code, errStr = execTx(tx, accMap, false)
|
||||
if errStr != "" {
|
||||
return code, nil, "Error (mock) executing tx: " + errStr
|
||||
}
|
||||
|
@ -225,7 +226,9 @@ func allPubKeys(tx types.Tx) (pubKeys []crypto.PubKey) {
|
|||
}
|
||||
|
||||
// Returns accounts in order of types.Tx inputs and outputs
|
||||
func execTx(tx types.Tx, accMap map[string]types.PubAccount) (accs []types.PubAccount, code tmsp.CodeType, errStr string) {
|
||||
// appendTx: true if this is for AppendTx.
|
||||
// TODO: create more intelligent sequence-checking. Current impl is just for a throughput demo.
|
||||
func execTx(tx types.Tx, accMap map[string]types.PubAccount, appendTx bool) (accs []types.PubAccount, code tmsp.CodeType, errStr string) {
|
||||
accs = make([]types.PubAccount, 0, len(tx.Inputs)+len(tx.Outputs))
|
||||
// Deduct from inputs
|
||||
for _, input := range tx.Inputs {
|
||||
|
@ -233,9 +236,15 @@ func execTx(tx types.Tx, accMap map[string]types.PubAccount) (accs []types.PubAc
|
|||
if !ok {
|
||||
return nil, tmsp.CodeType_UnknownAccount, "Input account does not exist"
|
||||
}
|
||||
if appendTx {
|
||||
if acc.Sequence != input.Sequence {
|
||||
return nil, tmsp.CodeType_BadNonce, "Invalid sequence"
|
||||
}
|
||||
} else {
|
||||
if acc.Sequence > input.Sequence {
|
||||
return nil, tmsp.CodeType_BadNonce, "Invalid sequence (too low)"
|
||||
}
|
||||
}
|
||||
if acc.Balance < input.Amount {
|
||||
return nil, tmsp.CodeType_InsufficientFunds, "Insufficient funds"
|
||||
}
|
||||
|
@ -256,8 +265,8 @@ func execTx(tx types.Tx, accMap map[string]types.PubAccount) (accs []types.PubAc
|
|||
},
|
||||
}
|
||||
accMap[output.PubKey.KeyString()] = acc
|
||||
continue
|
||||
}
|
||||
accs = append(accs, acc)
|
||||
} else {
|
||||
// Good!
|
||||
if (acc.Balance + output.Amount) < acc.Balance {
|
||||
return nil, tmsp.CodeType_InternalError, "Output balance overflow in execTx"
|
||||
|
@ -265,6 +274,7 @@ func execTx(tx types.Tx, accMap map[string]types.PubAccount) (accs []types.PubAc
|
|||
acc.Balance += output.Amount
|
||||
accs = append(accs, acc)
|
||||
}
|
||||
}
|
||||
return accs, tmsp.CodeType_OK, ""
|
||||
}
|
||||
|
||||
|
@ -296,6 +306,7 @@ func loadAccounts(eyesCli *eyes.MerkleEyesClient, pubKeys []crypto.PubKey) (accM
|
|||
|
||||
// NOTE: accs must be stored in deterministic order.
|
||||
func storeAccounts(eyesCli *eyes.MerkleEyesClient, accs []types.PubAccount) {
|
||||
fmt.Println("STORE ACCOUNTS", accs)
|
||||
for _, acc := range accs {
|
||||
accBytes := wire.BinaryBytes(acc.Account)
|
||||
err := eyesCli.SetSync([]byte(acc.PubKey.KeyString()), accBytes)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
|
@ -38,6 +37,7 @@ func main() {
|
|||
sequence := uint(0)
|
||||
// Make a bunch of PrivAccounts
|
||||
privAccounts := tests.RandAccounts(1000, 1000000, 0)
|
||||
privAccountSequences := make(map[string]int)
|
||||
|
||||
// Send coins to each account
|
||||
for i := 0; i < len(privAccounts); i++ {
|
||||
|
@ -76,25 +76,51 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Make a bunch of requests
|
||||
for i := 0; ; i++ {
|
||||
binary.BigEndian.PutUint64(buf, uint64(i))
|
||||
//txBytes := hex.EncodeToString(buf[:n])
|
||||
request := rpctypes.NewRPCRequest("fakeid", "broadcast_tx", Arr(buf[:8]))
|
||||
// Now send coins between these accounts
|
||||
for {
|
||||
randA := RandInt() % len(privAccounts)
|
||||
randB := RandInt() % len(privAccounts)
|
||||
if randA == randB {
|
||||
continue
|
||||
}
|
||||
|
||||
privAccountA := privAccounts[randA]
|
||||
privAccountASequence := privAccountSequences[privAccountA.PubKey.KeyString()]
|
||||
privAccountSequences[privAccountA.PubKey.KeyString()] = privAccountASequence + 1
|
||||
privAccountB := privAccounts[randB]
|
||||
|
||||
tx := types.Tx{
|
||||
Inputs: []types.Input{
|
||||
types.Input{
|
||||
PubKey: privAccountA.PubKey,
|
||||
Amount: 3,
|
||||
Sequence: uint(privAccountASequence),
|
||||
},
|
||||
},
|
||||
Outputs: []types.Output{
|
||||
types.Output{
|
||||
PubKey: privAccountB.PubKey,
|
||||
Amount: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Sign request
|
||||
signBytes := wire.BinaryBytes(tx)
|
||||
sig := privAccountA.PrivKey.Sign(signBytes)
|
||||
tx.Inputs[0].Signature = sig
|
||||
//fmt.Println("tx:", tx)
|
||||
|
||||
// Write request
|
||||
txBytes := wire.BinaryBytes(tx)
|
||||
request := rpctypes.NewRPCRequest("fakeid", "broadcast_tx_sync", Arr(txBytes))
|
||||
reqBytes := wire.JSONBytes(request)
|
||||
//fmt.Println("!!", string(reqBytes))
|
||||
fmt.Print(".")
|
||||
//fmt.Print(".")
|
||||
err := ws.WriteMessage(websocket.TextMessage, reqBytes)
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
Exit("writing websocket request: " + err.Error())
|
||||
}
|
||||
if i%1000 == 0 {
|
||||
fmt.Println(i)
|
||||
}
|
||||
time.Sleep(time.Microsecond * 1000)
|
||||
}
|
||||
*/
|
||||
|
||||
ws.Stop()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue