From c1b06d81017873cd6f53e4c917cdb958105e2128 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 31 Mar 2015 04:53:34 -0700 Subject: [PATCH 1/4] rpc: GetStorage and Call methods. Tests. --- rpc/core/accounts.go | 17 +++++++ rpc/core/mempool.go | 2 +- rpc/core/pipe.go | 5 +++ rpc/core/responses.go | 11 +++++ rpc/core/txs.go | 45 +++++++++++++++++++ rpc/handlers.go | 2 + rpc/test/http_rpc_test.go | 71 +++++++++++++++++------------ rpc/test/json_rpc_test.go | 16 +++---- rpc/test/test.go | 94 ++++++++++++++++++++++++++++++++++++--- 9 files changed, 221 insertions(+), 42 deletions(-) diff --git a/rpc/core/accounts.go b/rpc/core/accounts.go index abf208897..55c9b38e2 100644 --- a/rpc/core/accounts.go +++ b/rpc/core/accounts.go @@ -3,6 +3,7 @@ package core import ( "fmt" "github.com/tendermint/tendermint2/account" + . "github.com/tendermint/tendermint2/common" ) func GenPrivAccount() (*ResponseGenPrivAccount, error) { @@ -14,6 +15,22 @@ func GetAccount(addr []byte) (*ResponseGetAccount, error) { return &ResponseGetAccount{cache.GetAccount(addr)}, nil } +func GetStorage(address, slot []byte) (*ResponseGetStorage, error) { + state := consensusState.GetState() + account := state.GetAccount(address) + if account == nil { + return nil, fmt.Errorf("Unknown address: %X", address) + } + storageRoot := account.StorageRoot + storage := state.LoadStorage(storageRoot) + + _, value := storage.Get(RightPadWord256(slot).Bytes()) + if value == nil { + return &ResponseGetStorage{slot, nil}, nil + } + return &ResponseGetStorage{slot, value.([]byte)}, nil +} + func ListAccounts() (*ResponseListAccounts, error) { var blockHeight uint var accounts []*account.Account diff --git a/rpc/core/mempool.go b/rpc/core/mempool.go index 3f51a2177..c55876d31 100644 --- a/rpc/core/mempool.go +++ b/rpc/core/mempool.go @@ -28,7 +28,7 @@ func BroadcastTx(tx types.Tx) (*ResponseBroadcastTx, error) { var contractAddr []byte // check if creates new contract if callTx, ok := tx.(*types.CallTx); ok { - if callTx.Address == nil { + if len(callTx.Address) == 0 { createsContract = 1 contractAddr = state.NewContractAddress(callTx.Input.Address, uint64(callTx.Input.Sequence)) } diff --git a/rpc/core/pipe.go b/rpc/core/pipe.go index 4776a4e39..9562bd533 100644 --- a/rpc/core/pipe.go +++ b/rpc/core/pipe.go @@ -5,6 +5,7 @@ import ( "github.com/tendermint/tendermint2/consensus" mempl "github.com/tendermint/tendermint2/mempool" "github.com/tendermint/tendermint2/p2p" + "github.com/tendermint/tendermint2/state" ) var blockStore *bc.BlockStore @@ -27,3 +28,7 @@ func SetMempoolReactor(mr *mempl.MempoolReactor) { func SetSwitch(sw *p2p.Switch) { p2pSwitch = sw } + +func SetPrivValidator(priv *state.PrivValidator) { + consensusState.SetPrivValidator(priv) +} diff --git a/rpc/core/responses.go b/rpc/core/responses.go index a3ef7739b..61f06d9c5 100644 --- a/rpc/core/responses.go +++ b/rpc/core/responses.go @@ -14,6 +14,17 @@ type ResponseGetAccount struct { Account *account.Account } +type ResponseGetStorage struct { + Key []byte + Value []byte +} + +type ResponseCall struct { + Return []byte + GasUsed uint64 + // TODO ... +} + type ResponseListAccounts struct { BlockHeight uint Accounts []*account.Account diff --git a/rpc/core/txs.go b/rpc/core/txs.go index d33079e7b..37f062f25 100644 --- a/rpc/core/txs.go +++ b/rpc/core/txs.go @@ -3,9 +3,54 @@ package core import ( "fmt" "github.com/tendermint/tendermint2/account" + . "github.com/tendermint/tendermint2/common" + "github.com/tendermint/tendermint2/state" "github.com/tendermint/tendermint2/types" + "github.com/tendermint/tendermint2/vm" ) +func toVMAccount(acc *account.Account) *vm.Account { + return &vm.Account{ + Address: RightPadWord256(acc.Address), + Balance: acc.Balance, + Code: acc.Code, // This is crazy. + Nonce: uint64(acc.Sequence), + StorageRoot: RightPadWord256(acc.StorageRoot), + Other: acc.PubKey, + } +} + +//----------------------------------------------------------------------------- + +// Run a contract's code on an isolated and unpersisted state +// Cannot be used to create new contracts +func Call(address, data []byte) (*ResponseCall, error) { + + st := consensusState.GetState() // performs a copy + cache := mempoolReactor.Mempool.GetCache() + outAcc := cache.GetAccount(address) + if outAcc == nil { + return nil, fmt.Errorf("Account %x does not exist", address) + } + callee := toVMAccount(outAcc) + caller := &vm.Account{Address: Zero256} + txCache := state.NewTxCache(cache) + params := vm.Params{ + BlockHeight: uint64(st.LastBlockHeight), + BlockHash: RightPadWord256(st.LastBlockHash), + BlockTime: st.LastBlockTime.Unix(), + GasLimit: 10000000, + } + + vmach := vm.NewVM(txCache, params, caller.Address) + gas := uint64(1000000000) + ret, err := vmach.Call(caller, callee, callee.Code, data, 0, &gas) + if err != nil { + return nil, err + } + return &ResponseCall{Return: ret}, nil +} + //----------------------------------------------------------------------------- func SignTx(tx types.Tx, privAccounts []*account.PrivAccount) (*ResponseSignTx, error) { diff --git a/rpc/handlers.go b/rpc/handlers.go index 858786024..703be74c4 100644 --- a/rpc/handlers.go +++ b/rpc/handlers.go @@ -22,6 +22,8 @@ var funcMap = map[string]*FuncWrapper{ "blockchain": funcWrap(core.BlockchainInfo, []string{"min_height", "max_height"}), "get_block": funcWrap(core.GetBlock, []string{"height"}), "get_account": funcWrap(core.GetAccount, []string{"address"}), + "get_storage": funcWrap(core.GetStorage, []string{"address", "storage"}), + "call": funcWrap(core.Call, []string{"address", "data"}), "list_validators": funcWrap(core.ListValidators, []string{}), "dump_storage": funcWrap(core.DumpStorage, []string{"address"}), "broadcast_tx": funcWrap(core.BroadcastTx, []string{"tx"}), diff --git a/rpc/test/http_rpc_test.go b/rpc/test/http_rpc_test.go index 4de03b783..97e886809 100644 --- a/rpc/test/http_rpc_test.go +++ b/rpc/test/http_rpc_test.go @@ -6,14 +6,16 @@ import ( "encoding/json" "fmt" "github.com/tendermint/tendermint2/binary" + . "github.com/tendermint/tendermint2/common" "github.com/tendermint/tendermint2/config" "github.com/tendermint/tendermint2/merkle" "github.com/tendermint/tendermint2/rpc/core" + "github.com/tendermint/tendermint2/state" "github.com/tendermint/tendermint2/types" "io/ioutil" "net/http" - "net/url" "testing" + "time" ) func TestHTTPStatus(t *testing.T) { @@ -88,16 +90,16 @@ func TestHTTPSignedTx(t *testing.T) { amt := uint64(100) toAddr := []byte{20, 143, 25, 63, 16, 177, 83, 29, 91, 91, 54, 23, 233, 46, 190, 121, 122, 34, 86, 54} - tx, priv := signTx(t, "HTTP", byteAddr, toAddr, byteKey, amt) - checkTx(t, byteAddr, priv, tx) + tx, priv := signTx(t, "HTTP", byteAddr, toAddr, nil, byteKey, amt, 0, 0) + checkTx(t, byteAddr, priv, tx.(*types.SendTx)) toAddr = []byte{20, 143, 24, 63, 16, 17, 83, 29, 90, 91, 52, 2, 0, 41, 190, 121, 122, 34, 86, 54} - tx, priv = signTx(t, "HTTP", byteAddr, toAddr, byteKey, amt) - checkTx(t, byteAddr, priv, tx) + tx, priv = signTx(t, "HTTP", byteAddr, toAddr, nil, byteKey, amt, 0, 0) + checkTx(t, byteAddr, priv, tx.(*types.SendTx)) toAddr = []byte{0, 0, 4, 0, 0, 4, 0, 0, 4, 91, 52, 2, 0, 41, 190, 121, 122, 34, 86, 54} - tx, priv = signTx(t, "HTTP", byteAddr, toAddr, byteKey, amt) - checkTx(t, byteAddr, priv, tx) + tx, priv = signTx(t, "HTTP", byteAddr, toAddr, nil, byteKey, amt, 0, 0) + checkTx(t, byteAddr, priv, tx.(*types.SendTx)) } func TestHTTPBroadcastTx(t *testing.T) { @@ -108,27 +110,7 @@ func TestHTTPBroadcastTx(t *testing.T) { amt := uint64(100) toAddr := []byte{20, 143, 25, 63, 16, 177, 83, 29, 91, 91, 54, 23, 233, 46, 190, 121, 122, 34, 86, 54} - tx, priv := signTx(t, "HTTP", byteAddr, toAddr, byteKey, amt) - checkTx(t, byteAddr, priv, tx) - - n, w := new(int64), new(bytes.Buffer) - var err error - binary.WriteJSON(tx, w, n, &err) - if err != nil { - t.Fatal(err) - } - b := w.Bytes() - - var status struct { - Status string - Data core.ResponseBroadcastTx - Error string - } - requestResponse(t, "broadcast_tx", url.Values{"tx": {string(b)}}, &status) - if status.Status == "ERROR" { - t.Fatal(status.Error) - } - receipt := status.Data.Receipt + tx, receipt := broadcastTx(t, "HTTP", byteAddr, toAddr, nil, byteKey, amt, 0, 0) if receipt.CreatesContract > 0 { t.Fatal("This tx does not create a contract") } @@ -148,6 +130,39 @@ func TestHTTPBroadcastTx(t *testing.T) { } +func TestHTTPGetStorage(t *testing.T) { + priv := state.LoadPrivValidator(".tendermint/priv_validator.json") + _ = priv + //core.SetPrivValidator(priv) + + byteAddr, _ := hex.DecodeString(userAddr) + var byteKey [64]byte + oh, _ := hex.DecodeString(userPriv) + copy(byteKey[:], oh) + + amt := uint64(1100) + code := []byte{0x60, 0x5, 0x60, 0x1, 0x55} + _, receipt := broadcastTx(t, "HTTP", byteAddr, nil, code, byteKey, amt, 1000, 1000) + if receipt.CreatesContract == 0 { + t.Fatal("This tx creates a contract") + } + if len(receipt.TxHash) == 0 { + t.Fatal("Failed to compute tx hash") + } + contractAddr := receipt.ContractAddr + if len(contractAddr) == 0 { + t.Fatal("Creates contract but resulting address is empty") + } + time.Sleep(time.Second * 20) + + v := getStorage(t, contractAddr, []byte{0x1}) + got := RightPadWord256(v) + expected := RightPadWord256([]byte{0x5}) + if got.Compare(expected) != 0 { + t.Fatalf("Wrong storage value. Got %x, expected %x", got.Bytes(), expected.Bytes()) + } +} + /*tx.Inputs[0].Signature = mint.priv.PrivKey.Sign(account.SignBytes(tx)) err = mint.MempoolReactor.BroadcastTx(tx) return hex.EncodeToString(merkle.HashFromBinary(tx)), err*/ diff --git a/rpc/test/json_rpc_test.go b/rpc/test/json_rpc_test.go index 5d44429a5..7da00ccc3 100644 --- a/rpc/test/json_rpc_test.go +++ b/rpc/test/json_rpc_test.go @@ -107,16 +107,16 @@ func TestJSONSignedTx(t *testing.T) { amt := uint64(100) toAddr := []byte{20, 143, 25, 63, 16, 177, 83, 29, 91, 91, 54, 23, 233, 46, 190, 121, 122, 34, 86, 54} - tx, priv := signTx(t, "JSONRPC", byteAddr, toAddr, byteKey, amt) - checkTx(t, byteAddr, priv, tx) + tx, priv := signTx(t, "JSONRPC", byteAddr, toAddr, nil, byteKey, amt, 0, 0) + checkTx(t, byteAddr, priv, tx.(*types.SendTx)) toAddr = []byte{20, 143, 24, 63, 16, 17, 83, 29, 90, 91, 52, 2, 0, 41, 190, 121, 122, 34, 86, 54} - tx, priv = signTx(t, "JSONRPC", byteAddr, toAddr, byteKey, amt) - checkTx(t, byteAddr, priv, tx) + tx, priv = signTx(t, "JSONRPC", byteAddr, toAddr, nil, byteKey, amt, 0, 0) + checkTx(t, byteAddr, priv, tx.(*types.SendTx)) toAddr = []byte{0, 0, 4, 0, 0, 4, 0, 0, 4, 91, 52, 2, 0, 41, 190, 121, 122, 34, 86, 54} - tx, priv = signTx(t, "JSONRPC", byteAddr, toAddr, byteKey, amt) - checkTx(t, byteAddr, priv, tx) + tx, priv = signTx(t, "JSONRPC", byteAddr, toAddr, nil, byteKey, amt, 0, 0) + checkTx(t, byteAddr, priv, tx.(*types.SendTx)) } func TestJSONBroadcastTx(t *testing.T) { @@ -127,8 +127,8 @@ func TestJSONBroadcastTx(t *testing.T) { amt := uint64(100) toAddr := []byte{20, 143, 25, 63, 16, 177, 83, 29, 91, 91, 54, 23, 233, 46, 190, 121, 122, 34, 86, 54} - tx, priv := signTx(t, "JSONRPC", byteAddr, toAddr, byteKey, amt) - checkTx(t, byteAddr, priv, tx) + tx, priv := signTx(t, "JSONRPC", byteAddr, toAddr, nil, byteKey, amt, 0, 0) + checkTx(t, byteAddr, priv, tx.(*types.SendTx)) n, w := new(int64), new(bytes.Buffer) var err error diff --git a/rpc/test/test.go b/rpc/test/test.go index e391fee77..0923508bc 100644 --- a/rpc/test/test.go +++ b/rpc/test/test.go @@ -108,7 +108,7 @@ func getAccount(t *testing.T, typ string, addr []byte) *account.Account { return status.Data.Account } -func makeTx(t *testing.T, typ string, from, to []byte, amt uint64) *types.SendTx { +func makeSendTx(t *testing.T, typ string, from, to []byte, amt uint64) *types.SendTx { acc := getAccount(t, typ, from) nonce := 0 if acc != nil { @@ -138,6 +138,33 @@ func makeTx(t *testing.T, typ string, from, to []byte, amt uint64) *types.SendTx return tx } +func makeCallTx(t *testing.T, typ string, from, to, data []byte, amt, gaslim, fee uint64) *types.CallTx { + acc := getAccount(t, typ, from) + nonce := 0 + if acc != nil { + nonce = int(acc.Sequence) + 1 + } + + bytePub, err := hex.DecodeString(userPub) + if err != nil { + t.Fatal(err) + } + tx := &types.CallTx{ + Input: &types.TxInput{ + Address: from, + Amount: amt, + Sequence: uint(nonce), + Signature: account.SignatureEd25519{}, + PubKey: account.PubKeyEd25519(bytePub), + }, + Address: to, + GasLimit: gaslim, + Fee: fee, + Data: data, + } + return tx +} + func requestResponse(t *testing.T, method string, values url.Values, status interface{}) { resp, err := http.PostForm(requestAddr+method, values) if err != nil { @@ -154,8 +181,13 @@ func requestResponse(t *testing.T, method string, values url.Values, status inte } } -func signTx(t *testing.T, typ string, fromAddr, toAddr []byte, key [64]byte, amt uint64) (*types.SendTx, *account.PrivAccount) { - tx := makeTx(t, typ, fromAddr, toAddr, amt) +func signTx(t *testing.T, typ string, fromAddr, toAddr, data []byte, key [64]byte, amt, gaslim, fee uint64) (types.Tx, *account.PrivAccount) { + var tx types.Tx + if data == nil { + tx = makeSendTx(t, typ, fromAddr, toAddr, amt) + } else { + tx = makeCallTx(t, typ, fromAddr, toAddr, data, amt, gaslim, fee) + } n, w := new(int64), new(bytes.Buffer) var err error @@ -185,8 +217,60 @@ func signTx(t *testing.T, typ string, fromAddr, toAddr []byte, key [64]byte, amt t.Fatal(status.Error) } response := status.Data - tx = response.Tx.(*types.SendTx) - return tx, privAcc + //tx = response.Tx.(*types.SendTx) + return response.Tx, privAcc +} + +func broadcastTx(t *testing.T, typ string, fromAddr, toAddr, data []byte, key [64]byte, amt, gaslim, fee uint64) (types.Tx, core.Receipt) { + tx, _ := signTx(t, typ, fromAddr, toAddr, data, key, amt, gaslim, fee) + + n, w := new(int64), new(bytes.Buffer) + var err error + binary.WriteJSON(tx, w, n, &err) + if err != nil { + t.Fatal(err) + } + b := w.Bytes() + + var status struct { + Status string + Data core.ResponseBroadcastTx + Error string + } + requestResponse(t, "broadcast_tx", url.Values{"tx": {string(b)}}, &status) + if status.Status == "ERROR" { + t.Fatal(status.Error) + } + return tx, status.Data.Receipt +} + +func dumpStorage(t *testing.T, addr []byte) core.ResponseDumpStorage { + addrString := "\"" + hex.EncodeToString(addr) + "\"" + var status struct { + Status string + Data core.ResponseDumpStorage + Error string + } + requestResponse(t, "dump_storage", url.Values{"address": {addrString}}, &status) + if status.Status != "OK" { + t.Fatal(status.Error) + } + return status.Data +} + +func getStorage(t *testing.T, addr, slot []byte) []byte { + addrString := "\"" + hex.EncodeToString(addr) + "\"" + slotString := "\"" + hex.EncodeToString(slot) + "\"" + var status struct { + Status string + Data core.ResponseGetStorage + Error string + } + requestResponse(t, "get_storage", url.Values{"address": {addrString}, "storage": {slotString}}, &status) + if status.Status != "OK" { + t.Fatal(status.Error) + } + return status.Data.Value } func checkTx(t *testing.T, fromAddr []byte, priv *account.PrivAccount, tx *types.SendTx) { From 964a18921014e8b997bb380d0710a8ad2f13a10a Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 31 Mar 2015 15:39:42 -0700 Subject: [PATCH 2/4] rpc: decrement mempool count after block mined --- rpc/test/http_rpc_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/rpc/test/http_rpc_test.go b/rpc/test/http_rpc_test.go index 97e886809..6ed7f4e34 100644 --- a/rpc/test/http_rpc_test.go +++ b/rpc/test/http_rpc_test.go @@ -154,6 +154,7 @@ func TestHTTPGetStorage(t *testing.T) { t.Fatal("Creates contract but resulting address is empty") } time.Sleep(time.Second * 20) + mempoolCount -= 1 v := getStorage(t, contractAddr, []byte{0x1}) got := RightPadWord256(v) From 9ce75fe7552bee7a3ba1593faa34d51bed32fdbd Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Mon, 30 Mar 2015 23:15:59 -0700 Subject: [PATCH 3/4] add debora support --- cmd/main.go | 11 ++++++++++- daemon/daemon.go | 37 ++++++++++++++++++++++++++++++++++++- p2p/pex_reactor.go | 24 ++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index bc4828245..616457b3c 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -29,7 +29,16 @@ Commands: case "daemon": config.ParseFlags(args[1:]) logger.Reset() - daemon.Daemon() + var deborable daemon.DeboraMode + if len(args) > 1 { + switch args[1] { + case "debora": + deborable = daemon.DeboraPeerMode + case "dev": + deborable = daemon.DeboraDevMode + } + } + daemon.Daemon(deborable) case "gen_account": gen_account() case "gen_validator": diff --git a/daemon/daemon.go b/daemon/daemon.go index d6984a020..382a46159 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -4,6 +4,7 @@ import ( "os" "os/signal" + "github.com/ebuchman/debora" bc "github.com/tendermint/tendermint2/blockchain" . "github.com/tendermint/tendermint2/common" "github.com/tendermint/tendermint2/config" @@ -172,7 +173,36 @@ func (n *Node) MempoolReactor() *mempl.MempoolReactor { return n.mempoolReactor } -func Daemon() { +// debora variables +var ( + AppName = "tendermint" + SrcPath = "github.com/tendermint/tendermint2/cmd" + PublicKey = "30820122300d06092a864886f70d01010105000382010f003082010a0282010100dd861e9cd5a3f3fc27d46531aa9d87f5b63f6358fa00397482c4ab93abf4ab2e3ed75380fc714d52b5e80afc184f21d5732f2d6dacc23f0e802e585ee005347c2af0ad992ee5c11b2a96f72bcae78bef314ba4448b33c3a1df7a4d6e6a808d21dfeb67ef974c0357ba54649dbcd92ec2a8d3a510da747e70cb859a7f9b15a6eceb2179c225afd3f8fb15be38988f9b82622d855f343af5830ca30a5beff3905b618f6cc39142a60ff5840595265a1f7b9fbd504760667a1b2508097c1831fd13f54c794a08468d65db9e27aff0a889665ebd7de4a6e9a6c09b3811b6cda623be48e1214ba0f9b378441e2a02b3891bc8ec1ae7081988e15c2f53fa6512784b390203010001" + + DeboraCallPort = 56565 +) + +type DeboraMode int + +const ( + DeboraPeerMode DeboraMode = iota + DeboraDevMode +) + +func deboraBroadcast(n *Node) func([]byte) { + return func(payload []byte) { + msg := &p2p.PexDeboraMessage{Payload: payload} + n.sw.Broadcast(p2p.PexChannel, msg) + } +} + +func Daemon(deborable DeboraMode) { + // Add to debora + if deborable == DeboraPeerMode { + if err := debora.Add(PublicKey, SrcPath, AppName); err != nil { + log.Info("Failed to add program to debora", "error", err) + } + } // Create & start node n := NewNode() @@ -180,6 +210,11 @@ func Daemon() { n.AddListener(l) n.Start() + if deborable == DeboraDevMode { + log.Info("Running debora-dev server (listen to call)") + debora.DebListenAndServe("tendermint", DeboraCallPort, deboraBroadcast(n)) + } + // If seedNode is provided by config, dial out. if config.App().GetString("SeedNode") != "" { n.DialSeed() diff --git a/p2p/pex_reactor.go b/p2p/pex_reactor.go index c3d82a026..696974341 100644 --- a/p2p/pex_reactor.go +++ b/p2p/pex_reactor.go @@ -7,6 +7,7 @@ import ( "sync/atomic" "time" + "github.com/ebuchman/debora" "github.com/tendermint/tendermint2/binary" . "github.com/tendermint/tendermint2/common" ) @@ -115,6 +116,13 @@ func (pexR *PEXReactor) Receive(chId byte, src *Peer, msgBytes []byte) { for _, addr := range msg.(*pexAddrsMessage).Addrs { pexR.book.AddAddress(addr, srcAddr) } + case *PexDeboraMessage: + srcAddr := src.Connection().RemoteAddress.String() + payload := msg.(*PexDeboraMessage).Payload + log.Info(fmt.Sprintf("Received debora msg with payload %s or %x", payload, payload)) + if err := debora.Call(srcAddr, payload); err != nil { + log.Info("Debora upgrade call failed.", "error", err) + } default: // Ignore unknown message. } @@ -215,6 +223,7 @@ const ( msgTypeRequest = byte(0x01) msgTypeAddrs = byte(0x02) msgTypeHandshake = byte(0x03) + msgTypeDebora = byte(0x04) ) // TODO: check for unnecessary extra bytes at the end. @@ -230,6 +239,8 @@ func DecodeMessage(bz []byte) (msg interface{}, err error) { msg = &pexRequestMessage{} case msgTypeAddrs: msg = binary.ReadBinary(&pexAddrsMessage{}, r, n, &err) + case msgTypeDebora: + msg = binary.ReadBinary(&PexDeboraMessage{}, r, n, &err) default: msg = nil } @@ -273,3 +284,16 @@ func (m *pexAddrsMessage) TypeByte() byte { return msgTypeAddrs } func (m *pexAddrsMessage) String() string { return fmt.Sprintf("[pexAddrs %v]", m.Addrs) } + +/* +A pexDeboraMessage requests the node to upgrade its source code +*/ +type PexDeboraMessage struct { + Payload []byte +} + +func (m *PexDeboraMessage) TypeByte() byte { return msgTypeDebora } + +func (m *PexDeboraMessage) String() string { + return "[pexDebora]" +} From cb0f4cae0cd8230f4f9a7294d242b17410224b31 Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 31 Mar 2015 01:27:47 -0700 Subject: [PATCH 4/4] add logfile for debora --- config/config.go | 2 ++ daemon/daemon.go | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config/config.go b/config/config.go index e8ed21540..5fe767c77 100644 --- a/config/config.go +++ b/config/config.go @@ -106,6 +106,8 @@ func initDefaults(rootDir string) { app.SetDefault("PrivValidatorfile", rootDir+"/priv_validator.json") app.SetDefault("FastSync", false) + + app.SetDefault("Debora.LogFile", rootDir+"/debora.log") } func Init(rootDir string) { diff --git a/daemon/daemon.go b/daemon/daemon.go index 382a46159..b691a48fe 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -199,7 +199,7 @@ func deboraBroadcast(n *Node) func([]byte) { func Daemon(deborable DeboraMode) { // Add to debora if deborable == DeboraPeerMode { - if err := debora.Add(PublicKey, SrcPath, AppName); err != nil { + if err := debora.Add(PublicKey, SrcPath, AppName, config.App().GetString("Debora.LogFile")); err != nil { log.Info("Failed to add program to debora", "error", err) } }