swarm/storage: Add proper backend + wrapper for simulated testbackend

This commit is contained in:
lash 2018-01-14 06:07:52 +01:00
parent 3ec6a51ca6
commit b635d7fdc1
2 changed files with 101 additions and 53 deletions

View file

@ -11,9 +11,11 @@ import (
"golang.org/x/net/idna"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/contracts/ens"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
)
@ -99,7 +101,9 @@ type resource struct {
// TODO: signature validation
type ResourceHandler struct {
ChunkStore
ethapi *rpc.Client
ethapi *ethclient.Client
rpcClient *rpc.Client
ensapi *ens.ENS
resources map[string]*resource
hashLock sync.Mutex
resourceLock sync.RWMutex
@ -109,7 +113,7 @@ type ResourceHandler struct {
}
// Create or open resource update chunk store
func NewResourceHandler(privKey *ecdsa.PrivateKey, datadir string, cloudStore CloudStore, ethapi *rpc.Client) (*ResourceHandler, error) {
func NewResourceHandler(privKey *ecdsa.PrivateKey, datadir string, cloudStore CloudStore, rpcclient *rpc.Client, ensAddr common.Address) (*ResourceHandler, error) {
path := filepath.Join(datadir, "resource")
dbStore, err := NewDbStore(datadir, nil, singletonSwarmDbCapacity, 0)
if err != nil {
@ -120,9 +124,17 @@ func NewResourceHandler(privKey *ecdsa.PrivateKey, datadir string, cloudStore Cl
DbStore: dbStore,
}
hasher := MakeHashFunc("SHA3")
transactOpts := bind.NewKeyedTransactor(privKey)
ethapi := ethclient.NewClient(rpcclient)
ensinstance, err := ens.NewENS(transactOpts, ensAddr, ethapi)
if err != nil {
return nil, err
}
return &ResourceHandler{
ChunkStore: newResourceChunkStore(path, hasher, localStore, cloudStore),
ethapi: ethapi,
ethapi: ethclient.NewClient(rpcclient),
rpcClient: rpcclient,
ensapi: ensinstance,
resources: make(map[string]*resource),
hasher: hasher(),
privKey: privKey,
@ -519,7 +531,7 @@ func (self *ResourceHandler) Close() {
func (self *ResourceHandler) getBlock() (uint64, error) {
// get the block height and convert to uint64
var currentblock string
err := self.ethapi.Call(&currentblock, "eth_blockNumber")
err := self.rpcClient.Call(&currentblock, "eth_blockNumber")
if err != nil {
return 0, err
}

View file

@ -19,6 +19,7 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/contracts/ens"
"github.com/ethereum/go-ethereum/contracts/ens/contract"
"github.com/ethereum/go-ethereum/core"
@ -29,26 +30,46 @@ import (
)
var (
zeroAddr = common.Address{}
blockCount = uint64(4200)
cleanF func()
hashfunc = sha3.NewKeccak256()
domainName = "føø.bar"
)
func init() {
log.Root().SetHandler(log.CallerFileHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(true)))))
}
type fakeBackend struct {
*backends.SimulatedBackend
blocknumber uint64
}
func (f *fakeBackend) Commit() {
if f.SimulatedBackend != nil {
f.SimulatedBackend.Commit()
}
f.blocknumber++
}
type FakeRPC struct {
blockcount *uint64
backend *fakeBackend
}
func (r *FakeRPC) BlockNumber() (string, error) {
return strconv.FormatUint(*r.blockcount, 10), nil
return strconv.FormatUint(r.backend.blocknumber, 10), nil
}
func TestResourceValidContent(t *testing.T) {
rh, privkey, _, err, teardownTest := setupTest()
// privkey for signing updates
privkey, err := crypto.GenerateKey()
if err != nil {
return
}
rh, _, err, teardownTest := setupTest(privkey, nil, zeroAddr)
if err != nil {
teardownTest(t, err)
}
@ -97,8 +118,14 @@ func TestResourceValidContent(t *testing.T) {
}
func TestResourceReverseLookup(t *testing.T) {
//rh, privkey, datadir, err, teardownTest := setupTest()
rh, _, _, err, teardownTest := setupTest()
// privkey for signing updates
privkey, err := crypto.GenerateKey()
if err != nil {
return
}
rh, _, err, teardownTest := setupTest(privkey, nil, zeroAddr)
if err != nil {
teardownTest(t, err)
}
@ -149,7 +176,13 @@ func TestResourceReverseLookup(t *testing.T) {
func TestResourceHandler(t *testing.T) {
rh, privkey, datadir, err, teardownTest := setupTest()
// privkey for signing updates
privkey, err := crypto.GenerateKey()
if err != nil {
return
}
rh, datadir, err, teardownTest := setupTest(privkey, nil, zeroAddr)
if err != nil {
teardownTest(t, err)
}
@ -218,7 +251,7 @@ func TestResourceHandler(t *testing.T) {
// it will match on second iteration startblocknumber + (resourcefrequency * 3)
blockCount = startblocknumber + (resourcefrequency * 4)
rh2, err := NewResourceHandler(privkey, datadir, &testCloudStore{}, rh.ethapi)
rh2, err := NewResourceHandler(privkey, datadir, &testCloudStore{}, rh.rpcClient, ens.MainNetAddress)
_, err = rh2.LookupLatest(resourcename, true)
if err != nil {
teardownTest(t, err)
@ -280,7 +313,33 @@ func TestResourceHandler(t *testing.T) {
}
func setupTest() (rh *ResourceHandler, privkey *ecdsa.PrivateKey, datadir string, err error, teardown func(*testing.T, error)) {
func TestResourceENS(t *testing.T) {
// privkey for signing updates
privkey, err := crypto.GenerateKey()
if err != nil {
return
}
domainparts := strings.Split(domainName, ".")
addr, contractbackend, err := setupENS(privkey, domainparts[0], domainparts[1])
if err != nil {
t.Fatal(err)
}
rh, _, err, teardownTest := setupTest(privkey, contractbackend, addr)
if err != nil {
teardownTest(t, err)
}
_, err = rh.NewResource(domainName, 42)
if err != nil {
teardownTest(t, err)
}
teardownTest(t, nil)
}
func setupTest(privkey *ecdsa.PrivateKey, contractbackend bind.ContractBackend, ensaddr common.Address) (rh *ResourceHandler, datadir string, err error, teardown func(*testing.T, error)) {
var fsClean func()
var rpcClean func()
@ -293,12 +352,6 @@ func setupTest() (rh *ResourceHandler, privkey *ecdsa.PrivateKey, datadir string
}
}
// privkey for signing updates
privkey, err = crypto.GenerateKey()
if err != nil {
return
}
// temp datadir
datadir, err = ioutil.TempDir("", "rh")
if err != nil {
@ -316,8 +369,12 @@ func setupTest() (rh *ResourceHandler, privkey *ecdsa.PrivateKey, datadir string
return
}
rpcserver := rpc.NewServer()
var fake *fakeBackend
if contractbackend != nil {
fake = contractbackend.(*fakeBackend)
}
rpcserver.RegisterName("eth", &FakeRPC{
blockcount: &blockCount,
backend: fake,
})
go func() {
rpcserver.ServeListener(ipcl)
@ -332,7 +389,7 @@ func setupTest() (rh *ResourceHandler, privkey *ecdsa.PrivateKey, datadir string
return
}
rh, err = NewResourceHandler(privkey, datadir, &testCloudStore{}, rpcclient)
rh, err = NewResourceHandler(privkey, datadir, &testCloudStore{}, rpcclient, ensaddr)
teardown = func(t *testing.T, err error) {
cleanF()
if err != nil {
@ -342,22 +399,7 @@ func setupTest() (rh *ResourceHandler, privkey *ecdsa.PrivateKey, datadir string
return
}
func TestResourceENS(t *testing.T) {
_, privkey, _, err, teardownTest := setupTest()
if err != nil {
teardownTest(t, err)
}
err = setupENS(privkey, "foo", "bar")
if err != nil {
teardownTest(t, err)
}
teardownTest(t, nil)
}
func setupENS(privkey *ecdsa.PrivateKey, sub string, top string) error {
// ens backend
//key := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
func setupENS(privkey *ecdsa.PrivateKey, sub string, top string) (common.Address, bind.ContractBackend, error) {
var tophash [32]byte
var subhash [32]byte
hashfunc.Reset()
@ -367,45 +409,39 @@ func setupENS(privkey *ecdsa.PrivateKey, sub string, top string) error {
hashfunc.Write([]byte(sub))
copy(subhash[:], hashfunc.Sum(nil))
addr := crypto.PubkeyToAddress(privkey.PublicKey)
contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}})
contractBackend := &fakeBackend{
SimulatedBackend: backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}),
}
transactOpts := bind.NewKeyedTransactor(privkey)
_, _, ensinstance, err := contract.DeployENS(transactOpts, contractBackend)
ensAddr, _, ensinstance, err := contract.DeployENS(transactOpts, contractBackend)
if err != nil {
return fmt.Errorf("can't deploy: %v", err)
return zeroAddr, nil, fmt.Errorf("can't deploy: %v", err)
}
// Deploy the registrar.
// regAddr, _, reginstance, err := contract.DeployFIFSRegistrar(transactOpts, contractBackend, ensAddr, [32]byte{})
// if err != nil {
// return fmt.Errorf("can't deploy Registrar: %v", err)
// }
// contractBackend.Commit()
//
// Set the registrar as owner of the ENS root.
if _, err = ensinstance.SetOwner(transactOpts, [32]byte{}, addr); err != nil {
return fmt.Errorf("can't setowner: %v", err)
return zeroAddr, nil, fmt.Errorf("can't setowner: %v", err)
}
contractBackend.Commit()
if _, err = ensinstance.SetSubnodeOwner(transactOpts, [32]byte{}, tophash, addr); err != nil {
return fmt.Errorf("can't register top: %v", err)
return zeroAddr, nil, fmt.Errorf("can't register top: %v", err)
}
contractBackend.Commit()
if _, err = ensinstance.SetSubnodeOwner(transactOpts, ens.EnsNode(top), subhash, addr); err != nil {
return fmt.Errorf("can't register top: %v", err)
return zeroAddr, nil, fmt.Errorf("can't register top: %v", err)
}
contractBackend.Commit()
nodeowner, err := ensinstance.Owner(&bind.CallOpts{}, ens.EnsNode(strings.Join([]string{sub, top}, ".")))
if err != nil {
return fmt.Errorf("can't retrieve owner: %v", err)
return zeroAddr, nil, fmt.Errorf("can't retrieve owner: %v", err)
} else if !bytes.Equal(nodeowner.Bytes(), addr.Bytes()) {
return fmt.Errorf("retrieved owner doesn't match; expected '%x', got '%x'", addr, nodeowner)
return zeroAddr, nil, fmt.Errorf("retrieved owner doesn't match; expected '%x', got '%x'", addr, nodeowner)
}
return nil
return ensAddr, contractBackend, nil
}
type testCloudStore struct {