text:
# -*- coding: utf-8 -*-
import logging
import re
import urllib
import urllib2 as default_urllib2
import httplib as default_httplib
import traceback

from facegraph.url_operations import (add_path, get_host,
        add_query_params, update_query_params, get_path)

import bunch
import ujson as json
from functools import partial

p = "^\(#(\d+)\)"
code_re = re.compile(p)

__all__ = ['Graph']

log = logging.getLogger('pyfacegraph')

class Graph(object):

    """
    Proxy for accessing the Facebook Graph API.

    This class uses dynamic attribute handling to provide a flexible and
    future-proof interface to the Graph API.

    Tutorial
    ========

    To get started using the API, create a new `Graph` instance with an access
    token:

        >>> g = Graph(access_token)  # Access token is optional.
        >>> g
        <Graph('https://graph.facebook.com/') at 0x...>

    Addressing Nodes
    ----------------

    Each `Graph` contains an access token and a URL. The graph you just created
    will have its URL set to 'https://graph.facebook.com/' by default (this is
    defined as the class attribute `Graph.API_ROOT`).

        >>> print g.url
        https://graph.facebook.com/

    To address child nodes within the Graph API, `Graph` supports dynamic
    attribute and item lookups:

        >>> g.me
        <Graph('https://graph.facebook.com/me') at 0x...>
        >>> g.me.home
        <Graph('https://graph.facebook.com/me/home') at 0x...>
        >>> g['me']['home']
        <Graph('https://graph.facebook.com/me/home') at 0x...>
        >>> g[123456789]
        <Graph('https://graph.facebook.com/123456789') at 0x...>

    Note that a `Graph` instance is rarely modified; these methods return copies
    of the original object. In addition, the API is lazy: HTTP requests will
    never be made unless you explicitly make them.

    Retrieving Nodes
    ----------------

    You can fetch data by calling a `Graph` instance:

        >>> about_me = g.me()
        >>> about_me
        Node({'about': '...', 'id': '1503223370'})

    This returns a `Node` object, which contains the retrieved data. `Node` is
    a subclass of `bunch.Bunch`, so you can access keys using attribute syntax:

        >>> about_me.id
        '1503223370'
        >>> about_me.first_name
        'Zachary'
        >>> about_me.hometown.name
        'London, United Kingdom'

    Accessing non-existent attributes or items will return a `Graph` instance
    corresponding to a child node. This `Graph` can then be called normally, to
    retrieve the child node it represents:

        >>> about_me.home
        <Graph('https://graph.facebook.com/me/home') at 0x...>
        >>> about_me.home()
        Node({'data': [...]})

    See `Node`’s documentation for further examples.

    Creating, Updating and Deleting Nodes
    -------------------------------------

    With the Graph API, node manipulation is done via HTTP POST requests. The
    `post()` method on `Graph` instances will POST to the current URL, with
    varying semantics for each endpoint:

        >>> post = g.me.feed.post(message="Test.")  # Status update
        >>> post
        Node({'id': '...'})
        >>> g[post.id].comments.post(message="A comment.") # Comment on the post
        Node({'id': '...'})
        >>> g[post.id].likes.post()  # Like the post
        True

        >>> event = g[121481007877204]()
        >>> event.name
        'Facebook Developer Garage London May 2010'
        >>> event.rsvp_status is None
        True
        >>> event.attending.post()  # Attend the given event
        True

    Deletes are just POST requests with `?method=delete`; the `delete()` method
    is a helpful shortcut:

        >>> g[post.id].delete()
        True

    """

    API_ROOT = 'https://graph.facebook.com/'
    DEFAULT_TIMEOUT = 0 # No timeout as default

    def __init__(self, access_token=None, err_handler=None, timeout=DEFAULT_TIMEOUT, retries=5, urllib2=None, httplib=None, **state):
        self.access_token = access_token
        self.err_handler = err_handler
        self.url = self.API_ROOT
        self.timeout = timeout
        self.retries = retries
        self.__dict__.update(state)
        if urllib2 is None:
            import urllib2
        self.urllib2 = urllib2
        if httplib is None:
            import httplib
        self.httplib = httplib

    def __repr__(self):
        return '<Graph(%r) at 0x%x>' % (self.url, id(self))

    def copy(self, **update):
        """Copy this Graph, optionally overriding some attributes."""
        return type(self)(access_token=self.access_token,
                          err_handler=self.err_handler,
                          timeout=self.timeout,
                          retries=self.retries,
                          urllib2=self.urllib2,
                          httplib=self.httplib,
                          **update)

    def __getitem__(self, item):
        if isinstance(item, slice):
            log.debug('Deprecated magic slice!')
            log.debug( traceback.format_stack())
            return self._range(item.start, item.stop)
        return self.copy(url=add_path(self.url, unicode(item)))

    def __getattr__(self, attr):
        return self[attr]

    def _range(self, start, stop):
        params = {'offset': start,
                  'limit': stop - start}
        return self.copy(url=add_query_params(self.url, params))

    def with_url_params(self, param, val):
        """
            this used to overload the bitwise OR op
        """
        return self.copy(url=update_query_params(self.url, (param, val)))

    def __call__(self, **params):
        log.debug('Deprecated magic call!')
        log.debug( traceback.format_stack())
        return self.call_fb(**params)

    def call_fb(self, **params):
        """Read the current URL, and JSON-decode the results."""

        if self.access_token:
            params['access_token'] = self.access_token
        url = update_query_params(self.url, params)
        data = json.loads(self.fetch(url,
                                     timeout=self.timeout,
                                     retries=self.retries,
                                     urllib2=self.urllib2,
                                     httplib=self.httplib))
        return self.process_response(data, params)

    def __iter__(self):
        raise TypeError('%r object is not iterable' % self.__class__.__name__)

    def __sentry__(self):
        return 'Graph(url: %s, params: %s)' % (self.url, repr(self.__dict__))

    def fields(self, *fields):
        """Shortcut for `?fields=x,y,z`."""
        return self | ('fields', ','.join(fields))

    def ids(self, *ids):
        """Shortcut for `?ids=1,2,3`."""

        return self | ('ids', ','.join(map(str, ids)))

    def process_response(self, data, params, method=None):
        if isinstance(data, dict):
            if data.get("error"):
                code = data["error"].get("code")
                if code is None:
                    code = data["error"].get("error_code")
                msg = data["error"].get("message")
                if msg is None:
                    msg = data["error"].get("error_msg")
                if code is None:
                    code_match = code_re.match(msg)
                    if code_match is not None:
                        code = int(code_match.group(1))
                e = GraphException(code, msg, graph=self, params=params, method=method)
                if self.err_handler:
                    return self.err_handler(e=e)
                else:
                    raise e
            return bunch.bunchify(data)
        return data

    def post(self, **params):
        """
        POST to this URL (with parameters); return the JSON-decoded result.

        Example:

            >>> Graph('ACCESS TOKEN').me.feed.post(message="Test.")
            Node({'id': '...'})

        Some methods allow file attachments so uses MIME request to send those through.
        Must pass in a file object as 'file'
        """

        if self.access_token:
            params['access_token'] = self.access_token

        if get_path(self.url).split('/')[-1] in ['photos']:
            params['timeout'] = self.timeout
            params['httplib'] = self.httplib
            fetch = partial(self.post_mime,
                            self.url,
                            httplib=self.httplib,
                            retries=self.retries,
                            **params)
        else:
            params = dict([(k, v.encode('UTF-8')) for (k,v) in params.iteritems() if v is not None])
            fetch = partial(self.fetch,
                            self.url,
                            urllib2=self.urllib2,
                            httplib=self.httplib,
                            timeout=self.timeout,
                            retries=self.retries,
                            data=urllib.urlencode(params))

        data = json.loads(fetch())
        return self.process_response(data, params, "post")

    def post_file(self, file, **params):
        if self.access_token:
            params['access_token'] = self.access_token
        params['file'] = file
        params['timeout'] = self.timeout
        params['httplib'] = self.httplib
        data = json.loads(self.post_mime(self.url, **params))

        return self.process_response(data, params, "post_file")

    @staticmethod
    def post_mime(url, httplib=default_httplib, timeout=DEFAULT_TIMEOUT, retries=5, **kwargs):
        body = []
        crlf = '\r\n'
        boundary = "graphBoundary"

        # UTF8 params
        utf8_kwargs = dict([(k, v.encode('UTF-8')) for (k,v) in kwargs.iteritems() if k != 'file' and v is not None])

        # Add args
        for (k,v) in utf8_kwargs.iteritems():
            body.append("--"+boundary)
            body.append('Content-Disposition: form-data; name="%s"' % k)
            body.append('')
            body.append(str(v))

        # Add raw data
        file = kwargs.get('file')
        if file:
            file.open()
            data = file.read()
            file.close()

            body.append("--"+boundary)
            body.append('Content-Disposition: form-data; filename="facegraphfile.png"')
            body.append('')
            body.append(data)

            body.append("--"+boundary+"--")
            body.append('')

        body = crlf.join(body)

        # Post to server
        kwargs = {}
        if timeout:
            kwargs = {'timeout': timeout}
        r = httplib.HTTPSConnection(get_host(url), **kwargs)
        headers = {'Content-Type': 'multipart/form-data; boundary=%s' % boundary,
                   'Content-Length': str(len(body)),
                   'MIME-Version': '1.0'}

        r.request('POST', get_path(url).encode(), body, headers)
        attempt = 0
        while True:
            try:
                return r.getresponse().read()
            except (httplib.BadStatusLine, IOError):
                if attempt < retries:
                    attempt += 1
                else:
                    raise
            finally:
                r.close()

    def delete(self):
        """
        Delete this resource. Sends a POST with `?method=delete`
        """
        return self.post(method='delete')

    @staticmethod
    def fetch(url, data=None, urllib2=default_urllib2, httplib=default_httplib, timeout=DEFAULT_TIMEOUT, retries=None):
        """
        Fetch the specified URL, with optional form data; return a string.

        This method exists mainly for dependency injection purposes. By default
        it uses urllib2; you may override it and use an alternative library.
        """
        conn = None
        attempt = 0
        while True:
            try:
                kwargs = {}
                if timeout:
                    kwargs = {'timeout': timeout}
                conn = urllib2.urlopen(url, data=data, **kwargs)
                return conn.read()
            except urllib2.HTTPError, e:
                return e.fp.read()
            except (httplib.BadStatusLine, IOError):
                if attempt < retries:
                    attempt += 1
                else:
                    raise
            finally:
                conn and conn.close()

    def __sentry__(self):
        """
        Transform the graph object into something that sentry can
        understand
        """
        return "Graph(%s, %s)" % (self.url, str(self.__dict__))

