【软件工程与实践】(7)EventAccount事件账户的底层实现以及职能

目录

一、接口

1.EventAccount、EventGroup、EventInfo

我们先来看EventAccount这个接口实现了什么,我们可以看到,它继承了EventGrounpEventAccountInfo,这个接口的只要目的是为了获取区块的id字段。

public interface EventAccount extends EventGroup, EventAccountInfo {

	BlockchainIdentity getID();

}

我们顺着这个接口到EventGounp里面看看这个接口的具体作用是什么,我们会发现这个接口是一个事件组,里面存着用于处理不同时间的方法

这个是用于获取事件序列的方法;
eventName 事件名;
fromSequence 开始序号;
maxCount 最大数量;

Event[] getEvents(String eventName, long fromSequence, int maxCount);

这个方法用于查询所有事件

String[] getEventNames(long fromIndex, int count);

查询事件名称总数

long totalEventNames();

查询事件总数

long totalEvents(String eventName);

获取最近时间

Event getLatest(String eventName);

我们再去看到EventInfo,会发现里面是继承了区块的信息,以便其他方法调用这些信息

public interface EventAccountInfo extends com.jd.blockchain.ledger.BlockchainIdentity, com.jd.blockchain.ledger.AccountSnapshot {
}

2.EventPoerationHandler

注册账户事件

void registerAccount(BlockchainIdentity identity);

发布自定义事件

void publish(Bytes address, EventPublishOperation.EventEntry[] events);

发布系统事件

long publish(String eventName, BytesValue content, long latestSequence);

3. LedgerEventSet

这个实际上就是EventAcount在账本中的接口,在账本中用户获取EventAccount的事件组以及事件设置。

public interface LedgerEventSet {

	EventGroup getSystemEventGroup();

	EventAccountSet getEventAccountSet();

}

1.EventAccountSetEditor

它调用可事件账户设置的接口以及事务性的接口

public class EventAccountSetEditor implements EventAccountSet, Transactional 

这个方法适用于设置事件账户的:
CryptoSetting 二进制设置;
prefix 前缀;
ExPolicyKVStorage 储存方式;
VersioningKVStorage 最新事件储存方式;
AccountAccessPolicy 访问账户策略。

public EventAccountSetEditor(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage,
                           VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) {
        accountSet = new MerkleAccountSetEditor(cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage, accessPolicy);
    }

这个用于设置:
dataRootHash 根哈希值;
cryptoSetting 二进制;
prefix 前缀;
ExPolicyKVStorage 储存方式;
VersioningKVStorage 最新事件储存方式;
readonly 只读文件;
AccountAccessPolicy 访问账户策略。

 public EventAccountSetEditor(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix,
                           ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly,
                           AccountAccessPolicy accessPolicy) {
        accountSet = new MerkleAccountSetEditor(dataRootHash, cryptoSetting, Bytes.fromString(prefix), exStorage, verStorage,
                readonly, accessPolicy);
    }

这两个方法是主要方法,其他的方法基本是基于这两个方法来获取事件总数,事件最新版本等信息,方法和之前几篇类似,这里不多做赘述。

LedgerEventSetEditor

这个用于设置数据事件账户:
MerkleEventGroupPublisher 默克尔树事件账户的发布者;
EventAccountSetEditor 事件账户的设置;
readonly 只读文件。

public LedgerEventSetEditor(MerkleEventGroupPublisher systemEventSet, EventAccountSetEditor userEventSet, boolean readonly) {
		this.systemEventPublisher = systemEventSet;
		this.userEventSet = userEventSet;
		this.readonly = readonly;
	}

获取事件组

public MerkleEventGroupPublisher getSystemEventGroup() {
		return systemEventPublisher;
	}

查看事件是否为最新版本

public boolean isUpdated() {
		return systemEventPublisher.isUpdated() || userEventSet.isUpdated();
	}

这个是用来判断只读文件并扔出提示信息的方法,以及判断事物是否是最新版本的方法

public void commit() {
		if (readonly) {
			throw new IllegalStateException("Readonly ledger system event set which cann't been committed!");
		}
		if (!isUpdated()) {
			return;
		}

		systemEventPublisher.commit();
		userEventSet.commit();

	}

第一个方法可以删除事件,第二个可以的设置文件的只读模式。

public void cancel() {
		systemEventPublisher.cancel();
		userEventSet.cancel();
	}

	public boolean isReadonly() {
		return readonly;
	}

EventManager

这个是一个事件管理器,用于处理事件账户注册,用户事件发布,系统事件发布,事件监听

代码可以注册一个事件账户,你输入一个id它会自动生成相关信息,为你注册一个账户。

public void registerAccount(BlockchainIdentity identity) {
        txCtx.getEventSet().getEventAccountSet().register(identity.getAddress(), identity.getPubKey(), null);
    }

这个方法用于发布事件,输入地址,事件,它会先获取地址,然后用for循环把事件罗列出来。

public void publish(Bytes address, EventPublishOperation.EventEntry[] events) {
        EventPublishingAccount account = txCtx.getEventSet().getEventAccountSet().getAccount(address);
        for (EventPublishOperation.EventEntry event : events) {
            long v = account.publish(new EventInfo(address, event.getName(), event.getSequence()+1, event.getContent(), request.getTransactionHash(), txCtx.getBlockHeight()));
            if (v < 0) {
                throw new DataVersionConflictException();
            }
        }
    }

这一个方法和上一个方法本质上是一样的,但是执行的过程不一样。

public long publish(String eventName, BytesValue content, long latestSequence) {
        long v = txCtx.getEventSet().getSystemEventGroup().publish(new EventInfo(eventName, latestSequence+1, content, request.getTransactionHash(), txCtx.getBlockHeight()));
        if (v < 0) {
            throw new DataVersionConflictException();
        }

        return v;
    }
上一篇:readonly禁止用户输入 ,disabled禁用按钮,input:hidden的作用


下一篇:JS和Jquery操作label标签