Moralis nitro is out! ๐Ÿš€

Moralis Nitro is Finally out!

This brings a whole new level of scalability and performance to Moralis.
All new servers from now on are by default Moralis Nitro.
In this post Iโ€™ll explain the different features of the update.

Itโ€™s very important to upgrade to nitro as it will be the supported version moving ahead.

The easiest way to upgrade is to create a new server from scratch and migrate all data and configuration to the new server.

Below we describe how to upgrade an existing server.

How to upgrade?

This is a change that unfortunately requires manual care as there are some breaking changes and therefore in order to upgrade we need to create a group chat with your team and upgrade together. The process shouldnโ€™t take more than 15 minutes.

  1. Go to our Discord - https://moralis.io/mage
  2. Go to #legacy-to-nitro migration
    Screenshot 2022-05-24 at 10.32.22
  3. Say that you want to upgrade and tag CryptoKid
  4. CryptoKid will setup a group and we will migrate you :raised_hands:

Update: You can also find the steps required to upgrade in documentation:
https://docs.moralis.io/moralis-dapp/getting-started/create-a-moralis-dapp#migrate-dapp-to-nitro-version

Core Services

Moralis Nitro introduces the Core Services plugin that is automatically installed on each server.

This special plugin does all of the heavy-lifting when it comes to syncing historical and real-time blockchain data into your database.

This has many advantages:

  1. Blockchain data sync doesnโ€™t consume server resources which ensures that servers are capable of handling more users, more cloud code, more requests at a cheaper price.
  2. By having an external system for data sync we can make the sync non-blocking and have many independent worker processes handle the data sync. More on that below.

Fast and non-blocking event and transaction sync

In previous versions of the server all address synchronisation was performed on the same server.

When many users sign up at once they had to compete for resources during sync. With nitro we offload this synchronisation process into worker nodes that can process in parallel.

This allows the server to maintain an operational workload and users will see their transactions regardless of how many users sign up at once.

Core Services - User, Role, Session and Plugin

When you start a fresh server youโ€™ll notice that it has 1 User, 1 Session and 1 Role right after creation.

Screenshot 2022-02-02 at 21.59.43

This is by design.
Youโ€™ll notice that it has username set to coreservices.
You can think of it as a system-level user that syncs all the data into your server.
You shouldnโ€™t remove or change it.

If you accidentally remove the coreservices User, Role or Session the data sync into your database will stop - everything will be restored on the next restart of the server and all missed events will be caught up and inserted into the different tables.

You will also notice that each new server by default has a Plugin called Core Services.
This plugin is placed there by design and is impossible to delete.

Breaking Change - TokenBalance and NFTOwner Tables Removed

We noticed that most developers are using Moralis.Web3API to get token balances and nft owners. Therefore these tables will be removed from the database as itโ€™s a heavy job for the server to track token balances and nft owners. Instead API should be used to fetch this data.

You could for example fetch user nft balances and token balances each time they login or do a Job that does it regularly and puts the data into the User row in the database.

Many dapps donโ€™t even need to keep all tokens and NFTs of the user in sync all the time. This change allows more flexibility and allows the developer to adapt their Moralis instance to their exact use-case better.

Better default settings

Before Moralis Nitro we synced all user transactions into the database when a user signs in.

This created some issues with many new users logged in at the same time and user historic sync was enabled. If 1000 users sign up with 100 historical tx each - server needs to handle 100k transactions all at once. While we always had a setting in the dashboard to turn this off weโ€™ve noticed that some dapps missed to set that setting resulting in downtime when many users signed up all at once and in most cases the developer didnโ€™t even need full user history.

Now with Moralis Nitro only 50 historical user tx for each category (native, token, nft) and chain are synced.

And this can be adjusted in the admin settings for the particular server.

Smart contract event filters

Breaking Change: beforeConsume function is now deprecated and removed.
Instead when you setup a smart contract event sync you can specify logical conditions that will give you only events that comply with the conditions.

For example the filter below will only sync event instances where the variable price is equal to 80000000000000000:

{"eq": ["price", "80000000000000000"]}

Below are some more filter examples. You can set conditions for any variable in the event.

If sender = 0x0 AND receiver = 0x0

{ 
  "and": [
    { "eq": ["sender", "0x0"] },
    { "eq": ["receiver", "0x0"] }
  ] 
}

If sender = 0x0 OR receiver = 0x0

{ 
  "or": [
    { "eq": ["sender", "0x0"] },
    { "eq": ["receiver", "0x0"] }
  ] 
}

If (sender = 0x0 AND amount = 1000 ) OR (receiver = 0x0 AND amount = 100 )

{ 
  "or": [
    { 
      "and": [
       { "eq": ["sender", "0x0"] },
       { "eq": ["amount", "1000"]}
      ]
    },
    {
      "and": [
       { "eq": ["receiver", "0x0"] },
       { "eq": ["amount", "1000"]}
      ]
    }
  ] 
}

If an event has wei denominated values you can use <name>_decimals fields to run comparisons (like gt/lt):

{ 
  "and": [
    { "eq": ["sender", "0x0"] },
    { "gt": ["amount_decimals", "1000"]}
  ]
}

Wei numbers are stored as numbers (not only strings)

When syncing transactions and smart contract events - all onchain numbers are represented as wei 256 numbers which donโ€™t fit in traditional databases which meant that before Moralis Nitro update all such number were stored as strings in Moralis DB. This made it impossible to sort, sum, aggregate or run other queries such as LT or GT.

With Moralis Nitro - all events and transactions have a decimal column for each wei number where the actual decimal number is stored representing the wei value.

So for example if 10 ETH was transfered in a transaction Moralis would previously only show the wei value as a string. While now we also include โ€œ10โ€ as a sortable and queryable/sortable/comparable number.

Note: the decimal value can only hold 128 bits - meaning that everything above 34 characters long will lose precision. For exact 256 bit precision - use the string values.

For example:
256 original wei string: โ€œ12345678901234567890123456789012334567890โ€
128 decimal number: 12345678901234567890123456789000000000000

As you can see the decimal value will lose precision - but for most use-cases that include sorting/aggregation/LT and GT queries still would do the job


Summary of breaking changes:

  1. Token and NFT Balance tables removed
  2. beforeConsume removed
5 Likes

Great changes. Especially the event filters rock :+1:

1 Like

Losing the owner table is annoying. I was relying on this. It was useful to get all NFTs owned by a wallet (regardless of the contract). I am not sure I understand. What is the alternative?

Hey @jerome, so sorry for your inconvenience.

We remove it since it was rarely used by other developers and taking too much resources :raised_hands: Also this has been notified throughout multiple channels for quite a while of this breaking change

As an alternative, you can use the Web3 API https://docs.moralis.io/moralis-server/web3-sdk/token#getnftowners, which are widely used by other developers instead of the NFTOwners class.

Cheers~

Thanks. I guess I was focused on building and I missed these.

So this API will give ownership for only one smartContract, correct? How do you recommend building a databases with all NFT smart contracts used/registered by users of a DAPP?

Check this section to get all info about the user

https://docs.moralis.io/moralis-server/web3-sdk/account

You could put all this info in user row as a column each time they login

Or have some other strategy when you want to fetch this data for different users

It depends if the use case you have

The best strategy is to fetch only when you need this data for a particular user (instead of constantly updating all users)

Ok. Will look into that getNFTs function more

After testings, getNFTs seems to achieve my needs for now.

2 Likes