class GraphException(Exception):
    def __init__(self, code, message, args=None, params=None, graph=None, method=None):
        Exception.__init__(self)
        if args is not None:
            self.args = args
        self.message = message
        self.code = code
        self.params = params
        self.graph = graph
        self.method = method

    def __repr__(self):
        return str(self)

    def __str__(self):
        s = self.message
        if self.graph:
            s += "Node: %s" % self.graph.url
        if self.params:
            s += ", Params: %s" % self.params
        if self.code:
            s +=  ", (%s)" % self.code
        return s


text:
# -*- coding: utf-8 -*-

__version__ = '0.0.36'

from facegraph.api import Api
from facegraph.api import ApiException
from facegraph.fql import FQL
from facegraph.graph import Graph
from facegraph.graph import GraphException

repo_name: colinhowe/pyFaceGraph

repo_language: Python


text:
import socket
import ujson as json
from urllib import urlencode, unquote

FB_READ_TIMEOUT = 180

class Api:

    def __init__(self, access_token=None, request=None, cookie=None, app_id=None, stack=None,
                       err_handler=None, timeout=FB_READ_TIMEOUT, urllib2=None, httplib=None,
                       retries=5):

        self.uid = None
        self.access_token = access_token
        self.stack = stack if stack else []
        self.cookie = cookie
        self.err_handler = err_handler
        self.retries = retries

        if urllib2 is None:
            import urllib2
        self.urllib2 = urllib2
        if httplib is None:
            import httplib
        self.httplib = httplib
        self.timeout = timeout

        socket.setdefaulttimeout(self.timeout)

        if self.cookie:
            self.load_cookie()
        elif request:
            self.check_cookie(request, app_id)

    def __sentry__(self):
        return u'FB(method: %s, access_token: %s)' % (self.__method(), self.access_token)

    def __repr__(self):
        return '<FB(%r) at 0x%x>' % (self.__method(), id(self))

    def __method(self):
        return u".".join(self.stack)

    def __getitem__(self, name):
        """
        This method returns a new FB and allows us to chain attributes, e.g. fb.stream.publish
        A stack of attributes is maintained so that we can call the correct method later
        """
        s = []
        s.extend(self.stack)
        s.append(name)
        return self.__class__(stack=s, access_token=self.access_token, cookie=self.cookie, err_handler=self.err_handler,
                              timeout=self.timeout, retries=self.retries, urllib2=self.urllib2, httplib=self.httplib)

    def __getattr__(self, name):
        """
        We trigger __getitem__ here so that both self.method.name and self['method']['name'] work
        """
        return self[name]

    def __call__(self, _retries=None, *args, **kwargs):
        """
        Executes an old REST api method using the stored method stack
        """
        _retries = _retries or self.retries

        if len(self.stack)>0:
            kwargs.update({"format": "JSON"})
            method = self.__method()
            # Custom overrides
            if method == "photos.upload":
                return self.__photo_upload(**kwargs)

            # UTF8
            utf8_kwargs = {}
            for (k,v) in kwargs.iteritems():
                try:
                    v = v.encode('UTF-8')
                except AttributeError: pass
                utf8_kwargs[k] = v

            url = "https://api.facebook.com/method/%s?" % method
            if self.access_token:
                url += 'access_token=%s&' % self.access_token
            url += urlencode(utf8_kwargs)

            attempt = 0
            while True:
                try:
                    response = self.urllib2.urlopen(url, timeout=self.timeout).read()
                    break
                except self.urllib2.HTTPError, e:
                    response = e.fp.read()
                    break
                except (self.httplib.BadStatusLine, IOError):
                    if attempt < _retries:
                        attempt += 1
                    else:
                        raise

            return self.__process_response(response, params=kwargs)

    def __process_response(self, response, params=None):
        try:
            data = json.loads(response)
        except ValueError:
            data = response
        try:
            if 'error_code' in data:
                e = ApiException(code=int(data.get('error_code')),
                                 message=data.get('error_msg'),
                                 method=self.__method(),
                                 params=params,
                                 api=self)
                if self.err_handler:
                    return self.err_handler(e=e)
                else:
                    raise e

        except TypeError:
            pass
        return data

    def __photo_upload(self, _retries=None, **kwargs):
        _retries = _retries or self.retries

        body = []
        crlf = '\r\n'
        boundary = "conversocialBoundary"

        # UTF8
        utf8_kwargs = {}
        for (k,v) in kwargs.iteritems():
            try:
                v = v.encode('UTF-8')
            except AttributeError: pass
            utf8_kwargs[k] = v

        # Add args
        utf8_kwargs.update({'access_token': self.access_token})
        for (k,v) in utf8_kwargs.iteritems():
            if k=='photo': continue
            body.append("--"+boundary)
            body.append('Content-Disposition: form-data; name="%s"' % k)
            body.append('')
            body.append(str(v))

        # Add raw image data
        photo = utf8_kwargs.get('photo')
        photo.open()
        data = photo.read()
        photo.close()

        body.append("--"+boundary)
        body.append('Content-Disposition: form-data; filename="myfilewhichisgood.png"')
        body.append('Content-Type: image/png')
        body.append('')
        body.append(data)

        body.append("--"+boundary+"--")
        body.append('')

        body = crlf.join(body)

        # Post to server
        r = self.httplib.HTTPSConnection('api.facebook.com', timeout=self.timeout)
        headers = {'Content-Type': 'multipart/form-data; boundary=%s' % boundary,
                   'Content-Length': str(len(body)),
                   'MIME-Version': '1.0'}

        r.request('POST', '/method/photos.upload', body, headers)

        attempt = 0
        while True:
            try:
                response = r.getresponse().read()
                return self.__process_response(response, params=kwargs)
            except (self.httplib.BadStatusLine, IOError):
                if attempt < _retries:
                    attempt += 1
                else:
                    raise
            finally:
                r.close()

    def check_cookie(self, request, app_id):
        """"
        Parses the fb cookie if present
        """
        cookie = request.COOKIES.get("fbs_%s" % app_id)
        if cookie:
            self.cookie = dict([(v.split("=")[0], unquote(v.split("=")[1])) for v in cookie.split('&')])
            self.load_cookie()

    def load_cookie(self):
        """
        Checks for user FB cookie and sets as instance attributes.
        Contains:
            access_token    OAuth 2.0 access token used by FB for authentication
            uid             Users's Facebook UID
            expires         Expiry date of cookie, will be 0 for constant auth
            secret          Application secret
            sig             Sig parameter
            session_key     Old-style session key, replaced by access_token, deprecated
        """
        if self.cookie:
            for k in self.cookie:
                setattr(self, k, self.cookie.get(k))

    def __fetch(self, url):
        try:
            response = self.urllib2.urlopen(url, timeout=self.timeout)
        except self.urllib2.HTTPError, e:
            response = e.fp
        return json.load(response)

    def verify_token(self, tries=1):
        url = "https://graph.facebook.com/me?access_token=%s" % self.access_token
        for n in range(tries):
            data = self.__fetch(url)
            if 'error' in data:
                pass
            else:
                return True

    def exists(self, object_id):
        url = "https://graph.facebook.com/%s?access_token=%s" % (object_id, self.access_token)
        data = self.__fetch(url)
        if data:
            return True
        else:
            return False

class ApiException(Exception):
    def __init__(self, code, message, args=None, params=None, api=None, method=None):
        Exception.__init__(self)
        if args is not None:
            self.args = args
        self.message = message
        self.code = code
        self.params = params
        self.api = api
        self.method = method

    def __repr__(self):
        return str(self)

    def __str__(self):
        str = "%s, Method: %s" % (self.message, self.method)
        if self.params:
            str = "%s, Params: %s" % (str, self.params)
        if self.code:
            str =  "(#%s) %s" % (self.code, str)
        return str


text:
from unittest import TestCase
from facegraph import graph
from facegraph import url_operations as ops
from facegraph.fql import FQL
from mock import patch

class UrlOperationsTests(TestCase):
    def test_get_path(self):
        self.assertEquals('', ops.get_path(u'http://a.com'))
        self.assertEquals('/', ops.get_path(u'http://a.com/'))
        self.assertEquals('/a', ops.get_path(u'http://a.com/a'))
        self.assertEquals('/a/', ops.get_path(u'http://a.com/a/'))
        self.assertEquals('/a/b', ops.get_path(u'http://a.com/a/b'))

    def test_get_host(self):
        self.assertEquals('a.com', ops.get_host('http://a.com'))
        self.assertEquals('a.com', ops.get_host('http://a.com/a/b'))
        self.assertEquals('a.com', ops.get_host('http://a.com/a?a=b'))

    def test_add_path(self):
        url = u'http://a.com'
        self.assertEquals('http://a.com/', ops.add_path(url, ''))
        self.assertEquals('http://a.com/path', ops.add_path(url, 'path'))
        self.assertEquals('http://a.com/path', ops.add_path(url, '/path'))
        self.assertEquals('http://a.com/path/', ops.add_path(url, 'path/'))
        self.assertEquals('http://a.com/path/', ops.add_path(url, '/path/'))

    def test_add_path_trailing_slash(self):
        url = u'http://a.com/'
        self.assertEquals('http://a.com/path', ops.add_path(url, 'path'))
        self.assertEquals('http://a.com/path', ops.add_path(url, '/path'))
        self.assertEquals('http://a.com/path/', ops.add_path(url, 'path/'))
        self.assertEquals('http://a.com/path/', ops.add_path(url, '/path/'))

    def test_add_path_existing_path(self):
        url = u'http://a.com/path1'
        self.assertEquals('http://a.com/path1/path2', ops.add_path(url, 'path2'))
        self.assertEquals('http://a.com/path1/path2', ops.add_path(url, '/path2'))
        self.assertEquals('http://a.com/path1/path2/', ops.add_path(url, 'path2/'))
        self.assertEquals('http://a.com/path1/path2/', ops.add_path(url, '/path2/'))

    def test_add_path_trailing_slash_and_existing_path(self):
        url = u'http://a.com/path1/'
        self.assertEquals('http://a.com/path1/path2', ops.add_path(url, 'path2'))
        self.assertEquals('http://a.com/path1/path2', ops.add_path(url, '/path2'))
        self.assertEquals('http://a.com/path1/path2/', ops.add_path(url, 'path2/'))
        self.assertEquals('http://a.com/path1/path2/', ops.add_path(url, '/path2/'))

    def test_add_path_fragment(self):
        url = u'http://a.com/path1/#anchor'
        self.assertEquals('http://a.com/path1/path2#anchor', ops.add_path(url, 'path2'))
        self.assertEquals('http://a.com/path1/path2/#anchor', ops.add_path(url, 'path2/'))

    def test_add_path_query_string(self):
        url = u'http://a.com/path1/?a=b'
        self.assertEquals('http://a.com/path1/path2?a=b', ops.add_path(url, 'path2'))
        self.assertEquals('http://a.com/path1/path2/?a=b', ops.add_path(url, 'path2/'))

    def test_query_param(self):
        self.assertEquals(('a', 'b'), ops._query_param('a', 'b'))

    def test_query_param_unicode(self):
        # unicode objects should be encoded as utf-8 bytes
        self.assertEquals(('a', 'b'), ops._query_param('a', u'b'))
        self.assertEquals(('a', '\xc3\xa9'), ops._query_param('a', u'\xe9'))

        # bytes should be remain as bytes
        self.assertEquals(('a', '\xc3\xa9'), ops._query_param('a', '\xc3\xa9'))

    def test_add_query_params(self):
        url = u'http://a.com'
        self.assertEquals('http://a.com?a=b', ops.add_query_params(url, ('a', 'b')))
        self.assertEquals('http://a.com?a=b', ops.add_query_params(url, {'a': 'b'}))
        self.assertEquals('http://a.com?a=%C3%A9', ops.add_query_params(url, {'a': '\xc3\xa9'}))

        url = u'http://a.com/path'
        self.assertEquals('http://a.com/path?a=b', ops.add_query_params(url, {'a': 'b'}))

        url = u'http://a.com?a=b'
        self.assertEquals('http://a.com?a=b&a=c', ops.add_query_params(url, ('a', 'c')))
        self.assertEquals('http://a.com?a=b&c=d', ops.add_query_params(url, ('c', 'd')))

    def test_update_query_params(self):
        url = u'http://a.com?a=b'
        self.assertEquals('http://a.com?a=b', ops.update_query_params(url, {}))
        self.assertEquals('http://a.com?a=c', ops.update_query_params(url, ('a', 'c')))
        self.assertEquals('http://a.com?a=b&c=d', ops.update_query_params(url, {'c': 'd'}))
        self.assertEquals('http://a.com?a=%C4%A9', ops.update_query_params(url, {'a': '\xc4\xa9'}))

        url = u'http://a.com/path?a=b'
        self.assertEquals('http://a.com/path?a=c', ops.update_query_params(url, {'a': 'c'}))

    def test_escaping(self):
        url = u'http://a.com'
        self.assertEquals('http://a.com?my+key=c', ops.add_query_params(url, ('my key', 'c')))
        self.assertEquals('http://a.com?c=my+val', ops.add_query_params(url, ('c', 'my val')))

    def test_no_double_escaping_existing_params(self):
        url = 'http://a.com?a=%C4%A9'
        self.assertEquals('http://a.com?a=%C4%A9&c=d', ops.update_query_params(url, {'c': 'd'}))

        url = 'http://a.com?a=my+val'
        self.assertEquals('http://a.com?a=my+val&c=d', ops.update_query_params(url, {'c': 'd'}))

