Skip to content

Commit

Permalink
Merge pull request #73 from omisego/tx-get
Browse files Browse the repository at this point in the history
Tx-get
  • Loading branch information
Pongch authored Oct 14, 2019
2 parents 21c46de + 587094c commit c4038db
Show file tree
Hide file tree
Showing 11 changed files with 444 additions and 250 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff // indirect
github.com/golang/protobuf v1.3.2 // indirect
github.com/google/go-cmp v0.3.1 // indirect
github.com/hashicorp/golang-lru v0.5.1 // indirect
github.com/huin/goupnp v1.0.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.1 // indirect
Expand All @@ -37,4 +38,5 @@ require (
golang.org/x/text v0.3.2 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff // indirect
gotest.tools v2.2.0+incompatible
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
Expand Down Expand Up @@ -148,3 +150,5 @@ gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSv
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
23 changes: 18 additions & 5 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ var (
ownerUTXOAddress = get.Flag("address", "Owner address to search UTXOs").String()
getBalance = get.Command("balance", "Retrieve balance of an address from the Watcher service")
status = get.Command("status", "Get status from the Watcher")
transaction = get.Command("transaction", "get transaction details")
txHash = get.Flag("txhash", "transaction hash of the transaction you would like to get the information for").String()

getExit = get.Command("exit", "Get UTXO exit information")
getExitUTXOPosition = getExit.Flag("utxo", "Get UTXO exit information").Required().Int()
Expand All @@ -46,11 +48,11 @@ var (
send = kingpin.Command("send", "Create a transaction on the OmiseGO Plasma MoreVP network")
to = send.Flag("to", "Wallet address of the recipient").Required().String()
privatekey = send.Flag("privatekey", "Privatekey from a wallet to send from").Required().String()
amount = send.Flag("amount", "Amount to transact").Required().Uint()
amount = send.Flag("amount", "Amount to transact").Required().Uint64()
currency = send.Flag("currency", "currency of the amount to send, default to ETH").Default(plasma.EthCurrency).String()
watcherSubmitURL = send.Flag("watcher", "FQDN of the Watcher in the format http://watcher.path.net").Required().String()
feetoken = send.Flag("feetoken", "set the token to be used as transaction fee, default to ETH").Default(plasma.EthCurrency).String()
feeamount = send.Flag("feeamount", "set the amount to be used as transaction fee, default to 0").Default("0").Uint()
feeamount = send.Flag("feeamount", "set the amount to be used as transaction fee, default to 0").Default("0").Uint64()
metadata = send.Flag("metadata", "additional metadata to send with the transaction, up to 32 bytes").Default(plasma.DefaultMetadata).String()

exit = kingpin.Command("exit", "Standard exit a UTXO back to the root chain.")
Expand All @@ -69,7 +71,7 @@ var (
create = kingpin.Command("create", "Create a resource.")
createAccount = create.Command("account", "Create an account consisting of Public and Private key")

challengeexit = kingpin.Command("challengeexit", "Challenge an invalid exit on the root chain")
challengeexit = kingpin.Command("challenge exit", "Challenge an invalid exit on the root chain")
ceContract = challengeexit.Flag("contract", "Address of the Plasma MoreVP smart contract").Required().String()
ceClient = challengeexit.Flag("client", "Address of the Ethereum client. Infura and local node supported https://rinkeby.infura.io/v3/api_key or http://localhost:8545").Required().String()
cePrivateKey = challengeexit.Flag("privatekey", "Private key used to fund the gas for the smart contract call").Required().String()
Expand Down Expand Up @@ -105,7 +107,11 @@ func ParseArgs() {
plasma.DisplayBalance(balance)
case status.FullCommand():
//plamsa_cli get status --watcher=http://watcher.path.net
plasma.GetWatcherStatus(*watcherURL)
ws, err := plasma.GetWatcherStatus(*watcherURL)
if err != nil {
log.Error(err)
}
plasma.DisplayByzantineEvents(ws)
case deposit.FullCommand():
//plasma_cli deposit --privatekey=0x944A81BeECac91802787fBCFB9767FCBf81db1f5 --client=https://rinkeby.infura.io/v3/api_key --contract=0x457e2ec4ad356d3cb449e3bd4ba640d720c30377 --currency=ETH
d := plasma.PlasmaDeposit{PrivateKey: *privateKey, Client: *client, Contract: *contract, Amount: *depositAmount, Owner: *depositOwner, Currency: *depositCurrency}
Expand Down Expand Up @@ -134,7 +140,14 @@ func ParseArgs() {
signatures,
*watcherSubmitURL,
)
plasma.Submit(tx)
r, _ := plasma.Submit(tx)
plasma.DisplaySubmitResponse(r)
case transaction.FullCommand():
gtx, err := plasma.GetTransaction(*txHash, *watcherURL)
if err != nil {
log.Errorf("got error: %v", err)
}
plasma.DisplayGetResponse(gtx)
case exit.FullCommand():
//plasma_cli exit --utxo=1000000000 --privatekey=foo --contract=0x5bb7f2492487556e380e0bf960510277cdafd680 --watcher=ari.omg.network
s := plasma.StandardExit{UtxoPosition: util.ConvertStringToInt(*utxoPosition), Contract: *contractExit, PrivateKey: *exitPrivateKey, Client: *clientExit}
Expand Down
72 changes: 18 additions & 54 deletions plasma/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
package plasma

import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http"
"strings"
"math/big"

"github.com/omisego/plasma-cli/util"

log "github.com/sirupsen/logrus"
)
Expand All @@ -29,7 +29,7 @@ type WatcherUTXOsFromAddress struct {
Version string `json:"version"`
Success bool `json:"success"`
Data []struct {
UtxoPos int `json:"utxo_pos"`
UtxoPos *big.Int `json:"utxo_pos"`
Txindex int `json:"txindex"`
Owner string `json:"owner"`
Oindex int `json:"oindex"`
Expand Down Expand Up @@ -72,33 +72,15 @@ func DisplayBalance(b *WatcherBalanceFromAddress) {

// Retrieve the UTXOs associated with an address from the Watcher
func GetUTXOsFromAddress(address string, w string) (*WatcherUTXOsFromAddress, error) {
// Build request
var url strings.Builder
url.WriteString(w)
url.WriteString("/account.get_utxos")
postData := map[string]interface{}{"address": address, "limit": "10000"}
js, _ := json.Marshal(postData)
r, err := http.NewRequest("POST", url.String(), bytes.NewBuffer(js))
if err != nil {
return nil, err
}
r.Header.Add("Content-Type", "application/json")

// Make the request
client := &http.Client{}
resp, err := client.Do(r)
if err != nil {
return nil, err
}
defer resp.Body.Close()

// Unmarshall the response
postData := map[string]interface{}{"address": address, "limit": "10000"}
rstring, err := util.SendChChReq(
client,
w,
"/account.get_utxos",
postData,
)
response := WatcherUTXOsFromAddress{}

rstring, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
jsonErr := json.Unmarshal([]byte(rstring), &response)
if jsonErr != nil {
return nil, err
Expand All @@ -109,33 +91,15 @@ func GetUTXOsFromAddress(address string, w string) (*WatcherUTXOsFromAddress, er

// Get balance for a certain address
func GetBalance(address string, watcher string) (*WatcherBalanceFromAddress, error) {
// Build request
var url strings.Builder
url.WriteString(watcher)
url.WriteString("/account.get_balance")
postData := map[string]interface{}{"address": address}
js, _ := json.Marshal(postData)
r, err := http.NewRequest("POST", url.String(), bytes.NewBuffer(js))
if err != nil {
return nil, err
}
r.Header.Add("Content-Type", "application/json")

// Make the request
client := &http.Client{}
resp, err := client.Do(r)
if err != nil {
return nil, err
}
defer resp.Body.Close()

// Unmarshall the response
postData := map[string]interface{}{"address": address}
rstring, err := util.SendChChReq(
client,
watcher,
"/account.get_balance",
postData,
)
response := WatcherBalanceFromAddress{}

rstring, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
jsonErr := json.Unmarshal([]byte(rstring), &response)
if jsonErr != nil {
log.Warning("Could not unmarshal successful response from the Watcher")
Expand Down
33 changes: 30 additions & 3 deletions plasma/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"net/http"
"net/http/httptest"
"testing"
"math/big"
)

// Mock test server
Expand Down Expand Up @@ -50,7 +51,6 @@ func createMockServer(t *testing.T, rString string, url string, rStruct interfac
return ms
}


// Test getting balance for an account
func TestGetBalance(t *testing.T) {
rs := `{ "data": [ { "amount": 1000, "currency": "0x0000000000000000000000000000000000000000" } ], "success": true, "version": "0.2" }`
Expand Down Expand Up @@ -92,16 +92,24 @@ func TestGetBalanceWithExponent(t *testing.T) {
// Test getting UTXOs for an account
func TestGetUTXOs(t *testing.T) {
rs := `{ "data": [ { "amount": 123, "blknum": 1741002, "currency": "0x0000000000000000000000000000000000000000", "oindex": 0, "owner": "0x4522fb44c2ab359e76ecc75c22c9409690f12241", "txindex": 0, "utxo_pos": 1741002000000000 } ], "success": true, "version": "0.2" }`
expectedAmount := float64(123)
expectedUtxo := big.NewInt(1741002000000000)
ms := createMockServer(t, rs, "/account.get_utxos", WatcherUTXOsFromAddress{})
defer ms.Close()
_, err := GetUTXOsFromAddress("0x4522fb44c2ab359e76ecc75c22c9409690f12241", ms.URL)
balance, err := GetUTXOsFromAddress("0x4522fb44c2ab359e76ecc75c22c9409690f12241", ms.URL)
if err != nil {
t.Errorf("unexpected error from getting balance: %v", err)
}
if balance.Data[0].Amount != expectedAmount {
t.Errorf("unexpected utxo amount returned, expecting %v, got %v", expectedAmount, balance.Data[0].Amount)
}
if balance.Data[0].UtxoPos.Cmp(expectedUtxo) != 0 {
t.Errorf("unexpected utxo position returned, expecting %v, got %v", expectedUtxo, balance.Data[0].UtxoPos)
}
}

// Test getting UTXOs for an account with Exponent number
func TestGetUTXOsWithExponent (t *testing.T) {
func TestGetUTXOsWithExponent(t *testing.T) {
rs := `{ "data": [ { "amount": 1.949e+21, "blknum": 1741002, "currency": "0x0000000000000000000000000000000000000000", "oindex": 0, "owner": "0x4522fb44c2ab359e76ecc75c22c9409690f12241", "txindex": 0, "utxo_pos": 1741002000000000 } ], "success": true, "version": "0.2" }`
amountWanted := 1.949e+21
ms := createMockServer(t, rs, "/account.get_utxos", WatcherUTXOsFromAddress{})
Expand All @@ -115,3 +123,22 @@ func TestGetUTXOsWithExponent (t *testing.T) {
}
}

func TestGetUTXOsWithLargeUtxoPos(t *testing.T) {
rs := `{ "data": [ { "amount": 1.949e+21, "blknum": 1741002, "currency": "0x0000000000000000000000000000000000000000", "oindex": 0, "owner": "0x4522fb44c2ab359e76ecc75c22c9409690f12241", "txindex": 0, "utxo_pos": 1741002000000000100012344443 } ], "success": true, "version": "0.2" }`
amountWanted := 1.949e+21
utxoWanted, _ := new(big.Int).SetString("1741002000000000100012344443", 10)
ms := createMockServer(t, rs, "/account.get_utxos", WatcherUTXOsFromAddress{})
defer ms.Close()
res, err := GetUTXOsFromAddress("0x4522fb44c2ab359e76ecc75c22c9409690f12241", ms.URL)
if err != nil {
t.Errorf("unexpected error from getting balance: %v", err)
}
if amountWanted != res.Data[0].Amount {
t.Errorf("unexpected error, wanted amount %v, got %v", amountWanted, res.Data[0].Amount)
}

if utxoWanted.Cmp(res.Data[0].UtxoPos) != 0 {
t.Errorf("unexpected error, wanted amount %v, got %v", utxoWanted, res.Data[0].UtxoPos)
}
}

97 changes: 0 additions & 97 deletions plasma/plasma.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,28 +112,6 @@ type ChallengeUTXOData struct {
} `json:"data"`
}

type watcherStatus struct {
Version string `json:"version"`
Success bool `json:"success"`
Data struct {
LastValidatedChildBlockNumber int `json:"last_validated_child_block_number"`
LastMinedChildBlockTimestamp int `json:"last_mined_child_block_timestamp"`
LastMinedChildBlockNumber int `json:"last_mined_child_block_number"`
EthSyncing bool `json:"eth_syncing"`
ByzantineEvents []struct {
Event string `json:"event"`
Details struct{} `json:"details"`
} `json:"byzantine_events"`
} `json:"data"`
}

type ByzantineEvents struct {
piggyBack int
nonCanonical int
unchallengedExit int
invalidExit int
}

type watcherError struct {
Version string `json:"version"`
Success bool `json:"success"`
Expand All @@ -150,16 +128,6 @@ type inputDeposit struct {
Blknum uint `json:"blknum"`
}

type ExitDataUTXO struct {
Version string `json:"version"`
Success bool `json:"success"`
Data struct {
UtxoPos int64 `json:"utxo_pos"`
Txbytes string `json:"txbytes"`
Proof string `json:"proof"`
} `json:"data"`
}

// Start a standard exit from user provided UTXO & private key
func (s *StandardExit) StartStandardExit(watcher string) {
log.Info("Getting data needed to exit the UTXO from the Watcher")
Expand All @@ -170,70 +138,6 @@ func (s *StandardExit) StartStandardExit(watcher string) {
exit.StartStandardExit(s.Client, s.Contract, s.PrivateKey)
}

// Get the Watcher's status
func GetWatcherStatus(w string) {
var url strings.Builder
url.WriteString(w)
url.WriteString("/status.get")
r, err := http.NewRequest("POST", url.String(), nil)
if err != nil {
log.Fatal(err)
}
r.Header.Add("Content-Type", "application/json")

// Make the request
client := &http.Client{}
resp, err := client.Do(r)
if err != nil {
panic(err)
}
defer resp.Body.Close()

// Unmarshall the response
response := watcherStatus{}

rstring, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}

jsonErr := json.Unmarshal([]byte(rstring), &response)
if jsonErr != nil {
log.Error(jsonErr)
}
b := DisplayByzantineEvents(response)
log.Infof(
"Byzantine events:\n Invalid exits: %v, \n unchallenged exits: %v, \n Piggyback available: %v \n non-canonical ife: %v",
b.invalidExit,
b.unchallengedExit,
b.piggyBack,
b.nonCanonical,
)
log.Info("Last validated Childchain block number: ", response.Data.LastValidatedChildBlockNumber)
log.Info("Last mined Childchain block number: ", response.Data.LastMinedChildBlockNumber)
}

func DisplayByzantineEvents(b watcherStatus) ByzantineEvents {
var n int
var p int
var ue int
var ie int

for _, v := range b.Data.ByzantineEvents {
switch v.Event {
case "non_canonical_ife":
n++
case "piggyback_available":
p++
case "unchallenged_exit":
ue++
case "invalid_exit":
ie++
}
}
return ByzantineEvents{nonCanonical: n, piggyBack: p, unchallengedExit: ue, invalidExit: ie}
}

//Retrieve the UTXO exit data from the UTXO position
func GetUTXOExitData(watcher string, utxoPosition int) (StandardExitUTXOData, error) {
// Build request
Expand Down Expand Up @@ -273,7 +177,6 @@ func GetUTXOExitData(watcher string, utxoPosition int) (StandardExitUTXOData, er
return response, nil
}


// Start standard exit by calling the method in the smart contract
func (s *StandardExitUTXOData) StartStandardExit(ethereumClient string, contract string, private string) {
client, err := ethclient.Dial(ethereumClient)
Expand Down
Loading

0 comments on commit c4038db

Please sign in to comment.