public void UploadFile(Address from, string name, BigInteger contentSize, byte[] contentMerkle, ArchiveFlags flags, byte[] key) { Runtime.Expect(Runtime.IsWitness(from), "invalid witness"); Runtime.Expect(from.IsUser, "address must be user address"); Runtime.Expect(contentSize >= DomainSettings.ArchiveMinSize, "file too small"); Runtime.Expect(contentSize <= DomainSettings.ArchiveMaxSize, "file too big"); BigInteger requiredSize = CalculateRequiredSize(name, contentSize); var usedSize = GetUsedSpace(from); var stakedAmount = Runtime.GetStake(from); var availableSize = CalculateStorageSizeForStake(stakedAmount); availableSize -= usedSize; Runtime.Expect(availableSize >= requiredSize, "account does not have available space"); var hashes = MerkleTree.FromBytes(contentMerkle); Runtime.CreateArchive(from, hashes, contentSize, flags, key); var newEntry = new StorageEntry() { Name = name, hash = hashes.Root, }; var list = _storageMap.Get <Address, StorageList>(from); list.Add <StorageEntry>(newEntry); Runtime.Notify(EventKind.FileCreate, from, name); }
public void UploadFile(Address sender, Address target, string fileName, BigInteger fileSize, byte[] contentMerkle, ArchiveFlags flags, byte[] key) { Runtime.Expect(Runtime.IsWitness(sender), "invalid witness"); Runtime.Expect(target.IsUser, "destination address must be user address"); Runtime.Expect(fileSize >= DomainSettings.ArchiveMinSize, "file too small"); Runtime.Expect(fileSize <= DomainSettings.ArchiveMaxSize, "file too big"); BigInteger requiredSize = CalculateRequiredSize(fileName, fileSize); var targetUsedSize = GetUsedSpace(target); var targetStakedAmount = Runtime.GetStake(target); var targetAvailableSize = CalculateStorageSizeForStake(targetStakedAmount); targetAvailableSize -= targetUsedSize; if (sender == target) { Runtime.Expect(targetAvailableSize >= requiredSize, "target account does not have available space"); } else // otherwise we need to run some extra checks in case the sender is not the target { var foreignSpace = GetForeignSpace(target); if (foreignSpace < targetAvailableSize) { targetAvailableSize = foreignSpace; // limit available space to max allocated space to foreign addresses } Runtime.Expect(targetAvailableSize >= requiredSize, "target account does not have available space"); if (sender.IsUser) { // note that here we require sender to have at least free space equal to msg size, mostly a protection against spam var senderUsedSize = GetUsedSpace(sender); var senderStakedAmount = Runtime.GetStake(sender); var senderAvailableSize = CalculateStorageSizeForStake(senderStakedAmount); senderAvailableSize -= senderUsedSize; Runtime.Expect(senderAvailableSize >= requiredSize, "sender account does not have available space"); } else { Runtime.Expect(sender.IsSystem, "invalid address type for sender"); } } var hashes = MerkleTree.FromBytes(contentMerkle); Runtime.CreateArchive(sender, target, hashes, fileSize, flags, key); var newEntry = new StorageEntry() { Name = fileName, Hash = hashes.Root, Creator = sender, }; var list = _storageMap.Get <Address, StorageList>(target); list.Add <StorageEntry>(newEntry); Runtime.Notify(EventKind.FileCreate, target, newEntry); }