class GraphUrlTests(TestCase):
    def setUp(self):
        self.graph = graph.Graph()

    def test_initial_state(self):
        self.assertEquals(graph.Graph.API_ROOT, self.graph.url)

    def test_getitem(self):
        expected = 'https://graph.facebook.com/path'
        self.assertEquals(expected, self.graph.path.url)

        expected = 'https://graph.facebook.com/path/path2'
        self.assertEquals(expected, self.graph.path.path2.url)

    def test_getitem_slice(self):
        url = self.graph[0:20].url
        self.assertTrue(url.startswith('https://graph.facebook.com/?'))
        self.assertTrue('offset=0' in url)
        self.assertTrue('limit=20' in url)

    def test_getattr(self):
        expected = 'https://graph.facebook.com/path'
        self.assertEquals(expected, self.graph['path'].url)

        expected = 'https://graph.facebook.com/path/path2'
        self.assertEquals(expected, self.graph['path']['path2'].url)

    def test_update_params(self):
        expected = 'https://graph.facebook.com/?a=b'
        self.graph = self.graph & {'a': 'b'}
        self.assertEquals(expected, self.graph.url)
        expected += '&c=d'
        self.assertEquals(expected, (self.graph & {'c': 'd'}).url)

    def test_set_params(self):
        expected = 'https://graph.facebook.com/?a=b'
        self.graph = self.graph | {'a': 'b'}
        self.assertEquals(expected, self.graph.url)

        expected = 'https://graph.facebook.com/?a=c'
        self.assertEquals(expected, (self.graph | {'a': 'c'}).url)

        expected = 'https://graph.facebook.com/?a=b&c=d'
        self.assertEquals(expected, (self.graph | {'c': 'd'}).url)

    def test_fields(self):
        expected = 'https://graph.facebook.com/?fields=a%2Cb'
        self.graph = self.graph.fields('a', 'b')
        self.assertEquals(expected, self.graph.url)

    def test_ids(self):
        expected = 'https://graph.facebook.com/?ids=a%2Cb'
        self.graph = self.graph.ids('a', 'b')
        self.assertEquals(expected, self.graph.url)

class FQLTests(TestCase):
    def setUp(self):
        self.fql = FQL(access_token='abc123')

    @patch('facegraph.fql.FQL.fetch_json')
    def test_call(self, mock_fetch):
        self.fql('my_query')
        url = mock_fetch.call_args[0][0]
        self.assertTrue(url.startswith('https://api.facebook.com/method/fql.query?'))
        self.assertTrue('query=my_query' in url)
        self.assertTrue('access_token=abc123' in url)

    @patch('facegraph.fql.FQL.fetch_json')
    def test_call_with_arbitrary_params(self, mock_fetch):
        self.fql('my_query', key='value')
        url = mock_fetch.call_args[0][0]
        self.assertTrue(url.startswith('https://api.facebook.com/method/fql.query?'))
        self.assertTrue('query=my_query' in url)
        self.assertTrue('access_token=abc123' in url)
        self.assertTrue('key=value' in url)

    @patch('facegraph.fql.FQL.fetch_json')
    def test_multi(self, mock_fetch):
        self.fql.multi(['my_query1', 'my_query2'])
        url = mock_fetch.call_args[0][0]
        self.assertTrue(url.startswith('https://api.facebook.com/method/fql.multiquery?'))
        self.assertTrue("&queries=%5B%22my_query1%22%2C+%22my_query2%22%5D" in url)


text:
# Lists some code owners.
#
# A codeowner just oversees some part of the codebase. If an owned file is changed then the
# corresponding codeowner receives a review request. An approval of the codeowner might be
# required for merging a PR (depends on repository settings).
#
# For details about syntax, see:
# https://help.github.com/en/articles/about-code-owners
# But here are some important notes:
#
# - Glob syntax is git-like, e.g. `/core` means the core directory in the root, unlike `core`
#   which can be everywhere.
# - Multiple owners are supported.
# - Either handle (e.g, @github_user or @github_org/team) or email can be used. Keep in mind,
#   that handles might work better because they are more recognizable on GitHub,
#   eyou can use them for mentioning unlike an email.
# - The latest matching rule, if multiple, takes precedence.

# Global code owners
* @cmichi @athei @ascjones @agryaznov @SkymanOne

# CI
/.github/ @paritytech/ci @cmichi @ascjones @athei @agryaznov @SkymanOne
/scripts/ci/ @paritytech/ci @cmichi @ascjones @athei @agryaznov @SkymanOne
/.gitlab-ci.yml @paritytech/ci @cmichi @ascjones @athei @agryaznov @SkymanOne

repo_name: paritytech/substrate-contracts-node

repo_language: Rust

mime_type: text/plain


text:
[workspace]
resolver = "2"
members = [
    'node',
    'runtime',
]

[profile.release]
panic = 'unwind'


text:
# substrate-contracts-node

[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/paritytech/substrate-contracts-node)

This repository contains Substrate's [`node-template`](https://github.com/paritytech/substrate/tree/master/bin/node-template)
configured to include Substrate's [`pallet-contracts`](https://github.com/paritytech/substrate/tree/master/frame/contracts)
‒ a smart contract module.

