Skip to content

Commit

Permalink
fix caching for fees table (#1113)
Browse files Browse the repository at this point in the history
* fix caching for fees table

* handle error

* conver to lowercase

* add logs

* use println logs

* use zboxcore/logger

* use toAddress

* revert logging

---------

Co-authored-by: Yury <yuderbasov@gmail.com>
  • Loading branch information
2 people authored and cnlangzi committed Jul 28, 2023
1 parent bbf85ad commit 62b25f3
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 90 deletions.
134 changes: 47 additions & 87 deletions core/transaction/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"sync"
"time"

"github.com/0chain/common/core/logging"
"github.com/0chain/errors"
"github.com/0chain/gosdk/core/common"
"github.com/0chain/gosdk/core/encryption"
Expand Down Expand Up @@ -288,114 +287,75 @@ type cachedObject struct {
Value interface{}
}

func retriveFromTable(table map[string]map[string]int64, txnName, toAddress string) (uint64, error) {
var fees uint64
if val, ok := table[toAddress]; ok {
fees = uint64(val[txnName])
} else {
if txnName == "transfer" {
fees = uint64(table["transfer"]["transfer"])
} else {
return 0, fmt.Errorf("invalid transaction")
}
}
return fees, nil
}

// EstimateFee estimates transaction fee
func EstimateFee(txn *Transaction, miners []string, reqPercent ...float32) (uint64, error) {

const minReqNum = 3
var reqN int

if len(reqPercent) > 0 {
reqN = int(reqPercent[0] * float32(len(miners)))
}

reqN = util.MaxInt(minReqNum, reqN)
reqN = util.MinInt(reqN, len(miners))
randomMiners := util.Shuffle(miners)[:reqN]
txData := txn.TransactionData

var (
feeC = make(chan uint64, reqN)
errC = make(chan error, reqN)
)

wg := &sync.WaitGroup{}
wg.Add(len(randomMiners))

for _, miner := range randomMiners {
go func(minerUrl string) {
defer wg.Done()
var sn SmartContractTxnData
err := json.Unmarshal([]byte(txData), &sn)
if err != nil {
return 0, err
}

// Retrieve the object from the cache
cached, ok := cache.Get(STORAGESC_CREATE_ALLOCATION)

if ok {
cachedObj, ok := cached.(*cachedObject)
if !ok {
logging.Logger.Error("Object of bad type")
return
}
val := cachedObj.Value.(map[string]interface{})["fee"].(uint64)
feeC <- uint64(val)
return
}
txnName := sn.Name
txnName = strings.ToLower(txnName)
toAddress := txn.ToClientID

url := minerUrl + ESTIMATE_TRANSACTION_COST
req, err := util.NewHTTPPostRequest(url, txn)
if err != nil {
errC <- fmt.Errorf("create request failed, url: %s, err: %v", url, err)
return
}
reqN = util.MaxInt(minReqNum, reqN)
reqN = util.MinInt(reqN, len(miners))
randomMiners := util.Shuffle(miners)[:reqN]

res, err := req.Post()
// Retrieve the object from the cache
cached, ok := cache.Get(FEES_TABLE)
if ok {
cachedObj, ok := cached.(*cachedObject)
if ok {
table := cachedObj.Value.(map[string]map[string]int64)
fees, err := retriveFromTable(table, txnName, toAddress)
if err != nil {
errC <- fmt.Errorf("request failed, url: %s, err: %v", url, err)
return
return 0, err
}

rspFee := struct {
Fee uint64 `json:"fee"`
}{}

if err := json.Unmarshal([]byte(res.Body), &rspFee); err != nil {
errC <- fmt.Errorf("decode response failed, url: %s, err: %v", url, err)
return
}

feeC <- rspFee.Fee
}(miner)
return fees, nil
}
}

// wait for requests to complete
wg.Wait()
close(feeC)
close(errC)

feesCount := make(map[uint64]int, reqN)
for fee := range feeC {
feesCount[fee]++
table, err := GetFeesTable(randomMiners, reqPercent...)
if err != nil {
return 0, err
}

if len(feesCount) > 0 {
var (
max int
fee uint64
)

for f, count := range feesCount {
if count > max {
max = count
fee = f
}
}

// adding response to cache
obj := map[string]interface{}{
"fee": fee,
}

cache.Add(STORAGESC_CREATE_ALLOCATION, &cachedObject{
Expiration: 30 * time.Hour,
Value: obj,
})

return fee, nil
fees, err := retriveFromTable(table, txnName, toAddress)
if err != nil {
return 0, err
}

errs := make([]string, 0, reqN)
for err := range errC {
errs = append(errs, err.Error())
}
cache.Add(FEES_TABLE, &cachedObject{
Expiration: 30 * time.Hour,
Value: table,
})

return 0, errors.New("failed to estimate transaction fee", strings.Join(errs, ","))
return fees, nil
}

// GetFeesTable get fee tables
Expand Down
3 changes: 2 additions & 1 deletion core/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
//====== THIS IS AUTOGENERATED FILE. DO NOT MODIFY ========

package version
const VERSIONSTR = "v1.8.16-95-ge79318e2"
const VERSIONSTR = "v1.8.16-114-g2b0a3484"


9 changes: 8 additions & 1 deletion wasmsdk/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ <h2>please download zcn.wasm from https://github.com/0chain/gosdk/releases/lates
<button id="btnListFiles">List</button>
<span><input id="inputSelectedFile" type="file" multiple /> <button id="btnUploadFile">Upload</button> </span>
<button id="btnUploadEncryptFile">EncryptedUpload</button> </span>
[ <button id="btnDownloadFile">Download</button> | <button id="btnDownloadShared">Download with AuthTicket</button> | <button id="btnMultiDownload">MultiDownload</button>
[ <button id="btnDownloadFile">Download</button> | <button id="btnDownloadShared">Download with AuthTicket</button>
| <button id="btnMultiDownload">MultiDownload</button>
]
<button id="btnViewFile">View</button>
<button id="btnGetFileStats">GetFileStats</button>
Expand All @@ -113,6 +114,7 @@ <h2>please download zcn.wasm from https://github.com/0chain/gosdk/releases/lates
<button id="btnSearchContainer">searchcontainer</button>
<button id="btnAllocationRepair">Repair</button>
<button id="btnMultiOps">MultiOperation</button>
<button id="createDir">createDir</button>

<br>

Expand Down Expand Up @@ -301,6 +303,11 @@ <h2>please download zcn.wasm from https://github.com/0chain/gosdk/releases/lates
}
})

onClick('createDir', async () => {
const allocationId = getSelectedAllocation()
goWasm.sdk.createDir(allocationId, "/dir2")
})

onClick('btnListBlobbers', async () => {
// list active blobbers
let blobbersResp = await getBlobbersFromNetwork()
Expand Down
2 changes: 1 addition & 1 deletion zcncore/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ func (t *Transaction) ExecuteSmartContract(address, methodName string, input int
}

func (t *Transaction) Send(toClientID string, val uint64, desc string) error {
txnData, err := json.Marshal(SendTxnData{Note: desc})
txnData, err := json.Marshal(transaction.SmartContractTxnData{Name: "transfer", InputArgs: SendTxnData{Note: desc}})
if err != nil {
return errors.New("", "Could not serialize description to transaction_data")
}
Expand Down

0 comments on commit 62b25f3

Please sign in to comment.