From f9809d75073dc42871ab0dda32f0a6768086ba5b Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Sat, 6 Oct 2018 23:35:03 +0200 Subject: [PATCH] Return inputs for socket.io getAddressHistory and getDetailedTransaction --- api/types.go | 33 ++--- api/worker.go | 4 + server/socketio.go | 267 ++++++++++++++++++---------------------- server/socketio_test.go | 171 +++++++++++-------------- static/test.html | 10 +- 5 files changed, 223 insertions(+), 262 deletions(-) diff --git a/api/types.go b/api/types.go index 32280427..98f52bfb 100644 --- a/api/types.go +++ b/api/types.go @@ -64,21 +64,24 @@ type Vout struct { } type Tx struct { - Txid string `json:"txid"` - Version int32 `json:"version,omitempty"` - Locktime uint32 `json:"locktime,omitempty"` - Vin []Vin `json:"vin"` - Vout []Vout `json:"vout"` - Blockhash string `json:"blockhash,omitempty"` - Blockheight int `json:"blockheight"` - Confirmations uint32 `json:"confirmations"` - Time int64 `json:"time,omitempty"` - Blocktime int64 `json:"blocktime"` - ValueOut string `json:"valueOut"` - Size int `json:"size,omitempty"` - ValueIn string `json:"valueIn"` - Fees string `json:"fees"` - Hex string `json:"hex"` + Txid string `json:"txid"` + Version int32 `json:"version,omitempty"` + Locktime uint32 `json:"locktime,omitempty"` + Vin []Vin `json:"vin"` + Vout []Vout `json:"vout"` + Blockhash string `json:"blockhash,omitempty"` + Blockheight int `json:"blockheight"` + Confirmations uint32 `json:"confirmations"` + Time int64 `json:"time,omitempty"` + Blocktime int64 `json:"blocktime"` + ValueOut string `json:"valueOut"` + ValueOutSat big.Int `json:"-"` + Size int `json:"size,omitempty"` + ValueIn string `json:"valueIn"` + ValueInSat big.Int `json:"-"` + Fees string `json:"fees"` + FeesSat big.Int `json:"-"` + Hex string `json:"hex"` } type Paging struct { diff --git a/api/worker.go b/api/worker.go index 2dd6cb89..1a4f5197 100644 --- a/api/worker.go +++ b/api/worker.go @@ -125,6 +125,7 @@ func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTxs bool vin.Txid = bchainVin.Txid vin.N = i vin.Vout = bchainVin.Vout + vin.Sequence = int64(bchainVin.Sequence) vin.ScriptSig.Hex = bchainVin.ScriptSig.Hex // bchainVin.Txid=="" is coinbase transaction if bchainVin.Txid != "" { @@ -200,11 +201,14 @@ func (w *Worker) GetTransaction(txid string, bestheight uint32, spendingTxs bool Blocktime: bchainTx.Blocktime, Confirmations: bchainTx.Confirmations, Fees: w.chainParser.AmountToDecimalString(&feesSat), + FeesSat: feesSat, Locktime: bchainTx.LockTime, Time: bchainTx.Time, Txid: bchainTx.Txid, ValueIn: w.chainParser.AmountToDecimalString(&valInSat), + ValueInSat: valInSat, ValueOut: w.chainParser.AmountToDecimalString(&valOutSat), + ValueOutSat: valOutSat, Version: bchainTx.Version, Hex: bchainTx.Hex, Vin: vins, diff --git a/server/socketio.go b/server/socketio.go index c4242e9b..2d610157 100644 --- a/server/socketio.go +++ b/server/socketio.go @@ -6,6 +6,7 @@ import ( "blockbook/common" "blockbook/db" "encoding/json" + "math/big" "net/http" "strconv" "strings" @@ -27,10 +28,16 @@ type SocketIoServer struct { chainParser bchain.BlockChainParser metrics *common.Metrics is *common.InternalState + api *api.Worker } // NewSocketIoServer creates new SocketIo interface to blockbook and returns its handle func NewSocketIoServer(db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCache, metrics *common.Metrics, is *common.InternalState) (*SocketIoServer, error) { + api, err := api.NewWorker(db, chain, txCache, is) + if err != nil { + return nil, err + } + server := gosocketio.NewServer(transport.GetDefaultWebsocketTransport()) server.On(gosocketio.OnConnection, func(c *gosocketio.Channel) { @@ -59,6 +66,7 @@ func NewSocketIoServer(db *db.RocksDB, chain bchain.BlockChain, txCache *db.TxCa chainParser: chain.GetChainParser(), metrics: metrics, is: is, + api: api, } server.On("message", s.onMessage) @@ -244,33 +252,33 @@ type txOutputs struct { Satoshis int64 `json:"satoshis"` Script *string `json:"script"` // ScriptAsm *string `json:"scriptAsm"` - SpentTxID *string `json:"spentTxId,omitempty"` - SpentIndex int `json:"spentIndex,omitempty"` - SpentHeight int `json:"spentHeight,omitempty"` - Address *string `json:"address"` + // SpentTxID *string `json:"spentTxId,omitempty"` + // SpentIndex int `json:"spentIndex,omitempty"` + // SpentHeight int `json:"spentHeight,omitempty"` + Address *string `json:"address"` } type resTx struct { Hex string `json:"hex"` // BlockHash string `json:"blockHash,omitempty"` - Height int `json:"height"` - BlockTimestamp int64 `json:"blockTimestamp,omitempty"` - // Version int `json:"version"` - Hash string `json:"hash"` - Locktime int `json:"locktime,omitempty"` + Height int `json:"height"` + BlockTimestamp int64 `json:"blockTimestamp,omitempty"` + Version int `json:"version"` + Hash string `json:"hash"` + Locktime int `json:"locktime,omitempty"` // Size int `json:"size,omitempty"` - Inputs []txInputs `json:"inputs"` - // InputSatoshis int64 `json:"inputSatoshis,omitempty"` - Outputs []txOutputs `json:"outputs"` - // OutputSatoshis int64 `json:"outputSatoshis,omitempty"` - // FeeSatoshis int64 `json:"feeSatoshis,omitempty"` + Inputs []txInputs `json:"inputs"` + InputSatoshis int64 `json:"inputSatoshis,omitempty"` + Outputs []txOutputs `json:"outputs"` + OutputSatoshis int64 `json:"outputSatoshis,omitempty"` + FeeSatoshis int64 `json:"feeSatoshis,omitempty"` } type addressHistoryItem struct { - Addresses map[string]addressHistoryIndexes `json:"addresses"` - Satoshis int64 `json:"satoshis"` - Confirmations int `json:"confirmations"` - Tx resTx `json:"tx"` + Addresses map[string]*addressHistoryIndexes `json:"addresses"` + Satoshis int64 `json:"satoshis"` + Confirmations int `json:"confirmations"` + Tx resTx `json:"tx"` } type resultGetAddressHistory struct { @@ -289,20 +297,55 @@ func stringInSlice(a string, list []string) bool { return false } -func txToResTx(tx *bchain.Tx, height int, hi []txInputs, ho []txOutputs) resTx { +func txToResTx(tx *api.Tx) resTx { + inputs := make([]txInputs, len(tx.Vin)) + for i := range tx.Vin { + vin := &tx.Vin[i] + script := vin.ScriptSig.Hex + input := txInputs{ + Script: &script, + Sequence: int64(vin.Sequence), + OutputIndex: int(vin.Vout), + Satoshis: vin.ValueSat.Int64(), + } + if len(vin.Addresses) > 0 { + a := vin.Addresses[0] + input.Address = &a + } + inputs[i] = input + } + outputs := make([]txOutputs, len(tx.Vout)) + for i := range tx.Vout { + vout := &tx.Vout[i] + script := vout.ScriptPubKey.Hex + output := txOutputs{ + Satoshis: vout.ValueSat.Int64(), + Script: &script, + } + if len(vout.ScriptPubKey.Addresses) > 0 { + a := vout.ScriptPubKey.Addresses[0] + output.Address = &a + } + outputs[i] = output + } + var h int + if tx.Confirmations == 0 { + h = -1 + } else { + h = int(tx.Blockheight) + } return resTx{ - // BlockHash: tx.BlockHash, BlockTimestamp: tx.Blocktime, - // FeeSatoshis, - Hash: tx.Txid, - Height: height, - Hex: tx.Hex, - Inputs: hi, - // InputSatoshis, - Locktime: int(tx.LockTime), - Outputs: ho, - // OutputSatoshis, - // Version: int(tx.Version), + FeeSatoshis: tx.FeesSat.Int64(), + Hash: tx.Txid, + Height: h, + Hex: tx.Hex, + Inputs: inputs, + InputSatoshis: tx.ValueInSat.Int64(), + Locktime: int(tx.Locktime), + Outputs: outputs, + OutputSatoshis: tx.ValueOutSat.Int64(), + Version: int(tx.Version), } } @@ -341,54 +384,53 @@ func (s *SocketIoServer) getAddressHistory(addr []string, opts *addrOpts) (res r txids := txr.Result res.Result.TotalCount = len(txids) res.Result.Items = make([]addressHistoryItem, 0) - for i, txid := range txids { - if i >= opts.From && i < opts.To { - tx, height, err := s.txCache.GetTransaction(txid, bestheight) - if err != nil { - return res, err - } - ads := make(map[string]addressHistoryIndexes) - hi := make([]txInputs, 0) - ho := make([]txOutputs, 0) - for _, vout := range tx.Vout { - aoh := vout.ScriptPubKey.Hex - ao := txOutputs{ - Satoshis: vout.ValueSat.Int64(), - Script: &aoh, - } - voutAddr, err := s.getAddressesFromVout(&vout) - if err != nil { - return res, err - } - if len(voutAddr) > 0 { - ao.Address = &voutAddr[0] - } - a := addressInSlice(voutAddr, addr) - if a != "" { - hi, ok := ads[a] - if ok { - hi.OutputIndexes = append(hi.OutputIndexes, int(vout.N)) - } else { - hi := addressHistoryIndexes{} - hi.InputIndexes = make([]int, 0) - hi.OutputIndexes = append(hi.OutputIndexes, int(vout.N)) - ads[a] = hi - } - } - ho = append(ho, ao) - } - ahi := addressHistoryItem{} - ahi.Addresses = ads - ahi.Confirmations = int(tx.Confirmations) - var h int - if tx.Confirmations == 0 { - h = -1 - } else { - h = int(height) - } - ahi.Tx = txToResTx(tx, h, hi, ho) - res.Result.Items = append(res.Result.Items, ahi) + to := len(txids) + if to > opts.To { + to = opts.To + } + for txi := opts.From; txi < to; txi++ { + tx, err := s.api.GetTransaction(txids[txi], bestheight, false) + // for i, txid := range txids { + // if i >= opts.From && i < opts.To { + // tx, err := s.api.GetTransaction(txid, bestheight, false) + if err != nil { + return res, err } + ads := make(map[string]*addressHistoryIndexes) + var totalSat big.Int + for i := range tx.Vin { + vin := &tx.Vin[i] + a := addressInSlice(vin.Addresses, addr) + if a != "" { + hi := ads[a] + if hi == nil { + hi = &addressHistoryIndexes{OutputIndexes: []int{}} + ads[a] = hi + } + hi.InputIndexes = append(hi.InputIndexes, int(vin.N)) + totalSat.Sub(&totalSat, &vin.ValueSat) + } + } + for i := range tx.Vout { + vout := &tx.Vout[i] + a := addressInSlice(vout.ScriptPubKey.Addresses, addr) + if a != "" { + hi := ads[a] + if hi == nil { + hi = &addressHistoryIndexes{InputIndexes: []int{}} + ads[a] = hi + } + hi.OutputIndexes = append(hi.OutputIndexes, int(vout.N)) + totalSat.Add(&totalSat, &vout.ValueSat) + } + } + ahi := addressHistoryItem{} + ahi.Addresses = ads + ahi.Confirmations = int(tx.Confirmations) + ahi.Satoshis = totalSat.Int64() + ahi.Tx = txToResTx(tx) + res.Result.Items = append(res.Result.Items, ahi) + // } } return } @@ -594,78 +636,11 @@ func (s *SocketIoServer) getDetailedTransaction(txid string) (res resultGetDetai if err != nil { return } - tx, height, err := s.txCache.GetTransaction(txid, bestheight) + tx, err := s.api.GetTransaction(txid, bestheight, false) if err != nil { return res, err } - hi := make([]txInputs, 0) - ho := make([]txOutputs, 0) - for _, vin := range tx.Vin { - ais := vin.ScriptSig.Hex - ai := txInputs{ - Script: &ais, - Sequence: int64(vin.Sequence), - OutputIndex: int(vin.Vout), - } - if vin.Txid != "" { - var voutAddr []string - // load spending addresses from TxAddresses - ta, err := s.db.GetTxAddresses(vin.Txid) - if err != nil { - return res, err - } - if ta == nil { - // the tx may be in mempool, try to load it from backend - otx, _, err := s.txCache.GetTransaction(vin.Txid, bestheight) - if err != nil { - return res, err - } - if len(otx.Vout) > int(vin.Vout) { - vout := &otx.Vout[vin.Vout] - voutAddr, err = s.getAddressesFromVout(vout) - if err != nil { - return res, err - } - ai.Satoshis = vout.ValueSat.Int64() - } - } else { - if len(ta.Outputs) > int(vin.Vout) { - output := &ta.Outputs[vin.Vout] - ai.Satoshis = output.ValueSat.Int64() - voutAddr, _, err = output.Addresses(s.chainParser) - if err != nil { - return res, err - } - } - } - if len(voutAddr) > 0 { - ai.Address = &voutAddr[0] - } - } - hi = append(hi, ai) - } - for _, vout := range tx.Vout { - aos := vout.ScriptPubKey.Hex - ao := txOutputs{ - Satoshis: vout.ValueSat.Int64(), - Script: &aos, - } - voutAddr, err := s.getAddressesFromVout(&vout) - if err != nil { - return res, err - } - if len(voutAddr) > 0 { - ao.Address = &voutAddr[0] - } - ho = append(ho, ao) - } - var h int - if tx.Confirmations == 0 { - h = -1 - } else { - h = int(height) - } - res.Result = txToResTx(tx, h, hi, ho) + res.Result = txToResTx(tx) return } diff --git a/server/socketio_test.go b/server/socketio_test.go index 09f2d368..71406336 100644 --- a/server/socketio_test.go +++ b/server/socketio_test.go @@ -1,4 +1,4 @@ -// +build integration +// build integration package server @@ -8,6 +8,7 @@ import ( "encoding/json" "flag" "os" + "reflect" "sort" "strings" "testing" @@ -94,16 +95,74 @@ func getFullAddressHistory(addr []string, rr addrOpts, ws *gosocketio.Client) (* return &bbResponse, nil } -func equalAddressHistoryItem(logItem addressHistoryItem, bbItem addressHistoryItem) error { - if logItem.Tx.Hash != bbItem.Tx.Hash { - return errors.Errorf("Different hash bb: %v log: %v", bbItem.Tx.Hash, logItem.Tx.Hash) +func equalTx(logTx resTx, bbTx resTx) error { + if logTx.Hash != bbTx.Hash { + return errors.Errorf("Different Hash bb: %v log: %v", bbTx.Hash, logTx.Hash) } - if logItem.Tx.Hex != bbItem.Tx.Hex { - return errors.Errorf("Different hex bb: %v log: %v", bbItem.Tx.Hex, logItem.Tx.Hex) + if logTx.Hex != bbTx.Hex { + return errors.Errorf("Different Hex bb: %v log: %v", bbTx.Hex, logTx.Hex) + } + if logTx.BlockTimestamp != bbTx.BlockTimestamp { + return errors.Errorf("Different BlockTimestamp bb: %v log: %v", bbTx.BlockTimestamp, logTx.BlockTimestamp) + } + if logTx.FeeSatoshis != bbTx.FeeSatoshis { + return errors.Errorf("Different FeeSatoshis bb: %v log: %v", bbTx.FeeSatoshis, logTx.FeeSatoshis) + } + if logTx.Height != bbTx.Height { + return errors.Errorf("Different Height bb: %v log: %v", bbTx.Height, logTx.Height) + } + if logTx.InputSatoshis != bbTx.InputSatoshis { + return errors.Errorf("Different InputSatoshis bb: %v log: %v", bbTx.InputSatoshis, logTx.InputSatoshis) + } + if logTx.Locktime != bbTx.Locktime { + return errors.Errorf("Different Locktime bb: %v log: %v", bbTx.Locktime, logTx.Locktime) + } + if logTx.OutputSatoshis != bbTx.OutputSatoshis { + return errors.Errorf("Different OutputSatoshis bb: %v log: %v", bbTx.OutputSatoshis, logTx.OutputSatoshis) + } + if logTx.Version != bbTx.Version { + return errors.Errorf("Different Version bb: %v log: %v", bbTx.Version, logTx.Version) + } + if len(logTx.Inputs) != len(bbTx.Inputs) { + return errors.Errorf("Different number of Inputs bb: %v log: %v", len(bbTx.Inputs), len(logTx.Inputs)) + } + // blockbook parses bech addresses, it is ok for bitcore to return nil address and blockbook parsed address + for i := range logTx.Inputs { + if logTx.Inputs[i].Satoshis != bbTx.Inputs[i].Satoshis || + (bbTx.Inputs[i].Address == nil && logTx.Inputs[i].Address != bbTx.Inputs[i].Address) || + (logTx.Inputs[i].Address != nil && *logTx.Inputs[i].Address != *bbTx.Inputs[i].Address) || + logTx.Inputs[i].OutputIndex != bbTx.Inputs[i].OutputIndex || + logTx.Inputs[i].Sequence != bbTx.Inputs[i].Sequence { + return errors.Errorf("Different Inputs bb: %+v log: %+v", bbTx.Inputs, logTx.Inputs) + } + } + if len(logTx.Outputs) != len(bbTx.Outputs) { + return errors.Errorf("Different number of Outputs bb: %v log: %v", len(bbTx.Outputs), len(logTx.Outputs)) + } + // blockbook parses bech addresses, it is ok for bitcore to return nil address and blockbook parsed address + for i := range logTx.Outputs { + if logTx.Outputs[i].Satoshis != bbTx.Outputs[i].Satoshis || + (bbTx.Outputs[i].Address == nil && logTx.Outputs[i].Address != bbTx.Outputs[i].Address) || + (logTx.Outputs[i].Address != nil && *logTx.Outputs[i].Address != *bbTx.Outputs[i].Address) { + return errors.Errorf("Different Outputs bb: %+v log: %+v", bbTx.Outputs, logTx.Outputs) + } } - // Addresses do not match, bb getAddressHistory does not return input addresses return nil } + +func equalAddressHistoryItem(logItem addressHistoryItem, bbItem addressHistoryItem) error { + if err := equalTx(logItem.Tx, bbItem.Tx); err != nil { + return err + } + if !reflect.DeepEqual(logItem.Addresses, bbItem.Addresses) { + return errors.Errorf("Different Addresses bb: %v log: %v", bbItem.Addresses, logItem.Addresses) + } + if logItem.Satoshis != bbItem.Satoshis { + return errors.Errorf("Different Satoshis bb: %v log: %v", bbItem.Satoshis, logItem.Satoshis) + } + return nil +} + func verifyGetAddressHistory(t *testing.T, id int, lrs *logRequestResponse, bbResStr string, stat *verifyStats, ws *gosocketio.Client, bbRequest map[string]json.RawMessage) { bbResponse := resultGetAddressHistory{} logResponse := resultGetAddressHistory{} @@ -146,16 +205,17 @@ func verifyGetAddressHistory(t *testing.T, id int, lrs *logRequestResponse, bbRe } found := false for _, bbFullItem := range bbFullResponse.Result.Items { - if err1 = equalAddressHistoryItem(logItem, bbFullItem); err1 == nil { + err1 = equalAddressHistoryItem(logItem, bbFullItem) + if err1 == nil { found = true break } + if err1.Error()[:14] != "Different Hash" { + t.Log(err1) + } } if !found { t.Log("getAddressHistory", id, "addresses", addr, "mismatch ", err) - // bf, _ := json.Marshal(bbFullResponse.Result) - // bl, _ := json.Marshal(logResponse.Result) - // t.Log("{ \"bf\":", string(bf), ",\"bl\":", string(bl), "}") return } } @@ -237,94 +297,7 @@ func verifyGetDetailedTransaction(t *testing.T, id int, lrs *logRequestResponse, if err := unmarshalResponses(t, id, lrs, bbResStr, &bbResponse, &logResponse); err != nil { return } - equalInputs := func() error { - if len(bbResponse.Result.Inputs) != len(logResponse.Result.Inputs) { - return errors.Errorf("mismatch number of inputs %v %v", len(bbResponse.Result.Inputs), len(logResponse.Result.Inputs)) - } - for i, bbi := range bbResponse.Result.Inputs { - li := logResponse.Result.Inputs[i] - - if bbi.OutputIndex != li.OutputIndex || - bbi.Sequence != li.Sequence || - bbi.Satoshis != li.Satoshis { - return errors.Errorf("mismatch input %v %v, %v %v, %v %v", bbi.OutputIndex, li.OutputIndex, bbi.Sequence, li.Sequence, bbi.Satoshis, li.Satoshis) - } - // both must be null or both must not be null - if bbi.Address != nil && li.Address != nil { - if *bbi.Address != *li.Address { - return errors.Errorf("mismatch input Address %v %v", *bbi.Address, *li.Address) - } - } else if bbi.Address != li.Address { - // bitcore does not parse bech P2WPKH and P2WSH addresses - if bbi.Address == nil || (*bbi.Address)[0:3] != "bc1" { - return errors.Errorf("mismatch input Address %v %v", bbi.Address, li.Address) - } - } - // both must be null or both must not be null - if bbi.Script != nil && li.Script != nil { - if *bbi.Script != *li.Script { - return errors.Errorf("mismatch input Script %v %v", *bbi.Script, *li.Script) - } - } else if bbi.Script != li.Script { - return errors.Errorf("mismatch input Script %v %v", bbi.Script, li.Script) - } - } - return nil - } - equalOutputs := func() error { - if len(bbResponse.Result.Outputs) != len(logResponse.Result.Outputs) { - return errors.Errorf("mismatch number of outputs %v %v", len(bbResponse.Result.Outputs), len(logResponse.Result.Outputs)) - } - for i, bbo := range bbResponse.Result.Outputs { - lo := logResponse.Result.Outputs[i] - if bbo.Satoshis != lo.Satoshis { - return errors.Errorf("mismatch output Satoshis %v %v", bbo.Satoshis, lo.Satoshis) - } - // both must be null or both must not be null - if bbo.Script != nil && lo.Script != nil { - if *bbo.Script != *lo.Script { - return errors.Errorf("mismatch output Script %v %v", *bbo.Script, *lo.Script) - } - } else if bbo.Script != lo.Script { - return errors.Errorf("mismatch output Script %v %v", bbo.Script, lo.Script) - } - // both must be null or both must not be null - if bbo.Address != nil && lo.Address != nil { - if *bbo.Address != *lo.Address { - return errors.Errorf("mismatch output Address %v %v", *bbo.Address, *lo.Address) - } - } else if bbo.Address != lo.Address { - // bitcore does not parse bech P2WPKH and P2WSH addresses - if bbo.Address == nil || (*bbo.Address)[0:3] != "bc1" { - return errors.Errorf("mismatch output Address %v %v", bbo.Address, lo.Address) - } - } - } - return nil - } - // the tx in the log could have been still in mempool with Height -1 - if (bbResponse.Result.Height != logResponse.Result.Height && logResponse.Result.Height != -1) || - bbResponse.Result.Hash != logResponse.Result.Hash { - t.Log("getDetailedTransaction", id, "mismatch bb:", bbResponse.Result.Hash, bbResponse.Result.Height, - "log:", logResponse.Result.Hash, logResponse.Result.Height) - return - } - // the tx in the log could have been still in mempool with BlockTimestamp 0 - if bbResponse.Result.BlockTimestamp != logResponse.Result.BlockTimestamp && logResponse.Result.BlockTimestamp != 0 { - t.Log("getDetailedTransaction", id, "mismatch BlockTimestamp:", bbResponse.Result.BlockTimestamp, - "log:", logResponse.Result.BlockTimestamp) - return - } - if bbResponse.Result.Hex != logResponse.Result.Hex { - t.Log("getDetailedTransaction", id, "mismatch Hex:", bbResponse.Result.Hex, - "log:", logResponse.Result.Hex) - return - } - if err := equalInputs(); err != nil { - t.Log("getDetailedTransaction", id, err) - return - } - if err := equalOutputs(); err != nil { + if err := equalTx(logResponse.Result, bbResponse.Result); err != nil { t.Log("getDetailedTransaction", id, err) return } diff --git a/static/test.html b/static/test.html index e5e0789f..b12ebc4d 100644 --- a/static/test.html +++ b/static/test.html @@ -55,7 +55,9 @@ var addresses = document.getElementById('getAddressHistoryAddresses').value.split(","); addresses = addresses.map(s => s.trim()); var mempool = document.getElementById("getAddressHistoryMempool").checked; - lookupAddressHistories(addresses, 0, 5, mempool, 20000000, 0, function (result) { + var from = parseInt(document.getElementById("getAddressHistoryFrom").value); + var to = parseInt(document.getElementById("getAddressHistoryTo").value); + lookupAddressHistories(addresses, from, to, mempool, 90000000, 0, function (result) { console.log('getAddressHistory sent successfully'); console.log(result); document.getElementById('getAddressHistoryResult').innerText = JSON.stringify(result).replace(/,/g, ", "); @@ -283,7 +285,11 @@
- +
+ + + +