This repository is tracking Substrate's
[`polkadot-v1.0.0`](https://github.com/paritytech/substrate/tree/polkadot-v1.0.0) branch.
When new Polkadot releases come out we may update to those.

_This repository contains a couple of modifications that make it unsuitable
for a production deployment, but a great fit for development and testing:_

* The unstable features of the [`pallet-contracts`](https://github.com/paritytech/substrate/tree/master/frame/contracts)
  are enabled by default (see the [`runtime/Cargo.toml`](https://github.com/paritytech/substrate-contracts-node/blob/main/runtime/Cargo.toml)).
* The consensus algorithm has been switched to `manual-seal` in
  [#42](https://github.com/paritytech/substrate-contracts-node/pull/42).
  Hereby blocks are authored immediately at every transaction, so there
  is none of the typical six seconds block time associated with `grandpa` or `aura`.
* _If no CLI arguments are passed the node is started in development mode
  by default._
* A custom logging filter is applied by default that hides block production noise
  and prints the contracts debug buffer to the console.
* _With each start of the node process the chain starts from genesis ‒ so no
  chain state is retained, all contracts will be lost! If you want to retain
  chain state you have to supply a `--base-path`._
* For `pallet_contracts::Config` we increased the allowed contract sizes. This
  avoids running into `CodeTooLarge` when uploading contracts during development.
  See the comment in [`runtime/src/lib.rs`](https://github.com/paritytech/substrate-contracts-node/blob/main/runtime/src/lib.rs)
  for more details.

If you are looking for a node suitable for production see these configurations:

* [Substrate Node Template](https://github.com/paritytech/substrate/tree/master/bin/node-template)
* [Substrate Cumulus Parachain Template](https://github.com/paritytech/cumulus/tree/master/parachain-template)
* [Contracts Parachain Configuration for Rococo](https://github.com/paritytech/cumulus/tree/master/parachains/runtimes/contracts/contracts-rococo)

## Installation

### Download Binary

The easiest way is to download a binary release from [our releases page](https://github.com/paritytech/substrate-contracts-node/releases)
and just execute `./substrate-contracts-node`.

### Build Locally

Follow the [official installation steps](https://docs.substrate.io/install/) to set up all Substrate prerequisites.

Afterwards you can install this node via

```bash
cargo install contracts-node --git https://github.com/paritytech/substrate-contracts-node.git
```

## Usage

To run a local dev node execute

```bash
substrate-contracts-node
```

A new chain in temporary directory will be created each time the command is executed. This is the
default for this node. If you want to persist chain state across runs you need to
specify a directory with `--base-path`.

See our FAQ for more details:
[How do I print something to the console from the runtime?](https://paritytech.github.io/ink-docs/faq/#how-do-i-print-something-to-the-console-from-the-runtime).

## Connect with frontend

Once the node template is running locally, you can connect to it with frontends like [Contracts UI](https://contracts-ui.substrate.io/#/?rpc=ws://127.0.0.1:9944) or [Polkadot-JS Apps](https://polkadot.js.org/apps/#/explorer?rpc=ws://localhost:9944) and interact with your chain.

## How to upgrade to new Polkadot release

- [ ] Check Substrate's [`node-template`](https://github.com/paritytech/substrate/commits/master/bin/node-template)
      for new commits between the new polkadot release branch and the one this repository is currently synced with.
      The current branch is mentioned in this readme.
- [ ] Apply each commit that happened in this `node-template` folder since the last sync.
- [ ] Check commits for [`pallet-contracts`](https://github.com/paritytech/substrate/tree/master/frame/contracts)
      since the last time someone synchronized this repository with Substrate
      in order to not miss any important changes.
- [ ] Execute `diener update -s --branch my_polkadot_release_branch`. Manually upgrade the
      `pallet-assets-chain-extension` dependency to the latest release branch and then
      `cargo update -p pallet-contracts` for this repository. The specific crate which is mentioned
      here is actually not important: since Substrate uses git references for its Substrate
      dependencies it means that once one package is updated all are.
- [ ] Increment the minor version number in `node/Cargo.toml` and `runtime/Cargo.toml`.
- [ ] Execute `cargo run --release`. If successful, it should produce blocks
      and a new, up to date, `Cargo.lock` will be created.
- [ ] Update this readme with the hash of the Substrate `master` commit
      with which you synchronized. The hash appears two times in this
      readme.
- [ ] Create a PR with the changes, have it reviewed and merged.
- [ ] Replace `XX` in this command with your incremented version number and execute it:
      `git checkout main && git pull && git tag v0.XX.0 && git push origin v0.XX.0`.
      This will push a new tag with the version number to this repository.
- [ ] We have set this repository up in a way that tags à la `vX.X.X` trigger
      a CI run that creates a GitHub draft release. You can observe CI runs on
      [GitLab](https://gitlab.parity.io/parity/mirrors/substrate-contracts-node/-/pipelines).
      This draft release will contain a binary for Linux and Mac and appear
      under [Releases](https://github.com/paritytech/substrate-contracts-node/releases).
      Add a description in the style of "Synchronized with [`polkadot-v1.0.0`](https://github.com/paritytech/substrate/tree/polkadot-v1.0.0) branch."
      and publish it.


text:
#!/bin/sh

echo "Installing protoc..."
sudo apt update
sudo apt install -y unzip
PROTOC_VERSION=$(curl -s "https://api.github.com/repos/protocolbuffers/protobuf/releases/latest" | grep -Po '"tag_name": "v\K[0-9.]+')
curl -Lo protoc.zip "https://github.com/protocolbuffers/protobuf/releases/latest/download/protoc-${PROTOC_VERSION}-linux-x86_64.zip"
sudo unzip -q protoc.zip bin/protoc -d /usr/local
sudo chmod a+x /usr/local/bin/protoc
rm -rf protoc.zip

echo "Installing Substrate Contracts Node..."
SUBSTRATE_VERSION=$(curl -s "https://api.github.com/repos/paritytech/substrate-contracts-node/releases/latest" | grep -Po '"tag_name": "v\K[0-9.]+')
curl -Lo substrate.tar.gz "https://github.com/paritytech/substrate-contracts-node/releases/download/v${SUBSTRATE_VERSION}/substrate-contracts-node-linux.tar.gz"
mkdir substrate-temp
tar -xzf substrate.tar.gz -C substrate-temp
sudo mv substrate-temp/artifacts/substrate-contracts-node-linux/substrate-contracts-node /usr/local/bin/
sudo chmod a+x /usr/local/bin/substrate-contracts-node
rm -rf substrate.tar.gz substrate-temp

echo "Installing cargo-contract CLI tool..."
cargo install --force --locked cargo-contract --version 2.0.0-rc


text:
#!/bin/bash

set -u

# if there is no directory for this $CI_COMMIT_REF_NAME/$CI_JOB_NAME
# create such directory and
# copy recursively all the files from the newest dir which has $CI_JOB_NAME, if it exists

# cache lives in /ci-cache/${CI_PROJECT_NAME}/${2}/${CI_COMMIT_REF_NAME}/${CI_JOB_NAME}

function prepopulate {
  if [[ ! -d $1 ]]; then
    mkdir -p "/ci-cache/$CI_PROJECT_NAME/$2/$CI_COMMIT_REF_NAME";
    FRESH_CACHE=$(find "/ci-cache/$CI_PROJECT_NAME/$2" -mindepth 2 -maxdepth 2 \
      -type d -name "$CI_JOB_NAME"  -exec stat --printf="%Y\t%n\n" {} \; |sort -n -r |head -1 |cut -f2);
    if [[ -d $FRESH_CACHE ]]; then
      echo "____Using" "$FRESH_CACHE" "to prepopulate the cache____";
      time cp -r "$FRESH_CACHE" "$1";
    else
      echo "_____No such $2 dir, proceeding from scratch_____";
    fi
  else
    echo "____No need to prepopulate $2 cache____";
  fi
}

# CARGO_HOME cache is still broken so would be handled some other way.
prepopulate "$CARGO_TARGET_DIR" targets


text:
fn main() {
	#[cfg(feature = "std")]
	{
		substrate_wasm_builder::WasmBuilder::new()
			.with_current_project()
			.export_heap_base()
			.import_memory()
			.build();
	}
}


text:
[package]
name = "contracts-node-runtime"
version = "0.30.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"
license = "Unlicense"
homepage = "https://github.com/paritytech/substrate-contracts-node"
repository = "https://github.com/paritytech/substrate-contracts-node"
build = "build.rs"
publish = false

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] }
scale-info = { version = "2.5.0", default-features = false, features = ["derive"] }

pallet-authorship = { git = "https://github.com/paritytech/substrate", package = "pallet-authorship", default-features = false, branch = "polkadot-v1.0.0" }
pallet-assets = { git = "https://github.com/paritytech/substrate", package = "pallet-assets", default-features = false, branch = "polkadot-v1.0.0" }
pallet-balances = { git = "https://github.com/paritytech/substrate", package = "pallet-balances", default-features = false, branch = "polkadot-v1.0.0" }
frame-support = { git = "https://github.com/paritytech/substrate", package = "frame-support", default-features = false, branch = "polkadot-v1.0.0" }
pallet-insecure-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", package = "pallet-insecure-randomness-collective-flip", default-features = false, branch = "polkadot-v1.0.0" }
pallet-sudo = { git = "https://github.com/paritytech/substrate", package = "pallet-sudo", default-features = false, branch = "polkadot-v1.0.0" }
frame-system = { git = "https://github.com/paritytech/substrate", package = "frame-system", default-features = false, branch = "polkadot-v1.0.0" }
pallet-timestamp = { git = "https://github.com/paritytech/substrate", package = "pallet-timestamp", default-features = false, branch = "polkadot-v1.0.0" }
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", package = "pallet-transaction-payment", default-features = false, branch = "polkadot-v1.0.0" }
frame-executive = { git = "https://github.com/paritytech/substrate", package = "frame-executive", default-features = false, branch = "polkadot-v1.0.0" }
sp-api = { git = "https://github.com/paritytech/substrate", package = "sp-api", default-features = false, branch = "polkadot-v1.0.0" }
sp-block-builder = { git = "https://github.com/paritytech/substrate", package = "sp-block-builder", default-features = false, branch = "polkadot-v1.0.0" }
sp-core = { git = "https://github.com/paritytech/substrate", package = "sp-core", default-features = false, branch = "polkadot-v1.0.0" }
sp-inherents = { git = "https://github.com/paritytech/substrate", package = "sp-inherents", default-features = false, branch = "polkadot-v1.0.0" }
sp-offchain = { git = "https://github.com/paritytech/substrate", package = "sp-offchain", default-features = false, branch = "polkadot-v1.0.0" }
sp-runtime = { git = "https://github.com/paritytech/substrate", package = "sp-runtime", default-features = false, branch = "polkadot-v1.0.0" }
sp-io = { git = "https://github.com/paritytech/substrate", package = "sp-io", default-features = false, branch = "polkadot-v1.0.0" }
sp-session = { git = "https://github.com/paritytech/substrate", package = "sp-session", default-features = false, branch = "polkadot-v1.0.0" }
sp-std = { git = "https://github.com/paritytech/substrate", package = "sp-std", default-features = false, branch = "polkadot-v1.0.0" }
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", package = "sp-transaction-pool", default-features = false, branch = "polkadot-v1.0.0" }
sp-version = { git = "https://github.com/paritytech/substrate", package = "sp-version", default-features = false, branch = "polkadot-v1.0.0" }
pallet-utility = { git = "https://github.com/paritytech/substrate", package = "pallet-utility", default-features = false, branch = "polkadot-v1.0.0" }

# Used for the node's RPCs
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", package = "frame-system-rpc-runtime-api", default-features = false, branch = "polkadot-v1.0.0" }
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", package = "pallet-transaction-payment-rpc-runtime-api", default-features = false, branch = "polkadot-v1.0.0" }

# Contracts specific packages
pallet-contracts = { git = "https://github.com/paritytech/substrate", package = "pallet-contracts", default-features = false, branch = "polkadot-v1.0.0" }
pallet-contracts-primitives = { git = "https://github.com/paritytech/substrate", package = "pallet-contracts-primitives", default-features = false, branch = "polkadot-v1.0.0" }

# Chain extension
pallet-assets-chain-extension = { git = "https://github.com/727-Ventures/pallet-assets-chain-extension", default-features = false, features = ["substrate"], branch = "polkadot-v1.0.0"  }

[build-dependencies]
substrate-wasm-builder =  { git = "https://github.com/paritytech/substrate", package = "substrate-wasm-builder", optional = true, branch = "polkadot-v1.0.0" }

[features]
default = [
	"std",
]
std = [
	"codec/std",
	"scale-info/std",
	"frame-executive/std",
	"frame-support/std",
	"frame-system-rpc-runtime-api/std",
	"frame-system/std",
	"pallet-authorship/std",
	"pallet-balances/std",
	"pallet-insecure-randomness-collective-flip/std",
	"pallet-sudo/std",
	"pallet-timestamp/std",
	"pallet-transaction-payment-rpc-runtime-api/std",
	"pallet-transaction-payment/std",
	"sp-api/std",
	"sp-block-builder/std",
	"sp-core/std",
	"sp-inherents/std",
	"sp-offchain/std",
	"sp-runtime/std",
	"sp-session/std",
	"sp-std/std",
	"sp-transaction-pool/std",
	"sp-version/std",
	"pallet-contracts/std",
	"pallet-contracts-primitives/std",
	"pallet-assets/std",
	"pallet-assets-chain-extension/substrate-std",
	"substrate-wasm-builder",
]


text:
#![cfg_attr(not(feature = "std"), no_std)]
// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
#![recursion_limit = "256"]

// Make the WASM binary available.
#[cfg(feature = "std")]
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));

use frame_support::dispatch::DispatchClass;
use frame_system::{
	limits::{BlockLength, BlockWeights},
	EnsureSigned,
};
use sp_api::impl_runtime_apis;
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
use sp_runtime::{
	create_runtime_str, generic, impl_opaque_keys,
	traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, Verify},
	transaction_validity::{TransactionSource, TransactionValidity},
	ApplyExtrinsicResult, MultiSignature,
};
use sp_std::prelude::*;
#[cfg(feature = "std")]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;

// A few exports that help ease life for downstream crates.
pub use frame_support::{
	construct_runtime, parameter_types,
	traits::{
		AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU32, ConstU8, KeyOwnerProofSystem,
		Randomness, StorageInfo,
	},
	weights::{
		constants::{
			BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_REF_TIME_PER_SECOND,
		},
		IdentityFee, Weight,
	},
	StorageValue,
};
pub use frame_system::Call as SystemCall;
pub use pallet_balances::Call as BalancesCall;
pub use pallet_timestamp::Call as TimestampCall;
use pallet_transaction_payment::CurrencyAdapter;
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
pub use sp_runtime::{Perbill, Permill};

/// An index to a block.
pub type BlockNumber = u32;

/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
pub type Signature = MultiSignature;

/// Some way of identifying an account on the chain. We intentionally make it equivalent
/// to the public key of our transaction signing scheme.
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;

/// Balance of an account.
pub type Balance = u128;

/// Index of a transaction in the chain.
pub type Nonce = u32;

/// A hash of some data used by the chain.
pub type Hash = sp_core::H256;

/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
/// the specifics of the runtime. They can then be made to be agnostic over specific formats
/// of data like extrinsics, allowing for them to continue syncing the network through upgrades
/// to even the core data structures.
pub mod opaque {
	use super::*;

	pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;

	/// Opaque block header type.
	pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
	/// Opaque block type.
	pub type Block = generic::Block<Header, UncheckedExtrinsic>;
	/// Opaque block identifier type.
	pub type BlockId = generic::BlockId<Block>;

	impl_opaque_keys! {
		pub struct SessionKeys {}
	}
}
// To learn more about runtime versioning, see:
// https://docs.substrate.io/main-docs/build/upgrade#runtime-versioning
#[sp_version::runtime_version]
pub const VERSION: RuntimeVersion = RuntimeVersion {
	spec_name: create_runtime_str!("substrate-contracts-node"),
	impl_name: create_runtime_str!("substrate-contracts-node"),
	authoring_version: 1,
	// The version of the runtime specification. A full node will not attempt to use its native
	//   runtime in substitute for the on-chain Wasm runtime unless all of `spec_name`,
	//   `spec_version`, and `authoring_version` are the same between Wasm and native.
	// This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use
	//   the compatible custom types.
	spec_version: 100,
	impl_version: 1,
	apis: RUNTIME_API_VERSIONS,
	transaction_version: 1,
	state_version: 1,
};

/// The version information used to identify this runtime when compiled natively.
#[cfg(feature = "std")]
pub fn native_version() -> NativeVersion {
	NativeVersion { runtime_version: VERSION, can_author_with: Default::default() }
}

const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75);

/// We assume that ~10% of the block weight is consumed by `on_initialize` handlers.
/// This is used to limit the maximal weight of a single extrinsic.
const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);

/// We allow for 2 seconds of compute with a 6 second average block time, with maximum proof size.
const MAXIMUM_BLOCK_WEIGHT: Weight =
	Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), u64::MAX);

// Prints debug output of the `contracts` pallet to stdout if the node is
// started with `-lruntime::contracts=debug`.
const CONTRACTS_DEBUG_OUTPUT: pallet_contracts::DebugInfo =
	pallet_contracts::DebugInfo::UnsafeDebug;
const CONTRACTS_EVENTS: pallet_contracts::CollectEvents =
	pallet_contracts::CollectEvents::UnsafeCollect;

// Unit = the base number of indivisible units for balances
const UNIT: Balance = 1_000_000_000_000;
const MILLIUNIT: Balance = 1_000_000_000;
pub const EXISTENTIAL_DEPOSIT: Balance = MILLIUNIT;

const fn deposit(items: u32, bytes: u32) -> Balance {
	(items as Balance * UNIT + (bytes as Balance) * (5 * MILLIUNIT / 100)) / 10
}

fn schedule<T: pallet_contracts::Config>() -> pallet_contracts::Schedule<T> {
	pallet_contracts::Schedule {
		limits: pallet_contracts::Limits {
			runtime_memory: 1024 * 1024 * 1024,
			..Default::default()
		},
		..Default::default()
	}
}

impl pallet_insecure_randomness_collective_flip::Config for Runtime {}

parameter_types! {
	pub const BlockHashCount: BlockNumber = 2400;
	pub const Version: RuntimeVersion = VERSION;

	// This part is copied from Substrate's `bin/node/runtime/src/lib.rs`.
	//  The `RuntimeBlockLength` and `RuntimeBlockWeights` exist here because the
	// `DeletionWeightLimit` and `DeletionQueueDepth` depend on those to parameterize
	// the lazy contract deletion.
	pub RuntimeBlockLength: BlockLength =
		BlockLength::max_with_normal_ratio(5 * 1024 * 1024, NORMAL_DISPATCH_RATIO);
	pub RuntimeBlockWeights: BlockWeights = BlockWeights::builder()
		.base_block(BlockExecutionWeight::get())
		.for_class(DispatchClass::all(), |weights| {
			weights.base_extrinsic = ExtrinsicBaseWeight::get();
		})
		.for_class(DispatchClass::Normal, |weights| {
			weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
		})
		.for_class(DispatchClass::Operational, |weights| {
			weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
			// Operational transactions have some extra reserved space, so that they
			// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
			weights.reserved = Some(
				MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT
			);
		})
		.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
		.build_or_panic();

	pub const SS58Prefix: u8 = 42;
}

// Configure FRAME pallets to include in runtime.

impl frame_system::Config for Runtime {
	/// The basic call filter to use in dispatchable.
	type BaseCallFilter = frame_support::traits::Everything;
	/// The block type for the runtime.
	type Block = Block;
	/// Block & extrinsics weights: base values and limits.
	type BlockWeights = RuntimeBlockWeights;
	/// The maximum length of a block (in bytes).
	type BlockLength = RuntimeBlockLength;
	/// The identifier used to distinguish between accounts.
	type AccountId = AccountId;
	/// The aggregated dispatch type that is available for extrinsics.
	type RuntimeCall = RuntimeCall;
	/// The lookup mechanism to get account ID from whatever is passed in dispatchers.
	type Lookup = AccountIdLookup<AccountId, ()>;
	/// The index type for storing how many extrinsics an account has signed.
	type Nonce = Nonce;
	/// The type for hashing blocks and tries.
	type Hash = Hash;
	/// The hashing algorithm used.
	type Hashing = BlakeTwo256;
	/// The ubiquitous event type.
	type RuntimeEvent = RuntimeEvent;
	/// The ubiquitous origin type.
	type RuntimeOrigin = RuntimeOrigin;
	/// Maximum number of block number to block hash mappings to keep (oldest pruned first).
	type BlockHashCount = BlockHashCount;
	/// The weight of database operations that the runtime can invoke.
	type DbWeight = RocksDbWeight;
	/// Version of the runtime.
	type Version = Version;
	/// Converts a module to the index of the module in `construct_runtime!`.
	///
	/// This type is being generated by `construct_runtime!`.
	type PalletInfo = PalletInfo;
	/// What to do if a new account is created.
	type OnNewAccount = ();
	/// What to do if an account is fully reaped from the system.
	type OnKilledAccount = ();
	/// The data to be stored in an account.
	type AccountData = pallet_balances::AccountData<Balance>;
	/// Weight information for the extrinsics of this pallet.
	type SystemWeightInfo = ();
	/// This is used as an identifier of the chain. 42 is the generic substrate prefix.
	type SS58Prefix = SS58Prefix;
	/// The set code logic, just the default since we're not a parachain.
	type OnSetCode = ();
	type MaxConsumers = ConstU32<16>;
}

parameter_types! {
	pub const UncleGenerations: u32 = 0;
}

impl pallet_authorship::Config for Runtime {
	type FindAuthor = ();
	type EventHandler = ();
}

parameter_types! {
	pub const MinimumPeriod: u64 = 5;
}

impl pallet_timestamp::Config for Runtime {
	/// A timestamp: milliseconds since the unix epoch.
	type Moment = u64;
	type OnTimestampSet = ();
	type MinimumPeriod = MinimumPeriod;
	type WeightInfo = ();
}

parameter_types! {
	pub const MaxLocks: u32 = 50;
}

impl pallet_balances::Config for Runtime {
	type MaxLocks = MaxLocks;
	type MaxReserves = ();
	type ReserveIdentifier = [u8; 8];
	/// The type for recording an account's balance.
	type Balance = Balance;
	/// The ubiquitous event type.
	type RuntimeEvent = RuntimeEvent;
	type DustRemoval = ();
	type ExistentialDeposit = ConstU128<EXISTENTIAL_DEPOSIT>;
	type AccountStore = System;
	type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
	type FreezeIdentifier = ();
	type MaxFreezes = ();
	type RuntimeHoldReason = ();
	type MaxHolds = ();
}

impl pallet_transaction_payment::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type OnChargeTransaction = CurrencyAdapter<Balances, ()>;
	type OperationalFeeMultiplier = ConstU8<5>;
	type WeightToFee = IdentityFee<Balance>;
	type LengthToFee = IdentityFee<Balance>;
	type FeeMultiplierUpdate = ();
}

impl pallet_sudo::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type RuntimeCall = RuntimeCall;
	type WeightInfo = pallet_sudo::weights::SubstrateWeight<Runtime>;
}

pub const MILLICENTS: Balance = 1_000_000_000;
pub const CENTS: Balance = 1_000 * MILLICENTS; // assume this is worth about a cent.
pub const DOLLARS: Balance = 100 * CENTS;

parameter_types! {
	pub const AssetDeposit: Balance = 100 * DOLLARS;
	pub const ApprovalDeposit: Balance = 1 * DOLLARS;
	pub const StringLimit: u32 = 50;
	pub const MetadataDepositBase: Balance = 10 * DOLLARS;
	pub const MetadataDepositPerByte: Balance = 1 * DOLLARS;
}

impl pallet_assets::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type Balance = u128;
	type AssetId = u32;
	type AssetIdParameter = codec::Compact<u32>;
	type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
	type Currency = Balances;
	type ForceOrigin = frame_system::EnsureRoot<AccountId>;
	type AssetDeposit = AssetDeposit;
	type AssetAccountDeposit = ConstU128<DOLLARS>;
	type MetadataDepositBase = MetadataDepositBase;
	type MetadataDepositPerByte = MetadataDepositPerByte;
	type ApprovalDeposit = ApprovalDeposit;
	type StringLimit = StringLimit;
	type Freezer = ();
	type Extra = ();
	type WeightInfo = pallet_assets::weights::SubstrateWeight<Runtime>;
	type RemoveItemsLimit = ConstU32<1000>;
	type CallbackHandle = ();
}

parameter_types! {
	pub const DepositPerItem: Balance = deposit(1, 0);
	pub const DepositPerByte: Balance = deposit(0, 1);
	pub Schedule: pallet_contracts::Schedule<Runtime> = schedule::<Runtime>();
	pub const DefaultDepositLimit: Balance = deposit(1024, 1024 * 1024);
}

impl pallet_utility::Config for Runtime {
	type RuntimeEvent = RuntimeEvent;
	type RuntimeCall = RuntimeCall;
	type PalletsOrigin = OriginCaller;
	type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
}

pub enum AllowBalancesCall {}

impl frame_support::traits::Contains<RuntimeCall> for AllowBalancesCall {
	fn contains(call: &RuntimeCall) -> bool {
		matches!(call, RuntimeCall::Balances(BalancesCall::transfer_allow_death { .. }))
	}
}

impl pallet_contracts::Config for Runtime {
	type Time = Timestamp;
	type Randomness = RandomnessCollectiveFlip;
	type Currency = Balances;
	type RuntimeEvent = RuntimeEvent;
	type RuntimeCall = RuntimeCall;

	/// The safest default is to allow no calls at all.
	///
	/// Runtimes should whitelist dispatchables that are allowed to be called from contracts
	/// and make sure they are stable. Dispatchables exposed to contracts are not allowed to
	/// change because that would break already deployed contracts. The `RuntimeCall` structure
	/// itself is not allowed to change the indices of existing pallets, too.
	type CallFilter = AllowBalancesCall;
	type DepositPerItem = DepositPerItem;
	type DepositPerByte = DepositPerByte;
	type CallStack = [pallet_contracts::Frame<Self>; 23];
	type WeightPrice = pallet_transaction_payment::Pallet<Self>;
	type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
	type ChainExtension = pallet_assets_chain_extension::substrate::AssetsExtension;
	type Schedule = Schedule;
	type AddressGenerator = pallet_contracts::DefaultAddressGenerator;
	// This node is geared towards development and testing of contracts.
	// We decided to increase the default allowed contract size for this
	// reason (the default is `128 * 1024`).
	//
	// Our reasoning is that the error code `CodeTooLarge` is thrown
	// if a too-large contract is uploaded. We noticed that it poses
	// less friction during development when the requirement here is
	// just more lax.
	type MaxCodeLen = ConstU32<{ 256 * 1024 }>;
	type DefaultDepositLimit = DefaultDepositLimit;
	type MaxStorageKeyLen = ConstU32<128>;
	type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>;
	type UnsafeUnstableInterface = ConstBool<true>;
	type Migrations = ();
}

// Create the runtime by composing the FRAME pallets that were previously configured.
construct_runtime!(
	pub struct Runtime {
		System: frame_system,
		RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip,
		Utility: pallet_utility,
		Timestamp: pallet_timestamp,
		Balances: pallet_balances,
		Authorship: pallet_authorship,
		TransactionPayment: pallet_transaction_payment,
		Sudo: pallet_sudo,
		Contracts: pallet_contracts,
		Assets: pallet_assets,
	}
);

/// The address format for describing accounts.
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
/// Block header type as expected by this runtime.
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
/// Block type as expected by this runtime.
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
/// The SignedExtension to the basic transaction logic.
pub type SignedExtra = (
	frame_system::CheckNonZeroSender<Runtime>,
	frame_system::CheckSpecVersion<Runtime>,
	frame_system::CheckTxVersion<Runtime>,
	frame_system::CheckGenesis<Runtime>,
	frame_system::CheckEra<Runtime>,
	frame_system::CheckNonce<Runtime>,
	frame_system::CheckWeight<Runtime>,
	pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
);
/// The payload being signed in transactions.
pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =
	generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
/// Executive: handles dispatch to the various modules.
pub type Executive = frame_executive::Executive<
	Runtime,
	Block,
	frame_system::ChainContext<Runtime>,
	Runtime,
	AllPalletsWithSystem,
	pallet_contracts::Migration<Runtime>,
>;

type EventRecord = frame_system::EventRecord<
	<Runtime as frame_system::Config>::RuntimeEvent,
	<Runtime as frame_system::Config>::Hash,
>;

impl_runtime_apis! {
	impl sp_api::Core<Block> for Runtime {
		fn version() -> RuntimeVersion {
			VERSION
		}

		fn execute_block(block: Block) {
			Executive::execute_block(block);
		}

		fn initialize_block(header: &<Block as BlockT>::Header) {
			Executive::initialize_block(header)
		}
	}

	impl sp_api::Metadata<Block> for Runtime {
		fn metadata() -> OpaqueMetadata {
			OpaqueMetadata::new(Runtime::metadata().into())
		}
		fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
			Runtime::metadata_at_version(version)
		}

		fn metadata_versions() -> sp_std::vec::Vec<u32> {
			Runtime::metadata_versions()
		}
	}

	impl sp_block_builder::BlockBuilder<Block> for Runtime {
		fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
			Executive::apply_extrinsic(extrinsic)
		}

		fn finalize_block() -> <Block as BlockT>::Header {
			Executive::finalize_block()
		}

		fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
			data.create_extrinsics()
		}

		fn check_inherents(
			block: Block,
			data: sp_inherents::InherentData,
		) -> sp_inherents::CheckInherentsResult {
			data.check_extrinsics(&block)
		}
	}

	impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
		fn validate_transaction(
			source: TransactionSource,
			tx: <Block as BlockT>::Extrinsic,
			block_hash: <Block as BlockT>::Hash,
		) -> TransactionValidity {
			Executive::validate_transaction(source, tx, block_hash)
		}
	}

	impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
		fn offchain_worker(header: &<Block as BlockT>::Header) {
			Executive::offchain_worker(header)
		}
	}

	impl sp_session::SessionKeys<Block> for Runtime {
		fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
			opaque::SessionKeys::generate(seed)
		}

		fn decode_session_keys(
			encoded: Vec<u8>,
		) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
			opaque::SessionKeys::decode_into_raw_public_keys(&encoded)
		}
	}

	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
		fn account_nonce(account: AccountId) -> Nonce {
			System::account_nonce(account)
		}
	}

	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
		fn query_info(
			uxt: <Block as BlockT>::Extrinsic,
			len: u32,
		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
			TransactionPayment::query_info(uxt, len)
		}
		fn query_fee_details(
			uxt: <Block as BlockT>::Extrinsic,
			len: u32,
		) -> pallet_transaction_payment::FeeDetails<Balance> {
			TransactionPayment::query_fee_details(uxt, len)
		}
		fn query_weight_to_fee(weight: Weight) -> Balance {
			TransactionPayment::weight_to_fee(weight)
		}
		fn query_length_to_fee(length: u32) -> Balance {
			TransactionPayment::length_to_fee(length)
		}
	}

	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall> for Runtime {
		fn query_call_info(
			call: RuntimeCall,
			len: u32,
		) -> pallet_transaction_payment::RuntimeDispatchInfo<Balance> {
			TransactionPayment::query_call_info(call, len)
		}
		fn query_call_fee_details(
			call: RuntimeCall,
			len: u32,
		) -> pallet_transaction_payment::FeeDetails<Balance> {
			TransactionPayment::query_call_fee_details(call, len)
		}
		fn query_weight_to_fee(weight: Weight) -> Balance {
			TransactionPayment::weight_to_fee(weight)
		}
		fn query_length_to_fee(length: u32) -> Balance {
			TransactionPayment::length_to_fee(length)
		}
	}

	impl pallet_contracts::ContractsApi<Block, AccountId, Balance, BlockNumber, Hash, EventRecord>
		for Runtime
	{
		fn call(
			origin: AccountId,
			dest: AccountId,
			value: Balance,
			gas_limit: Option<Weight>,
			storage_deposit_limit: Option<Balance>,
			input_data: Vec<u8>,
		) -> pallet_contracts_primitives::ContractExecResult<Balance, EventRecord> {
			let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
			Contracts::bare_call(
				origin,
				dest,
				value,
				gas_limit,
				storage_deposit_limit,
				input_data,
				CONTRACTS_DEBUG_OUTPUT,
				CONTRACTS_EVENTS,
				pallet_contracts::Determinism::Enforced,
			)
		}

		fn instantiate(
			origin: AccountId,
			value: Balance,
			gas_limit: Option<Weight>,
			storage_deposit_limit: Option<Balance>,
			code: pallet_contracts_primitives::Code<Hash>,
			data: Vec<u8>,
			salt: Vec<u8>,
		) -> pallet_contracts_primitives::ContractInstantiateResult<AccountId, Balance, EventRecord>
		{
			let gas_limit = gas_limit.unwrap_or(RuntimeBlockWeights::get().max_block);
			Contracts::bare_instantiate(
				origin,
				value,
				gas_limit,
				storage_deposit_limit,
				code,
				data,
				salt,
				CONTRACTS_DEBUG_OUTPUT,
				CONTRACTS_EVENTS,
			)
		}

		fn upload_code(
			origin: AccountId,
			code: Vec<u8>,
			storage_deposit_limit: Option<Balance>,
			determinism: pallet_contracts::Determinism,
		) -> pallet_contracts_primitives::CodeUploadResult<Hash, Balance>
		{
			Contracts::bare_upload_code(origin, code, storage_deposit_limit, determinism)
		}

		fn get_storage(
			address: AccountId,
			key: Vec<u8>,
		) -> pallet_contracts_primitives::GetStorageResult {
			Contracts::get_storage(address, key)
		}
	}
}


