mirror of https://github.com/poanetwork/quorum.git
Fix TestPrivateTransaction to actually create private transactions (#144)
It now creates private transactions, but that means it now needs to run constellation in a subprocess, so do that as well
This commit is contained in:
parent
875c10b2d3
commit
57e7e5f92f
|
@ -14,28 +14,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
)
|
)
|
||||||
|
|
||||||
// privateTestMessage stubs transaction so that it can be flagged as private or not
|
|
||||||
// TODO(joel): is there duplication between this and callmsg?
|
|
||||||
type privateTestMessage struct {
|
|
||||||
*types.Message
|
|
||||||
private bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must implement `Message`
|
|
||||||
func (ptx privateTestMessage) From() common.Address { return ptx.Message.From() }
|
|
||||||
func (ptx privateTestMessage) To() *common.Address { return ptx.Message.To() }
|
|
||||||
|
|
||||||
func (ptx privateTestMessage) GasPrice() *big.Int { return ptx.Message.GasPrice() }
|
|
||||||
func (ptx privateTestMessage) Gas() *big.Int { return ptx.Message.Gas() }
|
|
||||||
func (ptx privateTestMessage) Value() *big.Int { return ptx.Message.Value() }
|
|
||||||
|
|
||||||
func (ptx privateTestMessage) Nonce() uint64 { return ptx.Message.Nonce() }
|
|
||||||
func (ptx privateTestMessage) CheckNonce() bool { return ptx.Message.CheckNonce() }
|
|
||||||
func (ptx privateTestMessage) Data() []byte { return ptx.Message.Data() }
|
|
||||||
|
|
||||||
// IsPrivate returns whether the transaction should be considered private.
|
|
||||||
func (pmsg privateTestMessage) IsPrivate() bool { return pmsg.private }
|
|
||||||
|
|
||||||
// callHelper makes it easier to do proper calls and use the state transition object.
|
// callHelper makes it easier to do proper calls and use the state transition object.
|
||||||
// It also manages the nonces of the caller and keeps private and public state, which
|
// It also manages the nonces of the caller and keeps private and public state, which
|
||||||
// can be freely modified outside of the helper.
|
// can be freely modified outside of the helper.
|
||||||
|
@ -59,7 +37,6 @@ func (cg *callHelper) TxNonce(addr common.Address) uint64 {
|
||||||
func (cg *callHelper) MakeCall(private bool, key *ecdsa.PrivateKey, to common.Address, input []byte) error {
|
func (cg *callHelper) MakeCall(private bool, key *ecdsa.PrivateKey, to common.Address, input []byte) error {
|
||||||
var (
|
var (
|
||||||
from = crypto.PubkeyToAddress(key.PublicKey)
|
from = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
pmsg = privateTestMessage{private: private}
|
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -79,18 +56,19 @@ func (cg *callHelper) MakeCall(private bool, key *ecdsa.PrivateKey, to common.Ad
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pmsg.Message = &msg
|
|
||||||
|
|
||||||
publicState, privateState := cg.PublicState, cg.PrivateState
|
publicState, privateState := cg.PublicState, cg.PrivateState
|
||||||
if !private {
|
if !private {
|
||||||
privateState = publicState
|
privateState = publicState
|
||||||
|
} else {
|
||||||
|
tx.SetPrivate()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(joel): can we just pass nil instead of bc?
|
// TODO(joel): can we just pass nil instead of bc?
|
||||||
bc, _ := NewBlockChain(cg.db, params.QuorumTestChainConfig, ethash.NewFaker(), vm.Config{})
|
bc, _ := NewBlockChain(cg.db, params.QuorumTestChainConfig, ethash.NewFaker(), vm.Config{})
|
||||||
context := NewEVMContext(pmsg, &cg.header, bc, &from)
|
context := NewEVMContext(msg, &cg.header, bc, &from)
|
||||||
vmenv := vm.NewEVM(context, publicState, privateState, params.QuorumTestChainConfig, vm.Config{})
|
vmenv := vm.NewEVM(context, publicState, privateState, params.QuorumTestChainConfig, vm.Config{})
|
||||||
_, _, _, err = ApplyMessage(vmenv, pmsg, cg.gp)
|
_, _, _, err = ApplyMessage(vmenv, msg, cg.gp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
{"data":{"bytes":"Wl+xSyXVuuqzpvznOS7dOobhcn4C5auxkFRi7yLtgtA="},"type":"unlocked"}
|
|
@ -0,0 +1 @@
|
||||||
|
BULeR8JyUWhiuuCMU/HLA0Q5pzkYT+cHII3ZKBey3Bo=
|
|
@ -0,0 +1 @@
|
||||||
|
{"data":{"bytes":"wGEar7J9G0JAgdisp61ZChyrJWeW2QPyKvecjjeVHOY="},"type":"unlocked"}
|
|
@ -0,0 +1 @@
|
||||||
|
8SjRHlUBe4hAmTk3KDeJ96RhN+s10xRrHDrxEi1O5W0=
|
|
@ -1,12 +1,21 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"io/ioutil"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"os"
|
||||||
|
osExec "os/exec"
|
||||||
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/private"
|
||||||
|
"github.com/ethereum/go-ethereum/private/constellation"
|
||||||
)
|
)
|
||||||
|
|
||||||
// callmsg is the message type used for call transactions in the private state test
|
// callmsg is the message type used for call transactions in the private state test
|
||||||
|
@ -63,6 +72,60 @@ func ExampleMakeCallHelper() {
|
||||||
fmt.Println("Public:", helper.PublicState.GetState(pubContractAddr, common.Hash{}).Big())
|
fmt.Println("Public:", helper.PublicState.GetState(pubContractAddr, common.Hash{}).Big())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var constellationCfgTemplate = template.Must(template.New("t").Parse(`
|
||||||
|
url = "http://127.0.0.1:9000/"
|
||||||
|
port = 9000
|
||||||
|
socketPath = "{{.RootDir}}/qdata/tm1.ipc"
|
||||||
|
otherNodeUrls = []
|
||||||
|
publicKeyPath = "{{.RootDir}}/keys/tm1.pub"
|
||||||
|
privateKeyPath = "{{.RootDir}}/keys/tm1.key"
|
||||||
|
archivalPublicKeyPath = "{{.RootDir}}/keys/tm1a.pub"
|
||||||
|
archivalPrivateKeyPath = "{{.RootDir}}/keys/tm1a.key"
|
||||||
|
storagePath = "{{.RootDir}}/qdata/constellation1"
|
||||||
|
`))
|
||||||
|
|
||||||
|
func runConstellation() (*osExec.Cmd, error) {
|
||||||
|
dir, err := ioutil.TempDir("", "TestPrivateTxConstellationData")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer os.RemoveAll(dir)
|
||||||
|
here, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = os.MkdirAll(path.Join(dir, "qdata"), 0755); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = os.Symlink(path.Join(here, "constellation-test-keys"), path.Join(dir, "keys")); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cfgFile, err := os.Create(path.Join(dir, "constellation.cfg"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = constellationCfgTemplate.Execute(cfgFile, map[string]string{"RootDir": dir})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
constellationCmd := osExec.Command("constellation-node", cfgFile.Name())
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
constellationCmd.Stdout = &stdout
|
||||||
|
constellationCmd.Stderr = &stderr
|
||||||
|
var constellationErr error
|
||||||
|
go func() {
|
||||||
|
constellationErr = constellationCmd.Start()
|
||||||
|
}()
|
||||||
|
// Give the constellation subprocess some time to start.
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
if constellationErr != nil {
|
||||||
|
fmt.Println(stdout.String() + stderr.String())
|
||||||
|
return nil, constellationErr
|
||||||
|
}
|
||||||
|
private.P = constellation.MustNew(cfgFile.Name())
|
||||||
|
return constellationCmd, nil
|
||||||
|
}
|
||||||
|
|
||||||
// 600a600055600060006001a1
|
// 600a600055600060006001a1
|
||||||
// [1] PUSH1 0x0a (store value)
|
// [1] PUSH1 0x0a (store value)
|
||||||
// [3] PUSH1 0x00 (store addr)
|
// [3] PUSH1 0x00 (store addr)
|
||||||
|
@ -73,7 +136,6 @@ func ExampleMakeCallHelper() {
|
||||||
// [11] LOG1
|
// [11] LOG1
|
||||||
//
|
//
|
||||||
// Store then log
|
// Store then log
|
||||||
|
|
||||||
func TestPrivateTransaction(t *testing.T) {
|
func TestPrivateTransaction(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
key, _ = crypto.GenerateKey()
|
key, _ = crypto.GenerateKey()
|
||||||
|
@ -82,6 +144,12 @@ func TestPrivateTransaction(t *testing.T) {
|
||||||
publicState = helper.PublicState
|
publicState = helper.PublicState
|
||||||
)
|
)
|
||||||
|
|
||||||
|
constellationCmd, err := runConstellation()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer constellationCmd.Process.Kill()
|
||||||
|
|
||||||
prvContractAddr := common.Address{1}
|
prvContractAddr := common.Address{1}
|
||||||
pubContractAddr := common.Address{2}
|
pubContractAddr := common.Address{2}
|
||||||
privateState.SetCode(prvContractAddr, common.Hex2Bytes("600a600055600060006001a1"))
|
privateState.SetCode(prvContractAddr, common.Hex2Bytes("600a600055600060006001a1"))
|
||||||
|
@ -94,7 +162,7 @@ func TestPrivateTransaction(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private transaction 1
|
// Private transaction 1
|
||||||
err := helper.MakeCall(true, key, prvContractAddr, nil)
|
err = helper.MakeCall(true, key, prvContractAddr, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue