Giter Club home page Giter Club logo

gosemble's Introduction

Gosemble

Go Report Card codecov

Warning

Gosemble is in pre-production and the code is not yet audited. Use at your own risk.

Go implementation of Polkadot/Substrate compatible runtimes. For more details, check the Official Documentation

Quick Start

Prerequisites

Clone the repository

git clone https://github.com/LimeChain/gosemble.git
cd gosemble

Pull all necessary git submodules

git submodule update --init --recursive

Build

To build a runtime, execute:

make build-docker-release

Start a local network

After the runtime is built, start a local network using Substrate host:

make start-network

Run Tests

After the Runtime is built, execute the tests with the help of Gossamer, which is used to import necessary Polkadot Host functionality and interact with the Runtime.

make test-unit
make test-integration

gosemble's People

Contributors

daniel-k-ivanov avatar dependabot[bot] avatar failfmi avatar nicksinch avatar radkomih avatar tgntr avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

gosemble's Issues

Use a SCALE codec compatible with Tinygo

  • changes to use SCALE codec compatible with Tinygo
  • fix wrong field type from the spec
  • refactor and use better abstractions for the Host provided functionality

Interfaces for specific types

Create interfaces, which allow easier configuration of given types. For example, block number to be easily changed from u64 and u128 in only one place in the codebase.

type Number: Member
		+ MaybeSerializeDeserialize
		+ MaybeFromStr
		+ Debug
		+ sp_std::hash::Hash
		+ Copy
		+ MaybeDisplay
		+ AtLeast32BitUnsigned
		+ Default
		+ TypeInfo
		+ MaxEncodedLen
		+ FullCodec;
  • Block Number
  • Nonce

Implement Ecdsa signature verification

There is a TODO in the codebase:

let m = sp_io::hashing::blake2_256(msg.get());
match sp_io::crypto::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) {
 	Ok(pubkey) =>
 		&sp_io::hashing::blake2_256(pubkey.as_ref()) ==
 			<dyn AsRef<[u8; 32]>>::as_ref(who),
 	_ => false,
}

docs: tutorials

Add step-by-step guides on how to run a local network and how to do a transfer

Complete `metadata` implementation

Remove the hard-coded metadata used from node-template and add the missing metadata types. Keep in mind that metadata type path has to be used if you want to successfully connect to polkadotjs, as it is uses path field to rebuilt most types and those paths have to be consistent with Substrate.

Example:

  /**
   * Lookup8: frame_support::dispatch::PerDispatchClass<sp_weights::weight_v2::Weight>
   **/
  FrameSupportDispatchPerDispatchClassWeight: {
    normal: 'SpWeightsWeightV2Weight',
    operational: 'SpWeightsWeightV2Weight',
    mandatory: 'SpWeightsWeightV2Weight'
  },
  /**
   * Lookup9: sp_weights::weight_v2::Weight
   **/
  SpWeightsWeightV2Weight: {
    refTime: 'Compact<u64>',
    proofSize: 'Compact<u64>'
  },

validate_transaction - input compatibility

The input passed to validate_transaction with gosemble types to Substrate runtimes fails. Go through the input arguments and check whether their encoding is correct.

Implement balances

  • system Events
  • balances Events
  • setBalance
  • transfer
  • force_transfer
  • transfer_keep_alive
  • transfer_all
  • force_unreserve

Enable critical logging before panics

Currently, whenever the runtime panics with an actual written error (e.g. parent hash should be valid), there is only error returned, without actual critical logging:

running runtime function: Failed to call the runtime function exported function

The following log must appear:

CRITICAL target=runtime message=panicked at 'parent hash should be valid', -build error line- ext_logging_log_version_1 pkg=runtime module=go-wasmer

and afterwards

running runtime function: Failed to call the runtime function exported function.

assert extrinsic length

Upon decoding an extrinsic, assert that the compact extrinsic length matches the actual decoded bytes length

remove the _start exported function

There is no need to export and call "_start" (it is also not expected from the host to support that), since it is the host allocator's responsibility to initialize and grow the heap as needed.

Refactor modules

Refactor existing modules to be easier to configure. Each module must have:

  • configuration
  • storage
  • events
  • constants
  • errors

Generic storage type

Create a generic storage type, which takes prefix, name and decode function. Type should implement exists, get and put.

Implement validate weights for BlockWeightsBuilder