text:
use substrate_build_script_utils::{generate_cargo_keys, rerun_if_git_head_changed};

fn main() {
	generate_cargo_keys();

	rerun_if_git_head_changed();
}


text:
[package]
name = "contracts-node"
version = "0.30.0"
authors = ["Parity Technologies <admin@parity.io>"]
description = "Substrate node configured for smart contracts via `pallet-contracts`."
edition = "2021"
license = "Unlicense"
build = "build.rs"
homepage = "https://github.com/paritytech/substrate-contracts-node"
repository = "https://github.com/paritytech/substrate-contracts-node"
publish = false

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[[bin]]
name = "substrate-contracts-node"
path = "src/main.rs"

[dependencies]
clap = { version = "4.2.7", features = ["derive"] }
futures = { version = "0.3.21", features = ["thread-pool"]}

sc-cli = { git = "https://github.com/paritytech/substrate", package = "sc-cli", default-features = false, branch = "polkadot-v1.0.0" }
sp-core = { git = "https://github.com/paritytech/substrate", package = "sp-core", branch = "polkadot-v1.0.0" }
sc-executor = { git = "https://github.com/paritytech/substrate", package = "sc-executor", branch = "polkadot-v1.0.0" }
sc-network = { git = "https://github.com/paritytech/substrate", package = "sc-network", branch = "polkadot-v1.0.0" }
sc-service = { git = "https://github.com/paritytech/substrate", package = "sc-service", default-features = false, branch = "polkadot-v1.0.0" }
sc-telemetry = { git = "https://github.com/paritytech/substrate", package = "sc-telemetry", branch = "polkadot-v1.0.0" }
sc-keystore = { git = "https://github.com/paritytech/substrate", package = "sc-keystore", branch = "polkadot-v1.0.0" }
sc-transaction-pool = { git = "https://github.com/paritytech/substrate", package = "sc-transaction-pool", branch = "polkadot-v1.0.0" }
sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", package = "sc-transaction-pool-api", branch = "polkadot-v1.0.0" }
sc-offchain = { git = "https://github.com/paritytech/substrate", package = "sc-offchain", branch = "polkadot-v1.0.0" }
sc-consensus = { git = "https://github.com/paritytech/substrate", package = "sc-consensus", branch = "polkadot-v1.0.0" }
sc-consensus-manual-seal = { git = "https://github.com/paritytech/substrate", package = "sc-consensus-manual-seal", branch = "polkadot-v1.0.0" }
sc-client-api = { git = "https://github.com/paritytech/substrate", package = "sc-client-api", branch = "polkadot-v1.0.0" }
sp-runtime = { git = "https://github.com/paritytech/substrate", package = "sp-runtime", branch = "polkadot-v1.0.0" }
sp-timestamp = { git = "https://github.com/paritytech/substrate", package = "sp-timestamp", branch = "polkadot-v1.0.0" }

