Skip to content

Commit

Permalink
Adds time_cache for blockheight
Browse files Browse the repository at this point in the history
The cache is invalidated after time-to-live
  • Loading branch information
yashasvi-ranawat committed May 5, 2024
1 parent f1e17ed commit 1b5d185
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 5 deletions.
4 changes: 3 additions & 1 deletion bitcash/network/APIs/BitcoinDotComAPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
from decimal import Decimal
from bitcash.exceptions import InvalidEndpointURLProvided
from bitcash.network import currency_to_satoshi
from bitcash.network.APIs import BaseAPI
from bitcash.network.APIs import BaseAPI, DEFAULT_CACHE_TIME
from bitcash.network.meta import Unspent
from bitcash.network.transaction import Transaction, TxPart
from bitcash.format import cashtokenaddress_to_address
from bitcash.utils import time_cache

# This class is the interface for Bitcash to interact with
# Bitcoin.com based RESTful interfaces.
Expand Down Expand Up @@ -53,6 +54,7 @@ def get_default_endpoints(cls, network):
def make_endpoint_url(self, path):
return self.network_endpoint + self.PATHS[path]

@time_cache(DEFAULT_CACHE_TIME)
def get_blockheight(self, *args, **kwargs):
api_url = self.make_endpoint_url("block-height")
r = session.get(api_url)
Expand Down
4 changes: 3 additions & 1 deletion bitcash/network/APIs/ChaingraphAPI.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from bitcash.network.http import session
from bitcash.exceptions import InvalidEndpointURLProvided
from bitcash.network.APIs import BaseAPI
from bitcash.network.APIs import BaseAPI, DEFAULT_CACHE_TIME
from bitcash.network.meta import Unspent
from bitcash.network.transaction import Transaction, TxPart
from bitcash.cashaddress import Address
from bitcash.utils import time_cache


class ChaingraphAPI(BaseAPI):
Expand Down Expand Up @@ -56,6 +57,7 @@ def send_request(self, json_request, *args, **kwargs):
def get_default_endpoints(cls, network):
return cls.DEFAULT_ENDPOINTS[network]

@time_cache(DEFAULT_CACHE_TIME)
def get_blockheight(self, *args, **kwargs):
json_request = {
"query": """
Expand Down
4 changes: 4 additions & 0 deletions bitcash/network/APIs/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from abc import ABC, abstractmethod


# default cache time for the blockheigt retrieval
DEFAULT_CACHE_TIME = 120


class BaseAPI(ABC):
"""
Abstract class for API classes
Expand Down
35 changes: 35 additions & 0 deletions bitcash/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import decimal
import functools
import time
from binascii import hexlify


Expand Down Expand Up @@ -68,3 +70,36 @@ def varint_to_int(val):
if start_byte == b"\xfd":
return int.from_bytes(val.read(2), "little")
return int.from_bytes(start_byte, "little")


def time_cache(max_age):
"""
Timed cache decorator to store a value until time-to-live
:param max_age: Time, in seconds, untill when the value is invalidated.
"""

class ReturnValue:
def __init__(self, value, expiry):
self.value = value
self.expiry = expiry

def _decorator(fn):
@functools.cache
def cache_fn(*args, **kwargs):
value = fn(*args, **kwargs)
expiry = time.monotonic() + max_age
return ReturnValue(value, expiry)

@functools.wraps(fn)
def _wrapped(*args, **kwargs):
return_value = cache_fn(*args, **kwargs)
if return_value.expiry < time.monotonic():
# update the reference to the cache
return_value.value = fn(*args, **kwargs)
return_value.expiry = time.monotonic() + max_age
return return_value.value

return _wrapped

return _decorator
4 changes: 1 addition & 3 deletions tests/network/APIs/test_ChaingraphAPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ def test_get_blockheight(self):
return_json = {
"data": {
"block": [
{
"height": "123456"
},
{"height": "123456"},
]
}
}
Expand Down

0 comments on commit 1b5d185

Please sign in to comment.