/// Verifies correctness of this `BlockWeights` object.
	pub fn validate(self) -> ValidationResult {
		fn or_max(w: Option<Weight>) -> Weight {
			w.unwrap_or_else(Weight::max_value)
		}
		let mut error = ValidationErrors::default();

		for class in DispatchClass::all() {
			let weights = self.per_class.get(*class);
			let max_for_class = or_max(weights.max_total);
			let base_for_class = weights.base_extrinsic;
			let reserved = or_max(weights.reserved);
			// Make sure that if total is set it's greater than base_block &&
			// base_for_class
			error_assert!(
				(max_for_class.all_gt(self.base_block) && max_for_class.all_gt(base_for_class))
				|| max_for_class == Weight::zero(),
				&mut error,
				"[{:?}] {:?} (total) has to be greater than {:?} (base block) & {:?} (base extrinsic)",
				class, max_for_class, self.base_block, base_for_class,
			);
			// Max extrinsic can't be greater than max_for_class.
			error_assert!(
				weights
					.max_extrinsic
					.unwrap_or(Weight::zero())
					.all_lte(max_for_class.saturating_sub(base_for_class)),
				&mut error,
				"[{:?}] {:?} (max_extrinsic) can't be greater than {:?} (max for class)",
				class,
				weights.max_extrinsic,
				max_for_class.saturating_sub(base_for_class),
			);
			// Max extrinsic should not be 0
			error_assert!(
				weights.max_extrinsic.unwrap_or_else(Weight::max_value).all_gt(Weight::zero()),
				&mut error,
				"[{:?}] {:?} (max_extrinsic) must not be 0. Check base cost and average initialization cost.",
				class, weights.max_extrinsic,
			);
			// Make sure that if reserved is set it's greater than base_for_class.
			error_assert!(
				reserved.all_gt(base_for_class) || reserved == Weight::zero(),
				&mut error,
				"[{:?}] {:?} (reserved) has to be greater than {:?} (base extrinsic) if set",
				class,
				reserved,
				base_for_class,
			);
			// Make sure max block is greater than max_total if it's set.
			error_assert!(
				self.max_block.all_gte(weights.max_total.unwrap_or(Weight::zero())),
				&mut error,
				"[{:?}] {:?} (max block) has to be greater than {:?} (max for class)",
				class,
				self.max_block,
				weights.max_total,
			);
			// Make sure we can fit at least one extrinsic.
			error_assert!(
				self.max_block.all_gt(base_for_class + self.base_block),
				&mut error,
				"[{:?}] {:?} (max block) must fit at least one extrinsic {:?} (base weight)",
				class,
				self.max_block,
				base_for_class + self.base_block,
			);
		}

		if error.has_errors {
			Err(error)
		} else {
			Ok(self)
		}
	}

Encode Weight components as compact

type Weight struct {
	// The weight of computational time used based on some reference hardware.
	RefTime sc.U64 // TODO: codec compact
	// The weight of storage space used by proof of validity.
	ProofSize sc.U64 // TODO: codec compact
}

Failing tests with tinygo 0.28.1

With the newer release of our toolchain, based on tinygo 0.28.1, most of the tests fail. This scale pr resolves some of the issues, but there are tests still failing, depending on the GC used:

conservative GC
Test_ApplyExtrinsic_ExhaustsResourcesError
Test_ValidateTransaction_ExhaustsResourcesError

custom extalloc GC
Test_BlockExecution
Test_Metadata_Encoding_Success
Test_ApplyExtrinsic_ExhaustsResourcesError
Test_Balances_Transfer_Invalid_ExistentialDeposit
Test_Balances_SetBalance_BadOrigin
Test_Balances_ForceTransfer_BadOrigin
Test_Balances_ForceFree_BadOrigin

LimeChain/tinygo#14

Switch from the default GC to the extalloc GC

We are currently testing everything with the Tinygo's default GC (conservative_gc), but we need to switch to a GC that uses the host's allocator.

Note: sharing data buffers between the host and the runtime is done by allocating chunks of the linear memory and only passing pointers with size between the host and the runtime

GC that doesn't utilize host's allocator

Is not problematic (there are workarounds) when:

  • Host shares input data to a runtime function.
  • Runtime function returns a result.

Is problematic:

  • Host imported function could be invoked in the middle of the execution of a runtime function. If the host function needs to return a buffer, the result is shared by writing it to a memory location that might be occupied by a valid GC allocation.

As a temporary workaround (until we fix the extalloc gc), we use different heap base offsets for the GC and the allocator (there could be memory collisions).

GC that utilizes host's allocator

There is an implementation of extalloc GC that uses external allocator, but there are bugs:

  • calling an exported runtime function twice, freezes the second time.

Issues

  • in Test_ApplyExtrinsic_ExhaustsResourcesError, Test_ValidateTransaction_ExhaustsResourcesError, we are trying to allocate pointer with size that is bigger than the max possible allocation supported by the host allocator

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.