# These dependencies are used for the node's RPCs
jsonrpsee = { version = "0.16.2", features = ["server"] }
sp-api = { git = "https://github.com/paritytech/substrate", package = "sp-api", branch = "polkadot-v1.0.0" }
sc-rpc = { git = "https://github.com/paritytech/substrate", package = "sc-rpc", branch = "polkadot-v1.0.0" }
sc-rpc-api = { git = "https://github.com/paritytech/substrate", package = "sc-rpc-api", branch = "polkadot-v1.0.0" }
sp-blockchain = { git = "https://github.com/paritytech/substrate", package = "sp-blockchain", branch = "polkadot-v1.0.0" }
sp-block-builder = { git = "https://github.com/paritytech/substrate", package = "sp-block-builder", branch = "polkadot-v1.0.0" }
sc-basic-authorship = { git = "https://github.com/paritytech/substrate", package = "sc-basic-authorship", branch = "polkadot-v1.0.0" }
substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", package = "substrate-frame-rpc-system", branch = "polkadot-v1.0.0" }
pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", package = "pallet-transaction-payment-rpc", branch = "polkadot-v1.0.0" }

# Local Dependencies
contracts-node-runtime = { path = "../runtime" }

# yank this crate until
# https://github.com/bluejekyll/enum-as-inner/issues/98
# is fixed
enum-as-inner = "=0.5.1"

