git.delta.rocks / unique-network / refs/commits / 683924f8b65f

difftreelog

feat log recording

Yaroslav Bolyukin2021-04-30parent: #ab6ae76.patch.diff
in: master

2 files changed

modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -43,7 +43,7 @@
 };
 use sp_runtime::traits::StaticLookup;
 use pallet_contracts::chain_extension::UncheckedFrom;
-use pallet_evm::AddressMapping;
+use pallet_ethereum::EthereumTransactionSender;
 use pallet_transaction_payment::OnChargeTransaction;
 
 #[cfg(test)]
@@ -185,7 +185,24 @@
 pub struct CollectionHandle<T: Config> {
     pub id: CollectionId,
     collection: Collection<T>,
+    logs: eth::log::LogRecorder,
 }
+impl<T: Config> CollectionHandle<T> {
+	pub fn get(id: CollectionId) -> Option<Self> {
+		<CollectionById<T>>::get(id)
+			.map(|collection| Self {
+				id,
+				collection,
+                logs: eth::log::LogRecorder::default(),
+			})
+	}
+    pub fn log(&self, topics: Vec<H256>, data: eth::abi::AbiWriter) {
+        self.logs.log(topics, data)
+    }
+    pub fn into_inner(self) -> Collection<T> {
+        self.collection.clone()
+    }
+}
 
 impl<T: Config> Deref for CollectionHandle<T> {
     type Target = Collection<T>;
@@ -471,6 +488,9 @@
     type Currency: Currency<Self::AccountId>;
     type CollectionCreationPrice: Get<<<Self as Config>::Currency as Currency<Self::AccountId>>::Balance>;
     type TreasuryAccountId: Get<Self::AccountId>;
+
+    type EthereumChainId: Get<u64>;
+    type EthereumTransactionSender: pallet_ethereum::EthereumTransactionSender;
 }
 
 #[cfg(feature = "runtime-benchmarks")]
@@ -1125,6 +1145,7 @@
             Self::validate_create_item_args(&target_collection, &data)?;
             Self::create_item_no_validation(&target_collection, owner, data)?;
 
+            Self::submit_logs(target_collection)?;
             Ok(())
         }
 
@@ -1158,6 +1179,7 @@
 
             Self::create_multiple_items_internal(sender, &collection, owner, items_data)?;
 
+            Self::submit_logs(collection)?;
             Ok(())
         }
 
@@ -1183,6 +1205,7 @@
 
             Self::burn_item_internal(&sender, &target_collection, item_id, value)?;
 
+            Self::submit_logs(target_collection)?;
             Ok(())
         }
 
@@ -1217,6 +1240,7 @@
 
             Self::transfer_internal(sender, recipient, &collection, item_id, value)?;
 
+            Self::submit_logs(collection)?;
             Ok(())
         }
 
@@ -1244,6 +1268,7 @@
 
             Self::approve_internal(sender, spender, &collection, item_id, amount)?;
 
+            Self::submit_logs(collection)?;
             Ok(())
         }
         
@@ -1275,6 +1300,7 @@
 
             Self::transfer_from_internal(sender, from, recipient, &collection, item_id, value)?;
 
+            Self::submit_logs(collection)?;
             Ok(())
         }
 
@@ -1736,7 +1762,30 @@
 		}
 		<Allowances<T>>::insert(collection.id, (item_id, sender.as_sub(), spender.as_sub()), allowance);
 
+		if matches!(collection.mode, CollectionMode::NFT) {
+			// TODO: NFT: only one owner may exist for token in ERC721
+			collection.log(
+				Vec::from([
+					eth::APPROVAL_NFT_TOPIC,
+					eth::address_to_topic(sender.as_eth()),
+					eth::address_to_topic(spender.as_eth()),
+				]),
+				abi_encode!(uint256(item_id.into())),
+			);
+		}
 
+		if matches!(collection.mode, CollectionMode::Fungible(_)) {
+			// TODO: NFT: only one owner may exist for token in ERC20
+			collection.log(
+				Vec::from([
+					eth::APPROVAL_FUNGIBLE_TOPIC,
+					eth::address_to_topic(sender.as_eth()),
+					eth::address_to_topic(spender.as_eth()),
+				]),
+				abi_encode!(uint256(allowance.into())),
+			);
+		}
+
 		Self::deposit_event(RawEvent::Approved(collection.id, item_id, sender, spender, allowance));
 		Ok(())
 	}
@@ -1791,6 +1840,17 @@
 			_ => ()
 		};
 