[build-dependencies]
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", package = "substrate-build-script-utils", branch = "polkadot-v1.0.0" }

[features]
default = []


text:
use crate::{
	chain_spec,
	cli::{Cli, Subcommand},
	service,
};
use contracts_node_runtime::Block;
use sc_cli::SubstrateCli;
use sc_service::PartialComponents;

impl SubstrateCli for Cli {
	fn impl_name() -> String {
		"Substrate Contracts Node".into()
	}

	fn impl_version() -> String {
		env!("SUBSTRATE_CLI_IMPL_VERSION").into()
	}

	fn description() -> String {
		env!("CARGO_PKG_DESCRIPTION").into()
	}

	fn author() -> String {
		env!("CARGO_PKG_AUTHORS").into()
	}

	fn support_url() -> String {
		"https://github.com/paritytech/substrate-contracts-node/issues/new".into()
	}

	fn copyright_start_year() -> i32 {
		2021
	}

	fn load_spec(&self, id: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
		Ok(match id {
			"" | "dev" => Box::new(chain_spec::development_config()?),
			"local" => Box::new(chain_spec::local_testnet_config()?),
			path =>
				Box::new(chain_spec::ChainSpec::from_json_file(std::path::PathBuf::from(path))?),
		})
	}
}

/// Parse and run command line arguments
pub fn run() -> sc_cli::Result<()> {
	let mut cli = Cli::from_args();

	// this is a development node: make dev chain spec the default
	if cli.run.shared_params.chain.is_none() {
		cli.run.shared_params.dev = true;
	}

	// remove block production noise and output contracts debug buffer by default
	if cli.run.shared_params.log.is_empty() {
		cli.run.shared_params.log = vec![
			"runtime::contracts=debug".into(),
			"sc_cli=info".into(),
			"sc_rpc_server=info".into(),
			"warn".into(),
		];
	}

	match &cli.subcommand {
		Some(Subcommand::Key(cmd)) => cmd.run(&cli),
		Some(Subcommand::BuildSpec(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.sync_run(|config| cmd.run(config.chain_spec, config.network))
		},
		Some(Subcommand::CheckBlock(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.async_run(|config| {
				let PartialComponents { client, task_manager, import_queue, .. } =
					service::new_partial(&config)?;
				Ok((cmd.run(client, import_queue), task_manager))
			})
		},
		Some(Subcommand::ExportBlocks(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.async_run(|config| {
				let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?;
				Ok((cmd.run(client, config.database), task_manager))
			})
		},
		Some(Subcommand::ExportState(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.async_run(|config| {
				let PartialComponents { client, task_manager, .. } = service::new_partial(&config)?;
				Ok((cmd.run(client, config.chain_spec), task_manager))
			})
		},
		Some(Subcommand::ImportBlocks(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.async_run(|config| {
				let PartialComponents { client, task_manager, import_queue, .. } =
					service::new_partial(&config)?;
				Ok((cmd.run(client, import_queue), task_manager))
			})
		},
		Some(Subcommand::PurgeChain(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.sync_run(|config| cmd.run(config.database))
		},
		Some(Subcommand::Revert(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.async_run(|config| {
				let PartialComponents { client, task_manager, backend, .. } =
					service::new_partial(&config)?;
				Ok((cmd.run(client, backend, None), task_manager))
			})
		},
		Some(Subcommand::ChainInfo(cmd)) => {
			let runner = cli.create_runner(cmd)?;
			runner.sync_run(|config| cmd.run::<Block>(&config))
		},
		None => {
			let runner = cli.create_runner(&cli.run)?;
			runner.run_node_until_exit(|config| async move {
				service::new_full(config).map_err(sc_cli::Error::Service)
			})
		},
	}
}


text:
use sc_cli::RunCmd;

#[derive(Debug, clap::Parser)]
pub struct Cli {
	#[command(subcommand)]
	pub subcommand: Option<Subcommand>,

	#[command(flatten)]
	pub run: RunCmd,
}

#[derive(Debug, clap::Subcommand)]
#[allow(clippy::large_enum_variant)]
pub enum Subcommand {
	/// Key management cli utilities
	#[clap(subcommand)]
	Key(sc_cli::KeySubcommand),

	/// Build a chain specification.
	BuildSpec(sc_cli::BuildSpecCmd),

	/// Validate blocks.
	CheckBlock(sc_cli::CheckBlockCmd),

	/// Export blocks.
	ExportBlocks(sc_cli::ExportBlocksCmd),

	/// Export the state of a given block into a chain spec.
	ExportState(sc_cli::ExportStateCmd),

	/// Import blocks.
	ImportBlocks(sc_cli::ImportBlocksCmd),

	/// Remove the whole chain.
	PurgeChain(sc_cli::PurgeChainCmd),

	/// Revert the chain to a previous state.
	Revert(sc_cli::RevertCmd),

	/// Db meta columns information.
	ChainInfo(sc_cli::ChainInfoCmd),
}


text:
use contracts_node_runtime::{
	AccountId, BalancesConfig, RuntimeGenesisConfig, Signature, SudoConfig, SystemConfig,
	WASM_BINARY,
};
use sc_service::ChainType;
use sp_core::{sr25519, Pair, Public};
use sp_runtime::traits::{IdentifyAccount, Verify};

// The URL for the telemetry server.
// const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";

/// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
pub type ChainSpec = sc_service::GenericChainSpec<RuntimeGenesisConfig>;

/// Generate a crypto pair from seed.
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
	TPublic::Pair::from_string(&format!("//{}", seed), None)
		.expect("static values are valid; qed")
		.public()
}

type AccountPublic = <Signature as Verify>::Signer;

/// Generate an account ID from seed.
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
where
	AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
	AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
}

pub fn development_config() -> Result<ChainSpec, String> {
	let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?;

	Ok(ChainSpec::from_genesis(
		// Name
		"Development",
		// ID
		"dev",
		ChainType::Development,
		move || {
			testnet_genesis(
				wasm_binary,
				// Sudo account
				get_account_id_from_seed::<sr25519::Public>("Alice"),
				// Pre-funded accounts
				vec![
					get_account_id_from_seed::<sr25519::Public>("Alice"),
					get_account_id_from_seed::<sr25519::Public>("Bob"),
					get_account_id_from_seed::<sr25519::Public>("Charlie"),
					get_account_id_from_seed::<sr25519::Public>("Dave"),
					get_account_id_from_seed::<sr25519::Public>("Eve"),
					get_account_id_from_seed::<sr25519::Public>("Ferdie"),
					get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
					get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
					get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
					get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
					get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
					get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
				],
				true,
			)
		},
		// Bootnodes
		vec![],
		// Telemetry
		None,
		// Protocol ID
		Some("rpc"),
		// Fork ID
		None,
		// Properties
		None,
		// Extensions
		None,
	))
}

pub fn local_testnet_config() -> Result<ChainSpec, String> {
	let wasm_binary = WASM_BINARY.ok_or_else(|| "Development wasm not available".to_string())?;

	Ok(ChainSpec::from_genesis(
		// Name
		"Local Testnet",
		// ID
		"local_testnet",
		ChainType::Local,
		move || {
			testnet_genesis(
				wasm_binary,
				// Sudo account
				get_account_id_from_seed::<sr25519::Public>("Alice"),
				// Pre-funded accounts
				vec![
					get_account_id_from_seed::<sr25519::Public>("Alice"),
					get_account_id_from_seed::<sr25519::Public>("Bob"),
					get_account_id_from_seed::<sr25519::Public>("Charlie"),
					get_account_id_from_seed::<sr25519::Public>("Dave"),
					get_account_id_from_seed::<sr25519::Public>("Eve"),
					get_account_id_from_seed::<sr25519::Public>("Ferdie"),
					get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
					get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
					get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
					get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
					get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
					get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
				],
				true,
			)
		},
		// Bootnodes
		vec![],
		// Telemetry
		None,
		// Protocol ID
		Some("rpc"),
		// Fork ID
		None,
		// Properties
		None,
		// Extensions
		None,
	))
}

/// Configure initial storage state for FRAME modules.
fn testnet_genesis(
	wasm_binary: &[u8],
	root_key: AccountId,
	endowed_accounts: Vec<AccountId>,
	_enable_println: bool,
) -> RuntimeGenesisConfig {
	RuntimeGenesisConfig {
		system: SystemConfig {
			// Add Wasm runtime to storage.
			code: wasm_binary.to_vec(),
			..Default::default()
		},
		balances: BalancesConfig {
			// Configure endowed accounts with initial balance of 1 << 60.
			balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(),
		},
		sudo: SudoConfig {
			// Assign network admin rights.
			key: Some(root_key),
		},
		transaction_payment: Default::default(),
		assets: Default::default(),
	}
}


text:
//! Substrate Node Template CLI library.
#![warn(missing_docs)]

mod chain_spec;
#[macro_use]
mod service;
mod cli;
mod command;
mod rpc;

fn main() -> sc_cli::Result<()> {
	command::run()
}


text:
//! A collection of node-specific RPC methods.
//! Substrate provides the `sc-rpc` crate, which defines the core RPC layer
//! used by Substrate nodes. This file extends those RPC definitions with
//! capabilities that are specific to this project's runtime configuration.

#![warn(missing_docs)]

use std::sync::Arc;

use contracts_node_runtime::{opaque::Block, AccountId, Balance, Nonce};
use jsonrpsee::RpcModule;
use sc_client_api::BlockBackend;
use sc_rpc::dev::{Dev, DevApiServer};
use sc_transaction_pool_api::TransactionPool;
use sp_api::ProvideRuntimeApi;
use sp_block_builder::BlockBuilder;
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};

pub use sc_rpc_api::DenyUnsafe;

/// Full client dependencies.
pub struct FullDeps<C, P> {
	/// The client instance to use.
	pub client: Arc<C>,
	/// Transaction pool instance.
	pub pool: Arc<P>,
	/// Whether to deny unsafe calls
	pub deny_unsafe: DenyUnsafe,
}

/// Instantiate all full RPC extensions.
pub fn create_full<C, P>(
	deps: FullDeps<C, P>,
) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
where
	C: ProvideRuntimeApi<Block>,
	C: BlockBackend<Block>,
	C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
	C: Send + Sync + 'static,
	C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Nonce>,
	C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
	C::Api: BlockBuilder<Block>,
	P: TransactionPool + 'static,
{
	use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
	use substrate_frame_rpc_system::{System, SystemApiServer};

	let mut module = RpcModule::new(());
	let FullDeps { client, pool, deny_unsafe } = deps;

	module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?;
	module.merge(TransactionPayment::new(client.clone()).into_rpc())?;

	// Extend this RPC with a custom API by using the following syntax.
	// `YourRpcStruct` should have a reference to a client, which is needed
	// to call into the runtime.
	// `module.merge(YourRpcTrait::into_rpc(YourRpcStruct::new(ReferenceToClient, ...)))?;`

	// Dev RPC API extension
	module.merge(Dev::new(client, deny_unsafe).into_rpc())?;

	Ok(module)
}


text:
//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.

use contracts_node_runtime::{self, opaque::Block, RuntimeApi};
use futures::FutureExt;
use sc_client_api::Backend;
pub use sc_executor::NativeElseWasmExecutor;
use sc_service::{error::Error as ServiceError, Configuration, TaskManager};
use sc_telemetry::{Telemetry, TelemetryWorker};
use sc_transaction_pool_api::OffchainTransactionPoolFactory;
use std::sync::Arc;

// Our native executor instance.
pub struct ExecutorDispatch;

impl sc_executor::NativeExecutionDispatch for ExecutorDispatch {
	/// We only use the default Substrate host functions as runtime benchmarks are not supported.
	type ExtendHostFunctions = ();

	fn dispatch(method: &str, data: &[u8]) -> Option<Vec<u8>> {
		contracts_node_runtime::api::dispatch(method, data)
	}

	fn native_version() -> sc_executor::NativeVersion {
		contracts_node_runtime::native_version()
	}
}

pub(crate) type FullClient =
	sc_service::TFullClient<Block, RuntimeApi, NativeElseWasmExecutor<ExecutorDispatch>>;
type FullBackend = sc_service::TFullBackend<Block>;
type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;

#[allow(clippy::type_complexity)]
pub fn new_partial(
	config: &Configuration,
) -> Result<
	sc_service::PartialComponents<
		FullClient,
		FullBackend,
		FullSelectChain,
		sc_consensus::DefaultImportQueue<Block, FullClient>,
		sc_transaction_pool::FullPool<Block, FullClient>,
		(Option<Telemetry>,),
	>,
	ServiceError,
> {
	let telemetry = config
		.telemetry_endpoints
		.clone()
		.filter(|x| !x.is_empty())
		.map(|endpoints| -> Result<_, sc_telemetry::Error> {
			let worker = TelemetryWorker::new(16)?;
			let telemetry = worker.handle().new_telemetry(endpoints);
			Ok((worker, telemetry))
		})
		.transpose()?;

	let executor = sc_service::new_native_or_wasm_executor(config);

	let (client, backend, keystore_container, task_manager) =
		sc_service::new_full_parts::<Block, RuntimeApi, _>(
			config,
			telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
			executor,
		)?;
	let client = Arc::new(client);

	let select_chain = sc_consensus::LongestChain::new(backend.clone());

	let telemetry = telemetry.map(|(worker, telemetry)| {
		task_manager.spawn_handle().spawn("telemetry", None, worker.run());
		telemetry
	});

	let import_queue = sc_consensus_manual_seal::import_queue(
		Box::new(client.clone()),
		&task_manager.spawn_essential_handle(),
		config.prometheus_registry(),
	);

	let transaction_pool = sc_transaction_pool::BasicPool::new_full(
		config.transaction_pool.clone(),
		config.role.is_authority().into(),
		config.prometheus_registry(),
		task_manager.spawn_essential_handle(),
		client.clone(),
	);

	Ok(sc_service::PartialComponents {
		client,
		backend,
		task_manager,
		import_queue,
		keystore_container,
		select_chain,
		transaction_pool,
		other: (telemetry,),
	})
}

/// Builds a new service for a full client.
pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
	let sc_service::PartialComponents {
		client,
		backend,
		mut task_manager,
		import_queue,
		keystore_container,
		select_chain,
		transaction_pool,
		other: (mut telemetry,),
	} = new_partial(&config)?;

	let net_config = sc_network::config::FullNetworkConfiguration::new(&config.network);

	let (network, system_rpc_tx, tx_handler_controller, network_starter, sync_service) =
		sc_service::build_network(sc_service::BuildNetworkParams {
			config: &config,
			net_config,
			client: client.clone(),
			transaction_pool: transaction_pool.clone(),
			spawn_handle: task_manager.spawn_handle(),
			import_queue,
			block_announce_validator_builder: None,
			warp_sync_params: None,
		})?;

	if config.offchain_worker.enabled {
		task_manager.spawn_handle().spawn(
			"offchain-workers-runner",
			"offchain-worker",
			sc_offchain::OffchainWorkers::new(sc_offchain::OffchainWorkerOptions {
				runtime_api_provider: client.clone(),
				is_validator: config.role.is_authority(),
				keystore: Some(keystore_container.keystore()),
				offchain_db: backend.offchain_storage(),
				transaction_pool: Some(OffchainTransactionPoolFactory::new(
					transaction_pool.clone(),
				)),
				network_provider: network.clone(),
				enable_http_requests: true,
				custom_extensions: |_| vec![],
			})
			.run(client.clone(), task_manager.spawn_handle())
			.boxed(),
		);
	}

	let rpc_extensions_builder = {
		let client = client.clone();
		let pool = transaction_pool.clone();

		Box::new(move |deny_unsafe, _| {
			let deps =
				crate::rpc::FullDeps { client: client.clone(), pool: pool.clone(), deny_unsafe };
			crate::rpc::create_full(deps).map_err(Into::into)
		})
	};
	let prometheus_registry = config.prometheus_registry().cloned();

	let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams {
		network,
		client: client.clone(),
		keystore: keystore_container.keystore(),
		task_manager: &mut task_manager,
		transaction_pool: transaction_pool.clone(),
		rpc_builder: rpc_extensions_builder,
		backend,
		system_rpc_tx,
		tx_handler_controller,
		sync_service,
		config,
		telemetry: telemetry.as_mut(),
	})?;

	let proposer = sc_basic_authorship::ProposerFactory::new(
		task_manager.spawn_handle(),
		client.clone(),
		transaction_pool.clone(),
		prometheus_registry.as_ref(),
		telemetry.as_ref().map(|x| x.handle()),
	);

	let params = sc_consensus_manual_seal::InstantSealParams {
		block_import: client.clone(),
		env: proposer,
		client,
		pool: transaction_pool,
		select_chain,
		consensus_data_provider: None,
		create_inherent_data_providers: move |_, ()| async move {
			Ok(sp_timestamp::InherentDataProvider::from_system_time())
		},
	};

	let authorship_future = sc_consensus_manual_seal::run_instant_seal(params);

	task_manager
		.spawn_essential_handle()
		.spawn_blocking("instant-seal", None, authorship_future);

	network_starter.start_network();
	Ok(task_manager)
}


text:
option('godot-cpp-lib-name', type : 'string', value : 'libgodot-cpp', description : 'GDNative C++ bindings static library name')
option('static-runtime', type : 'boolean', value : false, description : 'Link libraries statically for better portability')
option('builtin-runtime', type : 'boolean', value : true, description : 'Use the built-in libraries')
option('use-graphite2', type : 'boolean', value : true, description : 'Enable Graphite2 complementary shaper')
option('use-ubsan', type : 'boolean', value : false, description : 'Use LLVM/GCC compiler undefined behavior sanitizer')
option('use-asan', type : 'boolean', value : false, description : 'Use LLVM/GCC compiler address sanitizer')
option('use-lsan', type : 'boolean', value : false, description : 'Use LLVM/GCC compiler leak sanitizer')
option('use-tsan', type : 'boolean', value : false, description : 'Use LLVM/GCC compiler thread sanitizer')

repo_language: C

mime_type: text/x-c