+		if matches!(collection.mode, CollectionMode::Fungible(_)) {
+			collection.log(
+				Vec::from([
+					eth::APPROVAL_FUNGIBLE_TOPIC,
+					eth::address_to_topic(from.as_eth()),
+					eth::address_to_topic(sender.as_eth()),
+				]),
+				abi_encode!(uint256(allowance.into())),
+			);
+		}
+
 		Ok(())
 	}
 
@@ -2017,6 +2077,14 @@
             .ok_or(Error::<T>::NumOverflow)?;
         <Balance<T>>::insert(collection_id, item_owner.as_sub(), new_balance);
 
+        collection.log(
+            Vec::from([
+                eth::TRANSFER_NFT_TOPIC,
+                eth::address_to_topic(&H160::default()),
+                eth::address_to_topic(item_owner.as_eth()),
+            ]),
+            abi_encode!(uint256(current_index.into())),
+        );
         Self::deposit_event(RawEvent::ItemCreated(collection_id, current_index, item_owner));
         Ok(())
     }
@@ -2103,22 +2171,32 @@
             <FungibleItemList<T>>::remove(collection_id, owner.as_sub());
         }
 
+        collection.log(
+            Vec::from([
+                eth::TRANSFER_FUNGIBLE_TOPIC,
+                eth::address_to_topic(owner.as_eth()),
+                eth::address_to_topic(&H160::default()),
+            ]),
+            abi_encode!(uint256(value.into())),
+        );
         Ok(())
     }
 
     pub fn get_collection(collection_id: CollectionId) -> Result<CollectionHandle<T>, sp_runtime::DispatchError> {
-        Ok(<CollectionById<T>>::get(collection_id)
-            .map(|collection| CollectionHandle {
-                id: collection_id,
-                collection
-            })
+        Ok(<CollectionHandle<T>>::get(collection_id)
             .ok_or(Error::<T>::CollectionNotFound)?)
     }
 
     fn save_collection(collection: CollectionHandle<T>) {
-        <CollectionById<T>>::insert(collection.id, collection.collection);
+        <CollectionById<T>>::insert(collection.id, collection.into_inner());
     }
 
+    fn submit_logs(collection: CollectionHandle<T>) -> DispatchResult {
+        T::EthereumTransactionSender::submit_logs_transaction(
+            eth::generate_transaction(collection.id, T::EthereumChainId::get()),
+            collection.logs.retrieve_logs_for_contract(eth::collection_id_to_address(collection.id)),
+        )
+    }
 
     fn check_owner_permissions(target_collection: &CollectionHandle<T>, subject: &T::CrossAccountId) -> DispatchResult {
         ensure!(
@@ -2224,6 +2302,14 @@
             <FungibleItemList<T>>::insert(collection_id, owner.as_sub(), balance);
         }
 
+        collection.log(
+            Vec::from([
+                eth::TRANSFER_FUNGIBLE_TOPIC,
+                eth::address_to_topic(owner.as_eth()),
+                eth::address_to_topic(recipient.as_eth()),
+            ]),
+            abi_encode!(uint256(value.into())),
+        );
         Self::deposit_event(RawEvent::Transfer(collection.id, 1, owner.clone(), recipient.clone(), value));
 
         Ok(())
@@ -2348,6 +2434,14 @@
         // update index collection
         Self::move_token_index(collection_id, item_id, &old_owner, &new_owner)?;
 
+        collection.log(
+            Vec::from([
+                eth::TRANSFER_NFT_TOPIC,
+                eth::address_to_topic(sender.as_eth()),
+                eth::address_to_topic(new_owner.as_eth()),
+            ]),
+            abi_encode!(uint256(item_id.into())),
+        );
         Self::deposit_event(RawEvent::Transfer(collection.id, item_id, sender, new_owner, 1));
 
         Ok(())
modifiedruntime/src/lib.rsdiffbeforeafterboth
381 type Event = Event;381 type Event = Event;
382 type FindAuthor = EthereumFindAuthor<Aura>;382 type FindAuthor = EthereumFindAuthor<Aura>;
383 type StateRoot = pallet_ethereum::IntermediateStateRoot;383 type StateRoot = pallet_ethereum::IntermediateStateRoot;
384 type EvmSubmitLog = pallet_evm::Module<Runtime>;
384}385}
385386
386impl pallet_grandpa::Config for Runtime {387impl pallet_grandpa::Config for Runtime {
589 type CollectionCreationPrice = CollectionCreationPrice;590 type CollectionCreationPrice = CollectionCreationPrice;
590 type TreasuryAccountId = TreasuryAccountId;591 type TreasuryAccountId = TreasuryAccountId;
592
593 type EthereumChainId = ChainId;
594 type EthereumTransactionSender = pallet_ethereum::Module<Runtime>;
591}595}
592596
593construct_runtime!(597construct_runtime!(